Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf7b871c56 | ||
|
|
054e9f4bf9 | ||
|
|
a3b99638af | ||
|
|
6cf7267078 | ||
|
|
e6a219c8cc | ||
|
|
9ccf971e58 | ||
|
|
2fcc73e387 | ||
|
|
589db1f26b | ||
|
|
f3f91a1d8e | ||
|
|
d93ed6c7db | ||
|
|
65de93f679 | ||
|
|
b8701fa703 | ||
|
|
62a59a74d7 | ||
|
|
92157c03e9 | ||
|
|
7fefeb61e7 | ||
|
|
b425be302a | ||
|
|
f30f6e646c | ||
|
|
0af3ab700d | ||
|
|
8248843722 | ||
|
|
5fa4bc458e | ||
|
|
40cce24b78 | ||
|
|
968a001a36 | ||
|
|
180f6b2cfa | ||
|
|
46fe5a5645 | ||
|
|
ad51619b4d | ||
|
|
90270b4a3d | ||
|
|
e98212b1cd | ||
|
|
bf78c62384 | ||
|
|
ddd42ca004 |
@@ -1,13 +1,29 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes will be documented in this file.
|
All notable changes will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.2.1] - 2020-11-06
|
||||||
### Added
|
### Added
|
||||||
- 32bit support
|
- Scores to the freeplay menu
|
||||||
- Controller (dancepads) support
|
- A few new intro boot messages.
|
||||||
- Pause screen
|
- Lightning effect in Spooky stages
|
||||||
- Main Menu overhaul
|
- Campaign scores, can now compete on scoreboards for campaign!
|
||||||
- Cool intro screen thing
|
- Can now change difficulties in Freeplay mode
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Balanced out Normal mode for the harder songs. Should be much easier all around.
|
||||||
|
- Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- One of the charting bits on South and Spookeez during the intro.
|
||||||
|
|
||||||
|
## [0.2.0] - 2020-11-01
|
||||||
|
### Added
|
||||||
|
- Uhh Newgrounds release lolol I always lose track of shit.
|
||||||
|
|
||||||
## [0.1.0] - 2020-10-05
|
## [0.1.0] - 2020-10-05
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<project>
|
<project>
|
||||||
<!-- _________________________ Application Settings _________________________ -->
|
<!-- _________________________ Application Settings _________________________ -->
|
||||||
|
|
||||||
<app title="Friday Night Funkin" file="Funkin" main="Main" version="0.0.1" company="HaxeFlixel" />
|
<app title="Friday Night Funkin" file="Funkin" packageName="com.ninjamuffin99.funkin" main="Main" version="0.2.1" company="ninjamuffin99" />
|
||||||
|
|
||||||
<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
|
<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
|
||||||
or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"-->
|
or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"-->
|
||||||
@@ -25,6 +25,9 @@
|
|||||||
<!--Mobile-specific-->
|
<!--Mobile-specific-->
|
||||||
<window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />
|
<window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />
|
||||||
|
|
||||||
|
<!--Switch-specific-->
|
||||||
|
<window if="switch" orientation="landscape" fullscreen="true" width="0" height="0" resizable="true" />
|
||||||
|
|
||||||
<!-- _____________________________ Path Settings ____________________________ -->
|
<!-- _____________________________ Path Settings ____________________________ -->
|
||||||
|
|
||||||
<set name="BUILD_DIR" value="export/debug" if="debug" />
|
<set name="BUILD_DIR" value="export/debug" if="debug" />
|
||||||
@@ -41,6 +44,8 @@
|
|||||||
<assets path="assets/sounds" include="*.mp3" if="web" />
|
<assets path="assets/sounds" include="*.mp3" if="web" />
|
||||||
<assets path="assets/sounds" include="*.ogg" unless="web" />
|
<assets path="assets/sounds" include="*.ogg" unless="web" />
|
||||||
|
|
||||||
|
<assets path="CHANGELOG.md"/>
|
||||||
|
|
||||||
<assets path="assets/fonts/vcr.ttf" embed="true" />
|
<assets path="assets/fonts/vcr.ttf" embed="true" />
|
||||||
|
|
||||||
|
|
||||||
@@ -54,6 +59,9 @@
|
|||||||
|
|
||||||
<!--In case you want to use the ui package-->
|
<!--In case you want to use the ui package-->
|
||||||
<haxelib name="flixel-ui" />
|
<haxelib name="flixel-ui" />
|
||||||
|
<haxelib name="newgrounds" />
|
||||||
|
<haxelib name="markdown" />
|
||||||
|
<haxelib name="HtmlParser" />
|
||||||
|
|
||||||
<!--In case you want to use nape with flixel-->
|
<!--In case you want to use nape with flixel-->
|
||||||
<!--<haxelib name="nape-haxe4" />-->
|
<!--<haxelib name="nape-haxe4" />-->
|
||||||
@@ -93,7 +101,10 @@
|
|||||||
<!-- _________________________________ Custom _______________________________ -->
|
<!-- _________________________________ Custom _______________________________ -->
|
||||||
|
|
||||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||||
<icon path="art/icon.png"/>
|
|
||||||
<!-- <haxedef name="SKIP_TO_PLAYSTATE" if="debug" /> -->
|
<icon path="art/icon.png" />
|
||||||
|
<haxedef name="SKIP_TO_PLAYSTATE" if="debug" />
|
||||||
<!-- <haxedef name="NG_LOGIN" /> -->
|
<!-- <haxedef name="NG_LOGIN" /> -->
|
||||||
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -3,3 +3,4 @@
|
|||||||
This is the repository for Friday Night Funkin, a game originally made for Ludum Dare 47 "Stuck In a Loop".
|
This is the repository for Friday Night Funkin, a game originally made for Ludum Dare 47 "Stuck In a Loop".
|
||||||
|
|
||||||
Play the Ludum Dare prototype here: https://ninja-muffin24.itch.io/friday-night-funkin
|
Play the Ludum Dare prototype here: https://ninja-muffin24.itch.io/friday-night-funkin
|
||||||
|
Play the Newgrounds one here: https://www.newgrounds.com/portal/view/770371
|
||||||
|
|||||||
|
After Width: | Height: | Size: 3.0 MiB |
@@ -0,0 +1,27 @@
|
|||||||
|
@echo off
|
||||||
|
cd ..
|
||||||
|
@echo on
|
||||||
|
echo REBUILDING LIME FOR EXPORT (VERBOSE)
|
||||||
|
@echo off
|
||||||
|
color 0b
|
||||||
|
@echo on
|
||||||
|
lime rebuild windows -clean -v
|
||||||
|
@echo off
|
||||||
|
color 0a
|
||||||
|
@echo on
|
||||||
|
lime rebuild switch -clean -v
|
||||||
|
@echo off
|
||||||
|
color 0e
|
||||||
|
@echo on
|
||||||
|
lime rebuild tools -clean -v
|
||||||
|
echo HOPE AND PRAY...
|
||||||
|
@echo off
|
||||||
|
color 0a
|
||||||
|
@echo on
|
||||||
|
echo BUILDING GAME
|
||||||
|
lime build switch -final -v
|
||||||
|
@echo off
|
||||||
|
color 0b
|
||||||
|
@echo on
|
||||||
|
echo NSP FILE CREATED
|
||||||
|
pause
|
||||||
|
After Width: | Height: | Size: 582 KiB |
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 4.8 MiB |
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TextureAtlas imagePath="BoyFriend_Assets.png">
|
<TextureAtlas imagePath="BOYFRIEND.png">
|
||||||
<!-- Created with Adobe Animate version 20.0.0.17400 -->
|
<!-- Created with Adobe Animate version 20.0.0.17400 -->
|
||||||
<!-- http://www.adobe.com/products/animate.html -->
|
<!-- http://www.adobe.com/products/animate.html -->
|
||||||
<SubTexture name="BF Dead Loop0000" x="0" y="0" width="439" height="435"/>
|
<SubTexture name="BF Dead Loop0000" x="0" y="0" width="439" height="435"/>
|
||||||
@@ -442,26 +442,60 @@
|
|||||||
<SubTexture name="BF idle dance0011" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
<SubTexture name="BF idle dance0011" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
||||||
<SubTexture name="BF idle dance0012" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
<SubTexture name="BF idle dance0012" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
||||||
<SubTexture name="BF idle dance0013" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
<SubTexture name="BF idle dance0013" x="1669" y="2344" width="408" height="412" frameX="-2" frameY="0" frameWidth="411" frameHeight="412"/>
|
||||||
<SubTexture name="boyfriend attack0000" x="2087" y="2344" width="697" height="597" frameX="0" frameY="-87" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="BF idle shaking0000" x="2087" y="2344" width="408" height="412" frameX="-1" frameY="-1" frameWidth="410" frameHeight="413"/>
|
||||||
<SubTexture name="boyfriend attack0001" x="2087" y="2344" width="697" height="597" frameX="0" frameY="-87" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="BF idle shaking0001" x="2505" y="2344" width="408" height="412" frameX="-2" frameY="-1" frameWidth="410" frameHeight="413"/>
|
||||||
<SubTexture name="boyfriend attack0002" x="2794" y="2344" width="603" height="660" frameX="-102" frameY="-24" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="BF idle shaking0002" x="2923" y="2344" width="408" height="413" frameX="-1" frameY="0" frameWidth="410" frameHeight="413"/>
|
||||||
<SubTexture name="boyfriend attack0003" x="2794" y="2344" width="603" height="660" frameX="-102" frameY="-24" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="BF idle shaking0003" x="3341" y="2344" width="410" height="413"/>
|
||||||
<SubTexture name="boyfriend attack0004" x="3407" y="2344" width="444" height="684" frameX="-263" frameY="0" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="bf pre attack0000" x="3761" y="2344" width="386" height="373" frameX="0" frameY="-1" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend attack0005" x="3407" y="2344" width="444" height="684" frameX="-263" frameY="0" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="bf pre attack0001" x="3761" y="2344" width="386" height="373" frameX="0" frameY="-1" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend attack0006" x="3861" y="2344" width="501" height="630" frameX="-207" frameY="-55" frameWidth="708" frameHeight="685"/>
|
<SubTexture name="bf pre attack0002" x="4157" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0000" x="4372" y="2344" width="375" height="404" frameX="-3" frameY="0" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0003" x="4157" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0001" x="4757" y="2344" width="375" height="404" frameX="-3" frameY="0" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0004" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0002" x="5142" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0005" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0003" x="5532" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0006" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0004" x="5922" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0007" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0005" x="5142" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0008" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0006" x="5532" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0009" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0007" x="5922" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0010" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0008" x="5142" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0011" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0009" x="5532" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0012" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0010" x="5922" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0013" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0011" x="5142" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0014" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0012" x="5532" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0015" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0013" x="5922" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0016" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
<SubTexture name="boyfriend dodge0014" x="5142" y="2344" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
<SubTexture name="bf pre attack0017" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0018" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0019" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0020" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0021" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0022" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0023" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0024" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0025" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0026" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0027" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0028" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="bf pre attack0029" x="4549" y="2344" width="382" height="374" frameX="-2" frameY="0" frameWidth="386" frameHeight="374"/>
|
||||||
|
<SubTexture name="boyfriend attack0000" x="4941" y="2344" width="697" height="597" frameX="0" frameY="-87" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0001" x="4941" y="2344" width="697" height="597" frameX="0" frameY="-87" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0002" x="5648" y="2344" width="603" height="660" frameX="-102" frameY="-24" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0003" x="5648" y="2344" width="603" height="660" frameX="-102" frameY="-24" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0004" x="6261" y="2344" width="444" height="684" frameX="-263" frameY="0" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0005" x="6261" y="2344" width="444" height="684" frameX="-263" frameY="0" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend attack0006" x="6715" y="2344" width="501" height="630" frameX="-207" frameY="-55" frameWidth="708" frameHeight="685"/>
|
||||||
|
<SubTexture name="boyfriend dodge0000" x="7226" y="2344" width="375" height="404" frameX="-3" frameY="0" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0001" x="7611" y="2344" width="375" height="404" frameX="-3" frameY="0" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0002" x="0" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0003" x="390" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0004" x="780" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0005" x="0" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0006" x="390" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0007" x="780" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0008" x="0" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0009" x="390" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0010" x="780" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0011" x="0" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0012" x="390" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0013" x="780" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
|
<SubTexture name="boyfriend dodge0014" x="0" y="3038" width="380" height="403" frameX="0" frameY="-1" frameWidth="380" frameHeight="404"/>
|
||||||
</TextureAtlas>
|
</TextureAtlas>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.3 MiB |
@@ -73,121 +73,125 @@
|
|||||||
<SubTexture name="GF Down Note0017" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Down Note0017" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Down Note0018" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Down Note0018" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Down Note0019" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Down Note0019" x="4971" y="1325" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0000" x="5680" y="1325" width="699" height="632" frameX="-2" frameY="-5" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF FEAR 0000" x="5680" y="1325" width="699" height="640"/>
|
||||||
<SubTexture name="GF Right Note0001" x="6389" y="1325" width="703" height="632" frameX="0" frameY="-5" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF FEAR 0001" x="6389" y="1325" width="699" height="640"/>
|
||||||
<SubTexture name="GF Right Note0002" x="7102" y="1325" width="703" height="637"/>
|
<SubTexture name="GF FEAR 0002" x="7098" y="1325" width="699" height="638" frameX="0" frameY="-2" frameWidth="699" frameHeight="640"/>
|
||||||
<SubTexture name="GF Right Note0003" x="0" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF FEAR 0003" x="0" y="1978" width="699" height="640"/>
|
||||||
<SubTexture name="GF Right Note0004" x="709" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0000" x="709" y="1978" width="699" height="632" frameX="-2" frameY="-5" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0005" x="1418" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0001" x="1418" y="1978" width="703" height="632" frameX="0" frameY="-5" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0006" x="2127" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0002" x="2131" y="1978" width="703" height="637"/>
|
||||||
<SubTexture name="GF Right Note0007" x="2127" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0003" x="2844" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0008" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0004" x="3553" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0009" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0005" x="4262" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0010" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0006" x="4971" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0011" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0007" x="4971" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0012" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0008" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0013" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0009" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Right Note0014" x="2836" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
<SubTexture name="GF Right Note0010" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Up Note0000" x="3545" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
<SubTexture name="GF Right Note0011" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Up Note0001" x="4254" y="1978" width="703" height="661"/>
|
<SubTexture name="GF Right Note0012" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Up Note0002" x="4967" y="1978" width="703" height="661"/>
|
<SubTexture name="GF Right Note0013" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Up Note0003" x="5680" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
<SubTexture name="GF Right Note0014" x="5680" y="1978" width="699" height="637" frameX="-2" frameY="0" frameWidth="703" frameHeight="637"/>
|
||||||
<SubTexture name="GF Up Note0004" x="6389" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
<SubTexture name="GF Up Note0000" x="6389" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
||||||
<SubTexture name="GF Up Note0005" x="6389" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
<SubTexture name="GF Up Note0001" x="7098" y="1978" width="703" height="661"/>
|
||||||
<SubTexture name="GF Up Note0006" x="6389" y="1978" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
<SubTexture name="GF Up Note0002" x="0" y="2649" width="703" height="661"/>
|
||||||
<SubTexture name="GF left note0000" x="7098" y="1978" width="699" height="633" frameX="-2" frameY="-5" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF Up Note0003" x="713" y="2649" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
||||||
<SubTexture name="GF left note0001" x="0" y="2649" width="703" height="631" frameX="0" frameY="-7" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF Up Note0004" x="1422" y="2649" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
||||||
<SubTexture name="GF left note0002" x="713" y="2649" width="703" height="638"/>
|
<SubTexture name="GF Up Note0005" x="1422" y="2649" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
||||||
<SubTexture name="GF left note0003" x="1426" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF Up Note0006" x="1422" y="2649" width="699" height="661" frameX="-2" frameY="0" frameWidth="703" frameHeight="661"/>
|
||||||
<SubTexture name="GF left note0004" x="2135" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0000" x="2131" y="2649" width="699" height="633" frameX="-2" frameY="-5" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0005" x="2844" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0001" x="2840" y="2649" width="703" height="631" frameX="0" frameY="-7" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0006" x="3553" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0002" x="3553" y="2649" width="703" height="638"/>
|
||||||
<SubTexture name="GF left note0007" x="3553" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0003" x="4266" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0008" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0004" x="4975" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0009" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0005" x="5684" y="2649" width="699" height="638" frameX="-2" frameY="0" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0010" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0006" x="6393" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0011" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0007" x="6393" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0012" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0008" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0013" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0009" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="GF left note0014" x="4262" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
<SubTexture name="GF left note0010" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="gf sad0000" x="4971" y="2649" width="699" height="633" frameX="0" frameY="-3" frameWidth="699" frameHeight="636"/>
|
<SubTexture name="GF left note0011" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="gf sad0001" x="4971" y="2649" width="699" height="633" frameX="0" frameY="-3" frameWidth="699" frameHeight="636"/>
|
<SubTexture name="GF left note0012" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="gf sad0002" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="GF left note0013" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="gf sad0003" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="GF left note0014" x="7102" y="2649" width="699" height="637" frameX="-2" frameY="-1" frameWidth="703" frameHeight="638"/>
|
||||||
<SubTexture name="gf sad0004" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0000" x="0" y="3320" width="699" height="633" frameX="0" frameY="-3" frameWidth="699" frameHeight="636"/>
|
||||||
<SubTexture name="gf sad0005" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0001" x="0" y="3320" width="699" height="633" frameX="0" frameY="-3" frameWidth="699" frameHeight="636"/>
|
||||||
<SubTexture name="gf sad0006" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0002" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0007" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0003" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0008" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0004" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0009" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0005" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0010" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0006" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0011" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0007" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0012" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0008" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0013" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0009" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0014" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0010" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0015" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0011" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0016" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0012" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0017" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0013" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0018" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0014" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0019" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0015" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0020" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0016" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0021" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0017" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0022" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0018" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0023" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0019" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0024" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0020" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0025" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0021" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0026" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0022" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0027" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0023" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0028" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0024" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0029" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0025" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0030" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0026" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0031" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0027" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0032" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0028" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0033" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0029" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0034" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0030" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0035" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0031" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0036" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0032" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0037" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0033" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0038" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0034" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0039" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0035" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0040" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0036" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0041" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0037" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0042" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0038" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0043" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0039" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0044" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0040" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0045" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0041" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0046" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0042" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0047" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0043" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0048" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0044" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0049" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0045" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0050" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0046" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0051" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0047" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0052" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0048" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0053" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0049" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0054" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0050" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0055" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0051" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0056" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0052" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0057" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0053" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0058" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0054" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0059" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0055" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0060" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0056" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0061" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0057" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0062" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0058" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0063" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0059" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0064" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0060" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0065" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0061" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0066" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0062" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0067" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0063" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0068" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0064" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0069" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0065" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0070" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0066" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0071" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0067" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0072" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0068" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0073" x="0" y="3297" width="699" height="636"/>
|
<SubTexture name="gf sad0069" x="1418" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0074" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0070" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0075" x="5680" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0071" x="2127" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0076" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0072" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0077" x="6389" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0073" x="2836" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0078" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0074" x="709" y="3320" width="699" height="636"/>
|
||||||
<SubTexture name="gf sad0079" x="7098" y="2649" width="699" height="636"/>
|
<SubTexture name="gf sad0075" x="709" y="3320" width="699" height="636"/>
|
||||||
|
<SubTexture name="gf sad0076" x="1418" y="3320" width="699" height="636"/>
|
||||||
|
<SubTexture name="gf sad0077" x="1418" y="3320" width="699" height="636"/>
|
||||||
|
<SubTexture name="gf sad0078" x="2127" y="3320" width="699" height="636"/>
|
||||||
|
<SubTexture name="gf sad0079" x="2127" y="3320" width="699" height="636"/>
|
||||||
</TextureAtlas>
|
</TextureAtlas>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextureAtlas imagePath="backspace.png">
|
||||||
|
<!-- Created with Adobe Animate version 20.0.0.17400 -->
|
||||||
|
<!-- http://www.adobe.com/products/animate.html -->
|
||||||
|
<SubTexture name="backspace PRESSED0000" x="0" y="0" width="288" height="160" frameX="-14" frameY="-6" frameWidth="314" frameHeight="174"/>
|
||||||
|
<SubTexture name="backspace PRESSED0001" x="0" y="0" width="288" height="160" frameX="-14" frameY="-6" frameWidth="314" frameHeight="174"/>
|
||||||
|
<SubTexture name="backspace PRESSED0002" x="298" y="0" width="314" height="174"/>
|
||||||
|
<SubTexture name="backspace to exit0000" x="622" y="0" width="280" height="106"/>
|
||||||
|
<SubTexture name="backspace to exit white0000" x="0" y="184" width="280" height="106"/>
|
||||||
|
</TextureAtlas>
|
||||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -5,19 +5,18 @@
|
|||||||
<SubTexture name="EASY0000" x="0" y="0" width="196" height="65"/>
|
<SubTexture name="EASY0000" x="0" y="0" width="196" height="65"/>
|
||||||
<SubTexture name="HARD0000" x="206" y="0" width="211" height="67"/>
|
<SubTexture name="HARD0000" x="206" y="0" width="211" height="67"/>
|
||||||
<SubTexture name="NORMAL0000" x="427" y="0" width="308" height="67"/>
|
<SubTexture name="NORMAL0000" x="427" y="0" width="308" height="67"/>
|
||||||
|
<SubTexture name="WEEK10000" x="0" y="77" width="360" height="89"/>
|
||||||
<SubTexture name="WEEK1 select0000" x="0" y="77" width="360" height="89"/>
|
<SubTexture name="WEEK1 select0000" x="0" y="77" width="360" height="89"/>
|
||||||
<SubTexture name="WEEK1 select0001" x="370" y="77" width="360" height="89"/>
|
<SubTexture name="WEEK1 select0001" x="370" y="77" width="360" height="89"/>
|
||||||
|
<SubTexture name="WEEK20000" x="0" y="279" width="361" height="87"/>
|
||||||
<SubTexture name="arrow left0000" x="740" y="77" width="48" height="85"/>
|
<SubTexture name="arrow left0000" x="740" y="77" width="48" height="85"/>
|
||||||
<SubTexture name="arrow push left0000" x="798" y="77" width="42" height="75"/>
|
<SubTexture name="arrow push left0000" x="798" y="77" width="42" height="75"/>
|
||||||
<SubTexture name="arrow push right0000" x="850" y="77" width="41" height="74"/>
|
<SubTexture name="arrow push right0000" x="850" y="77" width="41" height="74"/>
|
||||||
<SubTexture name="arrow right0000" x="901" y="77" width="47" height="85"/>
|
<SubTexture name="arrow right0000" x="901" y="77" width="47" height="85"/>
|
||||||
<SubTexture name="lock0000" x="0" y="176" width="67" height="93"/>
|
<SubTexture name="lock0000" x="0" y="176" width="67" height="93"/>
|
||||||
<SubTexture name="week 2 CANNOT select0000" x="77" y="176" width="361" height="87" frameX="-10" frameY="0" frameWidth="383" frameHeight="87"/>
|
<SubTexture name="tutorial0000" x="77" y="176" width="443" height="82"/>
|
||||||
<SubTexture name="week 2 CANNOT select0001" x="448" y="176" width="361" height="87" frameX="0" frameY="0" frameWidth="383" frameHeight="87"/>
|
<SubTexture name="tutorial selected0000" x="77" y="176" width="443" height="82"/>
|
||||||
<SubTexture name="week 2 CANNOT select0002" x="0" y="279" width="362" height="87" frameX="-21" frameY="0" frameWidth="383" frameHeight="87"/>
|
<SubTexture name="tutorial selected0001" x="530" y="176" width="443" height="82"/>
|
||||||
<SubTexture name="week 2 CANNOT select0003" x="448" y="176" width="361" height="87" frameX="-7" frameY="0" frameWidth="383" frameHeight="87"/>
|
<SubTexture name="week2 select0000" x="0" y="279" width="361" height="87"/>
|
||||||
<SubTexture name="week 2 CANNOT select0004" x="77" y="176" width="361" height="87" frameX="-11" frameY="0" frameWidth="383" frameHeight="87"/>
|
<SubTexture name="week2 select0001" x="371" y="279" width="361" height="87"/>
|
||||||
<SubTexture name="week 2 CANNOT select0005" x="77" y="176" width="361" height="87" frameX="-11" frameY="0" frameWidth="383" frameHeight="87"/>
|
|
||||||
<SubTexture name="week2 select0000" x="77" y="176" width="361" height="87" frameX="0" frameY="0" frameWidth="383" frameHeight="87"/>
|
|
||||||
<SubTexture name="week2 select0001" x="372" y="279" width="361" height="87"/>
|
|
||||||
</TextureAtlas>
|
</TextureAtlas>
|
||||||
|
|||||||
|
After Width: | Height: | Size: 606 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 334 KiB |
@@ -48,6 +48,7 @@ class Alphabet extends FlxSpriteGroup
|
|||||||
this.text = text;
|
this.text = text;
|
||||||
isBold = bold;
|
isBold = bold;
|
||||||
|
|
||||||
|
|
||||||
if (text != "")
|
if (text != "")
|
||||||
{
|
{
|
||||||
if (typed)
|
if (typed)
|
||||||
@@ -77,7 +78,8 @@ class Alphabet extends FlxSpriteGroup
|
|||||||
lastWasSpace = true;
|
lastWasSpace = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AlphaCharacter.alphabet.contains(character.toLowerCase()))
|
if (AlphaCharacter.alphabet.indexOf(character.toLowerCase()) != -1)
|
||||||
|
//if (AlphaCharacter.alphabet.contains(character.toLowerCase()))
|
||||||
{
|
{
|
||||||
if (lastSprite != null)
|
if (lastSprite != null)
|
||||||
{
|
{
|
||||||
@@ -121,6 +123,7 @@ class Alphabet extends FlxSpriteGroup
|
|||||||
_finalText = text;
|
_finalText = text;
|
||||||
doSplitWords();
|
doSplitWords();
|
||||||
|
|
||||||
|
|
||||||
// trace(arrayShit);
|
// trace(arrayShit);
|
||||||
|
|
||||||
var loopNum:Int = 0;
|
var loopNum:Int = 0;
|
||||||
@@ -137,6 +140,7 @@ class Alphabet extends FlxSpriteGroup
|
|||||||
xPosResetted = true;
|
xPosResetted = true;
|
||||||
xPos = 0;
|
xPos = 0;
|
||||||
curRow += 1;
|
curRow += 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitWords[loopNum] == " ")
|
if (splitWords[loopNum] == " ")
|
||||||
@@ -144,9 +148,17 @@ class Alphabet extends FlxSpriteGroup
|
|||||||
lastWasSpace = true;
|
lastWasSpace = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
var isNumber:Bool = AlphaCharacter.numbers.contains(splitWords[loopNum]);
|
var isNumber:Bool = AlphaCharacter.numbers.contains(splitWords[loopNum]);
|
||||||
var isSymbol:Bool = AlphaCharacter.symbols.contains(splitWords[loopNum]);
|
var isSymbol:Bool = AlphaCharacter.symbols.contains(splitWords[loopNum]);
|
||||||
if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol)
|
#else
|
||||||
|
var isNumber:Bool = AlphaCharacter.numbers.indexOf(splitWords[loopNum]) != -1;
|
||||||
|
var isSymbol:Bool = AlphaCharacter.symbols.indexOf(splitWords[loopNum]) != -1;
|
||||||
|
#end
|
||||||
|
|
||||||
|
if (AlphaCharacter.alphabet.indexOf(splitWords[loopNum].toLowerCase()) != -1 || isNumber || isSymbol)
|
||||||
|
//if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (lastSprite != null && !xPosResetted)
|
if (lastSprite != null && !xPosResetted)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ class Boyfriend extends Character
|
|||||||
animation.addByPrefix('firstDeath', "BF dies", 24, false);
|
animation.addByPrefix('firstDeath', "BF dies", 24, false);
|
||||||
animation.addByPrefix('deathLoop', "BF Dead Loop", 24, true);
|
animation.addByPrefix('deathLoop', "BF Dead Loop", 24, true);
|
||||||
animation.addByPrefix('deathConfirm', "BF Dead confirm", 24, false);
|
animation.addByPrefix('deathConfirm', "BF Dead confirm", 24, false);
|
||||||
|
|
||||||
|
animation.addByPrefix('scared', 'BF idle shaking', 24);
|
||||||
playAnim('idle');
|
playAnim('idle');
|
||||||
|
|
||||||
antialiasing = true;
|
antialiasing = true;
|
||||||
@@ -47,6 +49,7 @@ class Boyfriend extends Character
|
|||||||
addOffset('firstDeath', 37, 11);
|
addOffset('firstDeath', 37, 11);
|
||||||
addOffset('deathLoop', 37, 5);
|
addOffset('deathLoop', 37, 5);
|
||||||
addOffset('deathConfirm', 37, 69);
|
addOffset('deathConfirm', 37, 69);
|
||||||
|
addOffset('scared', -4);
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ class Character extends FlxSprite
|
|||||||
|
|
||||||
switch (curCharacter)
|
switch (curCharacter)
|
||||||
{
|
{
|
||||||
case 'bf':
|
|
||||||
case 'gf':
|
case 'gf':
|
||||||
// GIRLFRIEND CODE
|
// GIRLFRIEND CODE
|
||||||
tex = FlxAtlasFrames.fromSparrow(AssetPaths.GF_assets__png, AssetPaths.GF_assets__xml);
|
tex = FlxAtlasFrames.fromSparrow(AssetPaths.GF_assets__png, AssetPaths.GF_assets__xml);
|
||||||
@@ -38,6 +37,8 @@ class Character extends FlxSprite
|
|||||||
animation.addByIndices('danceLeft', 'GF Dancing Beat', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
|
animation.addByIndices('danceLeft', 'GF Dancing Beat', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
|
||||||
animation.addByIndices('danceRight', 'GF Dancing Beat', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
|
animation.addByIndices('danceRight', 'GF Dancing Beat', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
|
||||||
|
|
||||||
|
animation.addByPrefix('scared', 'GF FEAR', 24);
|
||||||
|
|
||||||
addOffset('cheer');
|
addOffset('cheer');
|
||||||
addOffset('sad', -2, -2);
|
addOffset('sad', -2, -2);
|
||||||
addOffset('danceLeft', 0, -9);
|
addOffset('danceLeft', 0, -9);
|
||||||
@@ -48,6 +49,8 @@ class Character extends FlxSprite
|
|||||||
addOffset("singLEFT", 0, -19);
|
addOffset("singLEFT", 0, -19);
|
||||||
addOffset("singDOWN", 0, -20);
|
addOffset("singDOWN", 0, -20);
|
||||||
|
|
||||||
|
addOffset('scared');
|
||||||
|
|
||||||
playAnim('danceRight');
|
playAnim('danceRight');
|
||||||
|
|
||||||
case 'dad':
|
case 'dad':
|
||||||
@@ -112,6 +115,8 @@ class Character extends FlxSprite
|
|||||||
{
|
{
|
||||||
switch (curCharacter)
|
switch (curCharacter)
|
||||||
{
|
{
|
||||||
|
case 'bf':
|
||||||
|
|
||||||
case 'gf':
|
case 'gf':
|
||||||
danced = !danced;
|
danced = !danced;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ import openfl.events.Event;
|
|||||||
import openfl.events.IOErrorEvent;
|
import openfl.events.IOErrorEvent;
|
||||||
import openfl.events.IOErrorEvent;
|
import openfl.events.IOErrorEvent;
|
||||||
import openfl.events.IOErrorEvent;
|
import openfl.events.IOErrorEvent;
|
||||||
|
import openfl.media.Sound;
|
||||||
import openfl.net.FileReference;
|
import openfl.net.FileReference;
|
||||||
|
import openfl.utils.ByteArray;
|
||||||
|
|
||||||
using StringTools;
|
using StringTools;
|
||||||
|
|
||||||
@@ -758,10 +760,17 @@ class ChartingState extends MusicBeatState
|
|||||||
|
|
||||||
function loadJson(song:String):Void
|
function loadJson(song:String):Void
|
||||||
{
|
{
|
||||||
PlayState.SONG = Song.loadFromJson(song);
|
PlayState.SONG = Song.loadFromJson(song.toLowerCase(), song.toLowerCase());
|
||||||
FlxG.resetState();
|
FlxG.resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mp3File:Sound;
|
||||||
|
var waveForm:FlxSprite;
|
||||||
|
|
||||||
|
function drawWave():Void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private function saveLevel()
|
private function saveLevel()
|
||||||
{
|
{
|
||||||
var json = {
|
var json = {
|
||||||
|
|||||||
@@ -108,7 +108,11 @@ class Controls extends FlxActionSet
|
|||||||
var _pause = new FlxActionDigital(Action.PAUSE);
|
var _pause = new FlxActionDigital(Action.PAUSE);
|
||||||
var _reset = new FlxActionDigital(Action.RESET);
|
var _reset = new FlxActionDigital(Action.RESET);
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
var byName:Map<String, FlxActionDigital> = [];
|
var byName:Map<String, FlxActionDigital> = [];
|
||||||
|
#else
|
||||||
|
var byName:Map<String, FlxActionDigital> = new Map<String, FlxActionDigital>();
|
||||||
|
#end
|
||||||
|
|
||||||
public var gamepadsAdded:Array<Int> = [];
|
public var gamepadsAdded:Array<Int> = [];
|
||||||
public var keyboardScheme = KeyboardScheme.None;
|
public var keyboardScheme = KeyboardScheme.None;
|
||||||
@@ -193,6 +197,7 @@ class Controls extends FlxActionSet
|
|||||||
inline function get_RESET()
|
inline function get_RESET()
|
||||||
return _reset.check();
|
return _reset.check();
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
public function new(name, scheme = None)
|
public function new(name, scheme = None)
|
||||||
{
|
{
|
||||||
super(name);
|
super(name);
|
||||||
@@ -219,6 +224,36 @@ class Controls extends FlxActionSet
|
|||||||
|
|
||||||
setKeyboardScheme(scheme, false);
|
setKeyboardScheme(scheme, false);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
public function new(name, scheme:KeyboardScheme = null)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
|
||||||
|
add(_up);
|
||||||
|
add(_left);
|
||||||
|
add(_right);
|
||||||
|
add(_down);
|
||||||
|
add(_upP);
|
||||||
|
add(_leftP);
|
||||||
|
add(_rightP);
|
||||||
|
add(_downP);
|
||||||
|
add(_upR);
|
||||||
|
add(_leftR);
|
||||||
|
add(_rightR);
|
||||||
|
add(_downR);
|
||||||
|
add(_accept);
|
||||||
|
add(_back);
|
||||||
|
add(_pause);
|
||||||
|
add(_reset);
|
||||||
|
|
||||||
|
for (action in digitalActions)
|
||||||
|
byName[action.name] = action;
|
||||||
|
|
||||||
|
if (scheme == null)
|
||||||
|
scheme = None;
|
||||||
|
setKeyboardScheme(scheme, false);
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
override function update()
|
override function update()
|
||||||
{
|
{
|
||||||
@@ -278,7 +313,7 @@ class Controls extends FlxActionSet
|
|||||||
* @param func
|
* @param func
|
||||||
* @return ->Void)
|
* @return ->Void)
|
||||||
*/
|
*/
|
||||||
function forEachBound(control:Control, func:(FlxActionDigital, FlxInputState) -> Void)
|
function forEachBound(control:Control, func:FlxActionDigital->FlxInputState->Void)
|
||||||
{
|
{
|
||||||
switch (control)
|
switch (control)
|
||||||
{
|
{
|
||||||
@@ -332,6 +367,7 @@ class Controls extends FlxActionSet
|
|||||||
|
|
||||||
public function copyFrom(controls:Controls, ?device:Device)
|
public function copyFrom(controls:Controls, ?device:Device)
|
||||||
{
|
{
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
for (name => action in controls.byName)
|
for (name => action in controls.byName)
|
||||||
{
|
{
|
||||||
for (input in action.inputs)
|
for (input in action.inputs)
|
||||||
@@ -340,14 +376,31 @@ class Controls extends FlxActionSet
|
|||||||
byName[name].add(cast input);
|
byName[name].add(cast input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
for (name in controls.byName.keys())
|
||||||
|
{
|
||||||
|
var action = controls.byName[name];
|
||||||
|
for (input in action.inputs)
|
||||||
|
{
|
||||||
|
if (device == null || isDevice(input, device))
|
||||||
|
byName[name].add(cast input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
switch (device)
|
switch (device)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
// add all
|
// add all
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
for (gamepad in controls.gamepadsAdded)
|
for (gamepad in controls.gamepadsAdded)
|
||||||
if (!gamepadsAdded.contains(gamepad))
|
if (!gamepadsAdded.contains(gamepad))
|
||||||
gamepadsAdded.push(gamepad);
|
gamepadsAdded.push(gamepad);
|
||||||
|
#else
|
||||||
|
for (gamepad in controls.gamepadsAdded)
|
||||||
|
if (gamepadsAdded.indexOf(gamepad) == -1)
|
||||||
|
gamepadsAdded.push(gamepad);
|
||||||
|
#end
|
||||||
|
|
||||||
mergeKeyboardScheme(controls.keyboardScheme);
|
mergeKeyboardScheme(controls.keyboardScheme);
|
||||||
|
|
||||||
@@ -383,7 +436,11 @@ class Controls extends FlxActionSet
|
|||||||
*/
|
*/
|
||||||
public function bindKeys(control:Control, keys:Array<FlxKey>)
|
public function bindKeys(control:Control, keys:Array<FlxKey>)
|
||||||
{
|
{
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
inline forEachBound(control, (action, state) -> addKeys(action, keys, state));
|
inline forEachBound(control, (action, state) -> addKeys(action, keys, state));
|
||||||
|
#else
|
||||||
|
forEachBound(control, function(action, state) addKeys(action, keys, state));
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -392,7 +449,11 @@ class Controls extends FlxActionSet
|
|||||||
*/
|
*/
|
||||||
public function unbindKeys(control:Control, keys:Array<FlxKey>)
|
public function unbindKeys(control:Control, keys:Array<FlxKey>)
|
||||||
{
|
{
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
inline forEachBound(control, (action, _) -> removeKeys(action, keys));
|
inline forEachBound(control, (action, _) -> removeKeys(action, keys));
|
||||||
|
#else
|
||||||
|
forEachBound(control, function(action, _) removeKeys(action, keys));
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
|
inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
|
||||||
@@ -418,6 +479,8 @@ class Controls extends FlxActionSet
|
|||||||
removeKeyboard();
|
removeKeyboard();
|
||||||
|
|
||||||
keyboardScheme = scheme;
|
keyboardScheme = scheme;
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
switch (scheme)
|
switch (scheme)
|
||||||
{
|
{
|
||||||
case Solo:
|
case Solo:
|
||||||
@@ -450,6 +513,40 @@ class Controls extends FlxActionSet
|
|||||||
case None: // nothing
|
case None: // nothing
|
||||||
case Custom: // nothing
|
case Custom: // nothing
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
switch (scheme)
|
||||||
|
{
|
||||||
|
case Solo:
|
||||||
|
bindKeys(Control.UP, [W, FlxKey.UP]);
|
||||||
|
bindKeys(Control.DOWN, [S, FlxKey.DOWN]);
|
||||||
|
bindKeys(Control.LEFT, [A, FlxKey.LEFT]);
|
||||||
|
bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]);
|
||||||
|
bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]);
|
||||||
|
bindKeys(Control.BACK, [BACKSPACE, ESCAPE]);
|
||||||
|
bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
|
||||||
|
bindKeys(Control.RESET, [R]);
|
||||||
|
case Duo(true):
|
||||||
|
bindKeys(Control.UP, [W]);
|
||||||
|
bindKeys(Control.DOWN, [S]);
|
||||||
|
bindKeys(Control.LEFT, [A]);
|
||||||
|
bindKeys(Control.RIGHT, [D]);
|
||||||
|
bindKeys(Control.ACCEPT, [G, Z]);
|
||||||
|
bindKeys(Control.BACK, [H, X]);
|
||||||
|
bindKeys(Control.PAUSE, [ONE]);
|
||||||
|
bindKeys(Control.RESET, [R]);
|
||||||
|
case Duo(false):
|
||||||
|
bindKeys(Control.UP, [FlxKey.UP]);
|
||||||
|
bindKeys(Control.DOWN, [FlxKey.DOWN]);
|
||||||
|
bindKeys(Control.LEFT, [FlxKey.LEFT]);
|
||||||
|
bindKeys(Control.RIGHT, [FlxKey.RIGHT]);
|
||||||
|
bindKeys(Control.ACCEPT, [O]);
|
||||||
|
bindKeys(Control.BACK, [P]);
|
||||||
|
bindKeys(Control.PAUSE, [ENTER]);
|
||||||
|
bindKeys(Control.RESET, [BACKSPACE]);
|
||||||
|
case None: // nothing
|
||||||
|
case Custom: // nothing
|
||||||
|
}
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeKeyboard()
|
function removeKeyboard()
|
||||||
@@ -469,15 +566,27 @@ class Controls extends FlxActionSet
|
|||||||
public function addGamepad(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
public function addGamepad(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
||||||
{
|
{
|
||||||
gamepadsAdded.push(id);
|
gamepadsAdded.push(id);
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
for (control => buttons in buttonMap)
|
for (control => buttons in buttonMap)
|
||||||
bindButtons(control, id, buttons);
|
inline bindButtons(control, id, buttons);
|
||||||
|
#else
|
||||||
|
for (control in buttonMap.keys())
|
||||||
|
bindButtons(control, id, buttonMap[control]);
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
inline function addGamepadLiteral(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
inline function addGamepadLiteral(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
||||||
{
|
{
|
||||||
gamepadsAdded.push(id);
|
gamepadsAdded.push(id);
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
for (control => buttons in buttonMap)
|
for (control => buttons in buttonMap)
|
||||||
inline bindButtons(control, id, buttons);
|
inline bindButtons(control, id, buttons);
|
||||||
|
#else
|
||||||
|
for (control in buttonMap.keys())
|
||||||
|
bindButtons(control, id, buttonMap[control]);
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void
|
public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void
|
||||||
@@ -498,6 +607,7 @@ class Controls extends FlxActionSet
|
|||||||
|
|
||||||
public function addDefaultGamepad(id):Void
|
public function addDefaultGamepad(id):Void
|
||||||
{
|
{
|
||||||
|
#if !switch
|
||||||
addGamepadLiteral(id, [
|
addGamepadLiteral(id, [
|
||||||
Control.ACCEPT => [A],
|
Control.ACCEPT => [A],
|
||||||
Control.BACK => [B],
|
Control.BACK => [B],
|
||||||
@@ -508,6 +618,19 @@ class Controls extends FlxActionSet
|
|||||||
Control.PAUSE => [START],
|
Control.PAUSE => [START],
|
||||||
Control.RESET => [Y]
|
Control.RESET => [Y]
|
||||||
]);
|
]);
|
||||||
|
#else
|
||||||
|
addGamepadLiteral(id, [
|
||||||
|
//Swap A and B for switch
|
||||||
|
Control.ACCEPT => [B],
|
||||||
|
Control.BACK => [A],
|
||||||
|
Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP],
|
||||||
|
Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN],
|
||||||
|
Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT],
|
||||||
|
Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT],
|
||||||
|
Control.PAUSE => [START],
|
||||||
|
Control.RESET => [Y]
|
||||||
|
]);
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -516,7 +639,11 @@ class Controls extends FlxActionSet
|
|||||||
*/
|
*/
|
||||||
public function bindButtons(control:Control, id, buttons)
|
public function bindButtons(control:Control, id, buttons)
|
||||||
{
|
{
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id));
|
inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id));
|
||||||
|
#else
|
||||||
|
forEachBound(control, function(action, state) addButtons(action, buttons, state, id));
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -525,7 +652,11 @@ class Controls extends FlxActionSet
|
|||||||
*/
|
*/
|
||||||
public function unbindButtons(control:Control, gamepadID:Int, buttons)
|
public function unbindButtons(control:Control, gamepadID:Int, buttons)
|
||||||
{
|
{
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons));
|
inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons));
|
||||||
|
#else
|
||||||
|
forEachBound(control, function(action, _) removeButtons(action, gamepadID, buttons));
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static function addButtons(action:FlxActionDigital, buttons:Array<FlxGamepadInputID>, state, id)
|
inline static function addButtons(action:FlxActionDigital, buttons:Array<FlxGamepadInputID>, state, id)
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
package;
|
package;
|
||||||
|
|
||||||
|
import flash.text.TextField;
|
||||||
import flixel.FlxG;
|
import flixel.FlxG;
|
||||||
import flixel.FlxSprite;
|
import flixel.FlxSprite;
|
||||||
import flixel.addons.display.FlxGridOverlay;
|
import flixel.addons.display.FlxGridOverlay;
|
||||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
import flixel.text.FlxText;
|
import flixel.text.FlxText;
|
||||||
|
import flixel.util.FlxColor;
|
||||||
|
import htmlparser.HtmlDocument;
|
||||||
|
import lime.utils.Assets;
|
||||||
|
|
||||||
class FreeplayState extends MusicBeatState
|
class FreeplayState extends MusicBeatState
|
||||||
{
|
{
|
||||||
@@ -12,15 +17,30 @@ class FreeplayState extends MusicBeatState
|
|||||||
|
|
||||||
var selector:FlxText;
|
var selector:FlxText;
|
||||||
var curSelected:Int = 0;
|
var curSelected:Int = 0;
|
||||||
|
var curDifficulty:Int = 1;
|
||||||
|
|
||||||
|
var scoreText:FlxText;
|
||||||
|
var diffText:FlxText;
|
||||||
|
var lerpScore:Int = 0;
|
||||||
|
var intendedScore:Int = 0;
|
||||||
|
|
||||||
private var grpSongs:FlxTypedGroup<Alphabet>;
|
private var grpSongs:FlxTypedGroup<Alphabet>;
|
||||||
|
|
||||||
override function create()
|
override function create()
|
||||||
{
|
{
|
||||||
if (!FlxG.sound.music.playing)
|
if (FlxG.sound.music != null)
|
||||||
FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
|
{
|
||||||
|
if (!FlxG.sound.music.playing)
|
||||||
|
FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
|
||||||
|
}
|
||||||
|
|
||||||
if (StoryMenuState.weekUnlocked[1])
|
var isDebug:Bool = false;
|
||||||
|
|
||||||
|
#if debug
|
||||||
|
isDebug = true;
|
||||||
|
#end
|
||||||
|
|
||||||
|
if (StoryMenuState.weekUnlocked[1] || isDebug)
|
||||||
{
|
{
|
||||||
songs.push('Spookeez');
|
songs.push('Spookeez');
|
||||||
songs.push('South');
|
songs.push('South');
|
||||||
@@ -47,7 +67,23 @@ class FreeplayState extends MusicBeatState
|
|||||||
// songText.screenCenter(X);
|
// songText.screenCenter(X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoreText = new FlxText(FlxG.width * 0.7, 5, 0, "", 32);
|
||||||
|
// scoreText.autoSize = false;
|
||||||
|
scoreText.setFormat("assets/fonts/vcr.ttf", 32, FlxColor.WHITE, RIGHT);
|
||||||
|
// scoreText.alignment = RIGHT;
|
||||||
|
|
||||||
|
var scoreBG:FlxSprite = new FlxSprite(scoreText.x - 6, 0).makeGraphic(Std.int(FlxG.width * 0.35), 66, 0xFF000000);
|
||||||
|
scoreBG.alpha = 0.6;
|
||||||
|
add(scoreBG);
|
||||||
|
|
||||||
|
diffText = new FlxText(scoreText.x, scoreText.y + 36, 0, "", 24);
|
||||||
|
diffText.font = scoreText.font;
|
||||||
|
add(diffText);
|
||||||
|
|
||||||
|
add(scoreText);
|
||||||
|
|
||||||
changeSelection();
|
changeSelection();
|
||||||
|
changeDiff();
|
||||||
|
|
||||||
// FlxG.sound.playMusic('assets/music/title' + TitleState.soundExt, 0);
|
// FlxG.sound.playMusic('assets/music/title' + TitleState.soundExt, 0);
|
||||||
// FlxG.sound.music.fadeIn(2, 0, 0.8);
|
// FlxG.sound.music.fadeIn(2, 0, 0.8);
|
||||||
@@ -59,12 +95,33 @@ class FreeplayState extends MusicBeatState
|
|||||||
|
|
||||||
var swag:Alphabet = new Alphabet(1, 0, "swag");
|
var swag:Alphabet = new Alphabet(1, 0, "swag");
|
||||||
|
|
||||||
|
// JUST DOIN THIS SHIT FOR TESTING!!!
|
||||||
|
/*
|
||||||
|
var md:String = Markdown.markdownToHtml(Assets.getText('CHANGELOG.md'));
|
||||||
|
|
||||||
|
var texFel:TextField = new TextField();
|
||||||
|
texFel.width = FlxG.width;
|
||||||
|
texFel.height = FlxG.height;
|
||||||
|
// texFel.
|
||||||
|
texFel.htmlText = md;
|
||||||
|
|
||||||
|
FlxG.stage.addChild(texFel);
|
||||||
|
|
||||||
|
// scoreText.textField.htmlText = md;
|
||||||
|
|
||||||
|
trace(md);
|
||||||
|
*/
|
||||||
|
|
||||||
super.create();
|
super.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
|
lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4));
|
||||||
|
scoreText.text = "PERSONAL BEST:" + lerpScore;
|
||||||
|
|
||||||
var upP = controls.UP_P;
|
var upP = controls.UP_P;
|
||||||
var downP = controls.DOWN_P;
|
var downP = controls.DOWN_P;
|
||||||
var accepted = controls.ACCEPT;
|
var accepted = controls.ACCEPT;
|
||||||
@@ -78,6 +135,11 @@ class FreeplayState extends MusicBeatState
|
|||||||
changeSelection(1);
|
changeSelection(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controls.LEFT_P)
|
||||||
|
changeDiff(-1);
|
||||||
|
if (controls.RIGHT_P)
|
||||||
|
changeDiff(1);
|
||||||
|
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
{
|
{
|
||||||
FlxG.switchState(new MainMenuState());
|
FlxG.switchState(new MainMenuState());
|
||||||
@@ -85,15 +147,42 @@ class FreeplayState extends MusicBeatState
|
|||||||
|
|
||||||
if (accepted)
|
if (accepted)
|
||||||
{
|
{
|
||||||
PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase(), songs[curSelected].toLowerCase());
|
var poop:String = Highscore.formatSong(songs[curSelected].toLowerCase(), curDifficulty);
|
||||||
|
|
||||||
|
PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].toLowerCase());
|
||||||
PlayState.isStoryMode = false;
|
PlayState.isStoryMode = false;
|
||||||
FlxG.switchState(new PlayState());
|
FlxG.switchState(new PlayState());
|
||||||
FlxG.sound.music.stop();
|
if (FlxG.sound.music != null)
|
||||||
|
FlxG.sound.music.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeDiff(change:Int = 0)
|
||||||
|
{
|
||||||
|
curDifficulty += change;
|
||||||
|
|
||||||
|
if (curDifficulty < 0)
|
||||||
|
curDifficulty = 2;
|
||||||
|
if (curDifficulty > 2)
|
||||||
|
curDifficulty = 0;
|
||||||
|
|
||||||
|
intendedScore = Highscore.getScore(songs[curSelected], curDifficulty);
|
||||||
|
|
||||||
|
switch (curDifficulty)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
diffText.text = "EASY";
|
||||||
|
case 1:
|
||||||
|
diffText.text = 'NORMAL';
|
||||||
|
case 2:
|
||||||
|
diffText.text = "HARD";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSelection(change:Int = 0)
|
function changeSelection(change:Int = 0)
|
||||||
{
|
{
|
||||||
|
NGio.logEvent('Fresh');
|
||||||
|
|
||||||
curSelected += change;
|
curSelected += change;
|
||||||
|
|
||||||
if (curSelected < 0)
|
if (curSelected < 0)
|
||||||
@@ -103,6 +192,9 @@ class FreeplayState extends MusicBeatState
|
|||||||
|
|
||||||
// selector.y = (70 * curSelected) + 30;
|
// selector.y = (70 * curSelected) + 30;
|
||||||
|
|
||||||
|
intendedScore = Highscore.getScore(songs[curSelected], curDifficulty);
|
||||||
|
// lerpScore = 0;
|
||||||
|
|
||||||
var bullShit:Int = 0;
|
var bullShit:Int = 0;
|
||||||
|
|
||||||
for (item in grpSongs.members)
|
for (item in grpSongs.members)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ class GameOverSubstate extends MusicBeatSubstate
|
|||||||
var bf:Boyfriend;
|
var bf:Boyfriend;
|
||||||
var camFollow:FlxObject;
|
var camFollow:FlxObject;
|
||||||
|
|
||||||
|
// var
|
||||||
|
|
||||||
public function new(x:Float, y:Float)
|
public function new(x:Float, y:Float)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package;
|
||||||
|
|
||||||
|
import flixel.FlxG;
|
||||||
|
|
||||||
|
class Highscore
|
||||||
|
{
|
||||||
|
public static var songScores:Map<String, Int> = new Map();
|
||||||
|
|
||||||
|
public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Void
|
||||||
|
{
|
||||||
|
var daSong:String = formatSong(song, diff);
|
||||||
|
|
||||||
|
NGio.postScore(score, song);
|
||||||
|
|
||||||
|
if (songScores.exists(daSong))
|
||||||
|
{
|
||||||
|
if (songScores.get(daSong) < score)
|
||||||
|
setScore(daSong, score);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setScore(daSong, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void
|
||||||
|
{
|
||||||
|
NGio.postScore(score, "Week " + week);
|
||||||
|
|
||||||
|
var daWeek:String = formatSong('week' + week, diff);
|
||||||
|
|
||||||
|
if (songScores.exists(daWeek))
|
||||||
|
{
|
||||||
|
if (songScores.get(daWeek) < score)
|
||||||
|
setScore(daWeek, score);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setScore(daWeek, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE
|
||||||
|
*/
|
||||||
|
static function setScore(song:String, score:Int):Void
|
||||||
|
{
|
||||||
|
// Reminder that I don't need to format this song, it should come formatted!
|
||||||
|
songScores.set(song, score);
|
||||||
|
FlxG.save.data.songScores = songScores;
|
||||||
|
FlxG.save.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function formatSong(song:String, diff:Int):String
|
||||||
|
{
|
||||||
|
var daSong:String = song;
|
||||||
|
|
||||||
|
if (diff == 0)
|
||||||
|
daSong += '-easy';
|
||||||
|
else if (diff == 2)
|
||||||
|
daSong += '-hard';
|
||||||
|
|
||||||
|
return daSong;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getScore(song:String, diff:Int):Int
|
||||||
|
{
|
||||||
|
if (!songScores.exists(formatSong(song, diff)))
|
||||||
|
setScore(formatSong(song, diff), 0);
|
||||||
|
|
||||||
|
return songScores.get(formatSong(song, diff));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getWeekScore(week:Int, diff:Int):Int
|
||||||
|
{
|
||||||
|
if (!songScores.exists(formatSong('week' + week, diff)))
|
||||||
|
setScore(formatSong('week' + week, diff), 0);
|
||||||
|
|
||||||
|
return songScores.get(formatSong('week' + week, diff));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function load():Void
|
||||||
|
{
|
||||||
|
if (FlxG.save.data.songScores != null)
|
||||||
|
{
|
||||||
|
songScores = FlxG.save.data.songScores;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,8 +6,11 @@ import flixel.FlxSprite;
|
|||||||
import flixel.effects.FlxFlicker;
|
import flixel.effects.FlxFlicker;
|
||||||
import flixel.graphics.frames.FlxAtlasFrames;
|
import flixel.graphics.frames.FlxAtlasFrames;
|
||||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
|
import flixel.text.FlxText;
|
||||||
import flixel.tweens.FlxEase;
|
import flixel.tweens.FlxEase;
|
||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
|
import flixel.util.FlxColor;
|
||||||
|
import lime.app.Application;
|
||||||
|
|
||||||
class MainMenuState extends MusicBeatState
|
class MainMenuState extends MusicBeatState
|
||||||
{
|
{
|
||||||
@@ -15,7 +18,7 @@ class MainMenuState extends MusicBeatState
|
|||||||
|
|
||||||
var menuItems:FlxTypedGroup<FlxSprite>;
|
var menuItems:FlxTypedGroup<FlxSprite>;
|
||||||
|
|
||||||
var optionShit:Array<String> = ['story mode', 'freeplay', 'donate'];
|
var optionShit:Array<String> = ['story mode', 'freeplay', 'options', 'donate'];
|
||||||
|
|
||||||
var magenta:FlxSprite;
|
var magenta:FlxSprite;
|
||||||
var camFollow:FlxObject;
|
var camFollow:FlxObject;
|
||||||
@@ -36,7 +39,7 @@ class MainMenuState extends MusicBeatState
|
|||||||
camFollow = new FlxObject(0, 0, 1, 1);
|
camFollow = new FlxObject(0, 0, 1, 1);
|
||||||
add(camFollow);
|
add(camFollow);
|
||||||
|
|
||||||
magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuBGMagenta__png);
|
magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuDesat__png);
|
||||||
magenta.scrollFactor.x = 0;
|
magenta.scrollFactor.x = 0;
|
||||||
magenta.scrollFactor.y = 0.18;
|
magenta.scrollFactor.y = 0.18;
|
||||||
magenta.setGraphicSize(Std.int(magenta.width * 1.1));
|
magenta.setGraphicSize(Std.int(magenta.width * 1.1));
|
||||||
@@ -44,6 +47,7 @@ class MainMenuState extends MusicBeatState
|
|||||||
magenta.screenCenter();
|
magenta.screenCenter();
|
||||||
magenta.visible = false;
|
magenta.visible = false;
|
||||||
magenta.antialiasing = true;
|
magenta.antialiasing = true;
|
||||||
|
magenta.color = 0xFFfd719b;
|
||||||
add(magenta);
|
add(magenta);
|
||||||
// magenta.scrollFactor.set();
|
// magenta.scrollFactor.set();
|
||||||
|
|
||||||
@@ -68,75 +72,88 @@ class MainMenuState extends MusicBeatState
|
|||||||
|
|
||||||
FlxG.camera.follow(camFollow, null, 0.06);
|
FlxG.camera.follow(camFollow, null, 0.06);
|
||||||
|
|
||||||
|
var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "v" + Application.current.meta.get('version'));
|
||||||
|
versionShit.scrollFactor.set();
|
||||||
|
versionShit.setFormat("VCR OSD Mono", 16, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
|
||||||
|
add(versionShit);
|
||||||
|
|
||||||
changeItem();
|
changeItem();
|
||||||
|
|
||||||
super.create();
|
super.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var selectedSomethin:Bool = false;
|
||||||
|
|
||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
if (controls.UP_P)
|
if (!selectedSomethin)
|
||||||
{
|
{
|
||||||
FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt);
|
if (controls.UP_P)
|
||||||
changeItem(-1);
|
{
|
||||||
}
|
FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt);
|
||||||
|
changeItem(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if (controls.DOWN_P)
|
if (controls.DOWN_P)
|
||||||
{
|
{
|
||||||
FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt);
|
FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt);
|
||||||
changeItem(1);
|
changeItem(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.BACK)
|
if (controls.BACK)
|
||||||
{
|
{
|
||||||
FlxG.switchState(new TitleState());
|
FlxG.switchState(new TitleState());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controls.ACCEPT)
|
||||||
|
{
|
||||||
|
if (optionShit[curSelected] == 'donate')
|
||||||
|
{
|
||||||
|
FlxG.openURL('https://ninja-muffin24.itch.io/funkin');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectedSomethin = true;
|
||||||
|
FlxG.sound.play('assets/sounds/confirmMenu' + TitleState.soundExt);
|
||||||
|
|
||||||
|
FlxFlicker.flicker(magenta, 1.1, 0.15, false);
|
||||||
|
|
||||||
|
menuItems.forEach(function(spr:FlxSprite)
|
||||||
|
{
|
||||||
|
if (curSelected != spr.ID)
|
||||||
|
{
|
||||||
|
FlxTween.tween(spr, {alpha: 0}, 0.4, {
|
||||||
|
ease: FlxEase.quadOut,
|
||||||
|
onComplete: function(twn:FlxTween)
|
||||||
|
{
|
||||||
|
spr.kill();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker)
|
||||||
|
{
|
||||||
|
var daChoice:String = optionShit[curSelected];
|
||||||
|
|
||||||
|
switch (daChoice)
|
||||||
|
{
|
||||||
|
case 'story mode':
|
||||||
|
FlxG.switchState(new StoryMenuState());
|
||||||
|
case 'freeplay':
|
||||||
|
FlxG.switchState(new FreeplayState());
|
||||||
|
case 'options':
|
||||||
|
FlxG.switchState(new OptionsMenu());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
if (controls.ACCEPT)
|
|
||||||
{
|
|
||||||
if (optionShit[curSelected] == 'donate')
|
|
||||||
{
|
|
||||||
FlxG.openURL('https://ninja-muffin24.itch.io/funkin');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FlxG.sound.play('assets/sounds/confirmMenu' + TitleState.soundExt);
|
|
||||||
|
|
||||||
FlxFlicker.flicker(magenta, 1.1, 0.15, false);
|
|
||||||
|
|
||||||
menuItems.forEach(function(spr:FlxSprite)
|
|
||||||
{
|
|
||||||
if (curSelected != spr.ID)
|
|
||||||
{
|
|
||||||
FlxTween.tween(spr, {alpha: 0}, 0.4, {
|
|
||||||
ease: FlxEase.quadOut,
|
|
||||||
onComplete: function(twn:FlxTween)
|
|
||||||
{
|
|
||||||
spr.kill();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker)
|
|
||||||
{
|
|
||||||
var daChoice:String = optionShit[curSelected];
|
|
||||||
|
|
||||||
switch (daChoice)
|
|
||||||
{
|
|
||||||
case 'story mode':
|
|
||||||
FlxG.switchState(new StoryMenuState());
|
|
||||||
case 'freeplay':
|
|
||||||
FlxG.switchState(new FreeplayState());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuItems.forEach(function(spr:FlxSprite)
|
menuItems.forEach(function(spr:FlxSprite)
|
||||||
{
|
{
|
||||||
spr.screenCenter(X);
|
spr.screenCenter(X);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class MenuItem extends FlxSpriteGroup
|
|||||||
public var targetY:Float = 0;
|
public var targetY:Float = 0;
|
||||||
public var week:FlxSprite;
|
public var week:FlxSprite;
|
||||||
|
|
||||||
public function new(x:Float, y:Float, weekNum:Int = 0, unlocked:Bool = false)
|
public function new(x:Float, y:Float, weekNum:Int = 0)
|
||||||
{
|
{
|
||||||
super(x, y);
|
super(x, y);
|
||||||
|
|
||||||
@@ -18,18 +18,15 @@ class MenuItem extends FlxSpriteGroup
|
|||||||
|
|
||||||
week = new FlxSprite();
|
week = new FlxSprite();
|
||||||
week.frames = tex;
|
week.frames = tex;
|
||||||
week.animation.addByPrefix('week0', "WEEK1 select", 24);
|
// TUTORIAL IS WEEK 0
|
||||||
week.animation.addByPrefix('week1', "week2 select", 24);
|
week.animation.addByPrefix('week0', 'tutorial selected', 24);
|
||||||
|
week.animation.addByPrefix('week1', "WEEK1 select", 24);
|
||||||
|
week.animation.addByPrefix('week2', "week2 select", 24);
|
||||||
add(week);
|
add(week);
|
||||||
|
|
||||||
week.animation.play('week' + weekNum);
|
week.animation.play('week' + weekNum);
|
||||||
week.animation.pause();
|
week.animation.pause();
|
||||||
week.updateHitbox();
|
week.updateHitbox();
|
||||||
|
|
||||||
if (!unlocked)
|
|
||||||
{
|
|
||||||
week.alpha = 0.6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package;
|
package;
|
||||||
|
|
||||||
|
import flixel.FlxG;
|
||||||
import flixel.FlxSubState;
|
import flixel.FlxSubState;
|
||||||
|
|
||||||
class MusicBeatSubstate extends FlxSubState
|
class MusicBeatSubstate extends FlxSubState
|
||||||
|
|||||||
@@ -109,6 +109,24 @@ class NGio
|
|||||||
// more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores
|
// more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static public function postScore(score:Int = 0, song:String)
|
||||||
|
{
|
||||||
|
if (isLoggedIn)
|
||||||
|
{
|
||||||
|
for (id in NG.core.scoreBoards.keys())
|
||||||
|
{
|
||||||
|
var board = NG.core.scoreBoards.get(id);
|
||||||
|
|
||||||
|
if (song == board.name)
|
||||||
|
{
|
||||||
|
board.postScore(score, "Uhh meow?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace('loaded scoreboard id:$id, name:${board.name}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onNGScoresFetch():Void
|
function onNGScoresFetch():Void
|
||||||
{
|
{
|
||||||
scoreboardsLoaded = true;
|
scoreboardsLoaded = true;
|
||||||
@@ -128,6 +146,15 @@ class NGio
|
|||||||
// NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores;
|
// NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static public function logEvent(event:String)
|
||||||
|
{
|
||||||
|
if (isLoggedIn)
|
||||||
|
{
|
||||||
|
NG.core.calls.event.logEvent(event);
|
||||||
|
trace('should have logged: ' + event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline static public function unlockMedal(id:Int)
|
inline static public function unlockMedal(id:Int)
|
||||||
{
|
{
|
||||||
if (isLoggedIn)
|
if (isLoggedIn)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package;
|
||||||
|
|
||||||
|
import flixel.FlxG;
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
import flixel.util.FlxColor;
|
||||||
|
|
||||||
|
class OptionsMenu extends MusicBeatState
|
||||||
|
{
|
||||||
|
override function create()
|
||||||
|
{
|
||||||
|
var menuBG:FlxSprite = new FlxSprite().loadGraphic(AssetPaths.menuDesat__png);
|
||||||
|
menuBG.color = 0xFFea71fd;
|
||||||
|
menuBG.setGraphicSize(Std.int(menuBG.width * 1.1));
|
||||||
|
menuBG.updateHitbox();
|
||||||
|
menuBG.screenCenter();
|
||||||
|
menuBG.antialiasing = true;
|
||||||
|
add(menuBG);
|
||||||
|
|
||||||
|
super.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
override function update(elapsed:Float)
|
||||||
|
{
|
||||||
|
if (controls.BACK)
|
||||||
|
FlxG.switchState(new MainMenuState());
|
||||||
|
|
||||||
|
super.update(elapsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package;
|
||||||
|
|
||||||
|
class OptionsSubState extends MusicBeatSubstate
|
||||||
|
{
|
||||||
|
var textMenuItems:Array<String> = ['Master Volume', 'Sound Volume'];
|
||||||
|
|
||||||
|
public function new()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ class PlayState extends MusicBeatState
|
|||||||
public static var curLevel:String = 'Tutorial';
|
public static var curLevel:String = 'Tutorial';
|
||||||
public static var SONG:SwagSong;
|
public static var SONG:SwagSong;
|
||||||
public static var isStoryMode:Bool = false;
|
public static var isStoryMode:Bool = false;
|
||||||
|
public static var storyWeek:Int = 0;
|
||||||
public static var storyPlaylist:Array<String> = [];
|
public static var storyPlaylist:Array<String> = [];
|
||||||
public static var storyDifficulty:Int = 1;
|
public static var storyDifficulty:Int = 1;
|
||||||
|
|
||||||
@@ -78,8 +79,12 @@ class PlayState extends MusicBeatState
|
|||||||
var dialogue:Array<String> = ['blah blah blah', 'coolswag'];
|
var dialogue:Array<String> = ['blah blah blah', 'coolswag'];
|
||||||
|
|
||||||
var halloweenBG:FlxSprite;
|
var halloweenBG:FlxSprite;
|
||||||
|
var isHalloween:Bool = false;
|
||||||
|
|
||||||
var talking:Bool = true;
|
var talking:Bool = true;
|
||||||
|
var songScore:Int = 0;
|
||||||
|
|
||||||
|
public static var campaignScore:Int = 0;
|
||||||
|
|
||||||
override public function create()
|
override public function create()
|
||||||
{
|
{
|
||||||
@@ -135,6 +140,8 @@ class PlayState extends MusicBeatState
|
|||||||
halloweenBG.animation.play('idle');
|
halloweenBG.animation.play('idle');
|
||||||
halloweenBG.antialiasing = true;
|
halloweenBG.antialiasing = true;
|
||||||
add(halloweenBG);
|
add(halloweenBG);
|
||||||
|
|
||||||
|
isHalloween = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -558,7 +565,7 @@ class PlayState extends MusicBeatState
|
|||||||
{
|
{
|
||||||
if (FlxG.sound.music != null)
|
if (FlxG.sound.music != null)
|
||||||
{
|
{
|
||||||
vocals.time = FlxG.sound.music.time;
|
vocals.time = Conductor.songPosition;
|
||||||
|
|
||||||
FlxG.sound.music.play();
|
FlxG.sound.music.play();
|
||||||
vocals.play();
|
vocals.play();
|
||||||
@@ -591,15 +598,16 @@ class PlayState extends MusicBeatState
|
|||||||
openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
|
openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FlxG.keys.justPressed.ESCAPE)
|
if (FlxG.keys.justPressed.SEVEN)
|
||||||
{
|
{
|
||||||
// FlxG.switchState(new ChartingState());
|
FlxG.switchState(new ChartingState());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlxG.watch.addQuick('VOL', vocals.amplitudeLeft);
|
// FlxG.watch.addQuick('VOL', vocals.amplitudeLeft);
|
||||||
// FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight);
|
// FlxG.watch.addQuick('VOLRight', vocals.amplitudeRight);
|
||||||
|
|
||||||
healthHeads.setGraphicSize(Std.int(FlxMath.lerp(100, healthHeads.width, 0.98)));
|
healthHeads.setGraphicSize(Std.int(FlxMath.lerp(150, healthHeads.width, 0.50)));
|
||||||
|
healthHeads.updateHitbox();
|
||||||
healthHeads.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (healthHeads.width / 2);
|
healthHeads.x = healthBar.x + (healthBar.width * (FlxMath.remapToRange(healthBar.percent, 0, 100, 100, 0) * 0.01)) - (healthHeads.width / 2);
|
||||||
|
|
||||||
if (health > 2)
|
if (health > 2)
|
||||||
@@ -612,8 +620,11 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
/* if (FlxG.keys.justPressed.NINE)
|
/* if (FlxG.keys.justPressed.NINE)
|
||||||
FlxG.switchState(new Charting()); */
|
FlxG.switchState(new Charting()); */
|
||||||
// if (FlxG.keys.justPressed.EIGHT)
|
|
||||||
// FlxG.switchState(new AnimationDebug(SONG.player2));
|
#if debug
|
||||||
|
if (FlxG.keys.justPressed.EIGHT)
|
||||||
|
FlxG.switchState(new AnimationDebug(SONG.player1));
|
||||||
|
#end
|
||||||
|
|
||||||
if (startingSong)
|
if (startingSong)
|
||||||
{
|
{
|
||||||
@@ -677,7 +688,8 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
if (camZooming)
|
if (camZooming)
|
||||||
{
|
{
|
||||||
FlxG.camera.zoom = FlxMath.lerp(1.05, FlxG.camera.zoom, 0.96);
|
FlxG.camera.zoom = FlxMath.lerp(1.05, FlxG.camera.zoom, 0.95);
|
||||||
|
camHUD.zoom = FlxMath.lerp(1, camHUD.zoom, 0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlxG.watch.addQuick("beatShit", totalBeats);
|
FlxG.watch.addQuick("beatShit", totalBeats);
|
||||||
@@ -759,6 +771,9 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
if (!daNote.mustPress && daNote.wasGoodHit)
|
if (!daNote.mustPress && daNote.wasGoodHit)
|
||||||
{
|
{
|
||||||
|
if (SONG.song != 'Tutorial')
|
||||||
|
camZooming = true;
|
||||||
|
|
||||||
switch (Math.abs(daNote.noteData))
|
switch (Math.abs(daNote.noteData))
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
@@ -780,6 +795,7 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
|
|
||||||
daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
|
daNote.y = (strumLine.y - (Conductor.songPosition - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
|
||||||
|
|
||||||
// WIP interpolation shit? Need to fix the pause issue
|
// WIP interpolation shit? Need to fix the pause issue
|
||||||
// daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
|
// daNote.y = (strumLine.y - (songTime - daNote.strumTime) * (0.45 * PlayState.SONG.speed));
|
||||||
|
|
||||||
@@ -808,8 +824,12 @@ class PlayState extends MusicBeatState
|
|||||||
{
|
{
|
||||||
trace('SONG DONE' + isStoryMode);
|
trace('SONG DONE' + isStoryMode);
|
||||||
|
|
||||||
|
Highscore.saveScore(SONG.song, songScore, storyDifficulty);
|
||||||
|
|
||||||
if (isStoryMode)
|
if (isStoryMode)
|
||||||
{
|
{
|
||||||
|
campaignScore += songScore;
|
||||||
|
|
||||||
storyPlaylist.remove(storyPlaylist[0]);
|
storyPlaylist.remove(storyPlaylist[0]);
|
||||||
|
|
||||||
if (storyPlaylist.length <= 0)
|
if (storyPlaylist.length <= 0)
|
||||||
@@ -819,6 +839,12 @@ class PlayState extends MusicBeatState
|
|||||||
FlxG.switchState(new StoryMenuState());
|
FlxG.switchState(new StoryMenuState());
|
||||||
|
|
||||||
StoryMenuState.weekUnlocked[1] = true;
|
StoryMenuState.weekUnlocked[1] = true;
|
||||||
|
|
||||||
|
NGio.unlockMedal(60961);
|
||||||
|
Highscore.saveWeekScore(storyWeek, campaignScore, storyDifficulty);
|
||||||
|
|
||||||
|
FlxG.save.data.weekUnlocked = StoryMenuState.weekUnlocked;
|
||||||
|
FlxG.save.flush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -856,22 +882,28 @@ class PlayState extends MusicBeatState
|
|||||||
//
|
//
|
||||||
|
|
||||||
var rating:FlxSprite = new FlxSprite();
|
var rating:FlxSprite = new FlxSprite();
|
||||||
|
var score:Int = 350;
|
||||||
|
|
||||||
var daRating:String = "sick";
|
var daRating:String = "sick";
|
||||||
|
|
||||||
if (noteDiff > Conductor.safeZoneOffset * 0.9)
|
if (noteDiff > Conductor.safeZoneOffset * 0.9)
|
||||||
{
|
{
|
||||||
daRating = 'shit';
|
daRating = 'shit';
|
||||||
|
score = 50;
|
||||||
}
|
}
|
||||||
else if (noteDiff > Conductor.safeZoneOffset * 0.75)
|
else if (noteDiff > Conductor.safeZoneOffset * 0.75)
|
||||||
{
|
{
|
||||||
daRating = 'bad';
|
daRating = 'bad';
|
||||||
|
score = 100;
|
||||||
}
|
}
|
||||||
else if (noteDiff > Conductor.safeZoneOffset * 0.2)
|
else if (noteDiff > Conductor.safeZoneOffset * 0.2)
|
||||||
{
|
{
|
||||||
daRating = 'good';
|
daRating = 'good';
|
||||||
|
score = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
songScore += score;
|
||||||
|
|
||||||
/* if (combo > 60)
|
/* if (combo > 60)
|
||||||
daRating = 'sick';
|
daRating = 'sick';
|
||||||
else if (combo > 12)
|
else if (combo > 12)
|
||||||
@@ -921,7 +953,9 @@ class PlayState extends MusicBeatState
|
|||||||
numScore.acceleration.y = FlxG.random.int(200, 300);
|
numScore.acceleration.y = FlxG.random.int(200, 300);
|
||||||
numScore.velocity.y -= FlxG.random.int(140, 160);
|
numScore.velocity.y -= FlxG.random.int(140, 160);
|
||||||
numScore.velocity.x = FlxG.random.float(-5, 5);
|
numScore.velocity.x = FlxG.random.float(-5, 5);
|
||||||
add(numScore);
|
|
||||||
|
if (combo >= 10 || combo == 0)
|
||||||
|
add(numScore);
|
||||||
|
|
||||||
FlxTween.tween(numScore, {alpha: 0}, 0.2, {
|
FlxTween.tween(numScore, {alpha: 0}, 0.2, {
|
||||||
onComplete: function(tween:FlxTween)
|
onComplete: function(tween:FlxTween)
|
||||||
@@ -1107,6 +1141,8 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
combo = 0;
|
combo = 0;
|
||||||
|
|
||||||
|
songScore -= 10;
|
||||||
|
|
||||||
FlxG.sound.play('assets/sounds/missnote' + FlxG.random.int(1, 3) + TitleState.soundExt, FlxG.random.float(0.1, 0.2));
|
FlxG.sound.play('assets/sounds/missnote' + FlxG.random.int(1, 3) + TitleState.soundExt, FlxG.random.float(0.1, 0.2));
|
||||||
// FlxG.sound.play('assets/sounds/missnote1' + TitleState.soundExt, 1, false);
|
// FlxG.sound.play('assets/sounds/missnote1' + TitleState.soundExt, 1, false);
|
||||||
// FlxG.log.add('played imss note');
|
// FlxG.log.add('played imss note');
|
||||||
@@ -1229,6 +1265,18 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lightningStrikeShit():Void
|
||||||
|
{
|
||||||
|
FlxG.sound.play('assets/sounds/thunder_' + FlxG.random.int(1, 2) + TitleState.soundExt);
|
||||||
|
halloweenBG.animation.play('lightning');
|
||||||
|
|
||||||
|
lightningStrikeBeat = curBeat;
|
||||||
|
lightningOffset = FlxG.random.int(8, 24);
|
||||||
|
|
||||||
|
boyfriend.playAnim('scared', true);
|
||||||
|
gf.playAnim('scared', true);
|
||||||
|
}
|
||||||
|
|
||||||
override function stepHit()
|
override function stepHit()
|
||||||
{
|
{
|
||||||
if (SONG.needsVoices)
|
if (SONG.needsVoices)
|
||||||
@@ -1250,6 +1298,9 @@ class PlayState extends MusicBeatState
|
|||||||
super.stepHit();
|
super.stepHit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lightningStrikeBeat:Int = 0;
|
||||||
|
var lightningOffset:Int = 8;
|
||||||
|
|
||||||
override function beatHit()
|
override function beatHit()
|
||||||
{
|
{
|
||||||
super.beatHit();
|
super.beatHit();
|
||||||
@@ -1276,9 +1327,13 @@ class PlayState extends MusicBeatState
|
|||||||
// FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM);
|
// FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM);
|
||||||
|
|
||||||
if (camZooming && FlxG.camera.zoom < 1.35 && totalBeats % 4 == 0)
|
if (camZooming && FlxG.camera.zoom < 1.35 && totalBeats % 4 == 0)
|
||||||
FlxG.camera.zoom += 0.025;
|
{
|
||||||
|
FlxG.camera.zoom += 0.015;
|
||||||
|
camHUD.zoom += 0.03;
|
||||||
|
}
|
||||||
|
|
||||||
healthHeads.setGraphicSize(Std.int(healthHeads.width + 20));
|
healthHeads.setGraphicSize(Std.int(healthHeads.width + 30));
|
||||||
|
healthHeads.updateHitbox();
|
||||||
|
|
||||||
if (totalBeats % gfSpeed == 0)
|
if (totalBeats % gfSpeed == 0)
|
||||||
{
|
{
|
||||||
@@ -1297,5 +1352,10 @@ class PlayState extends MusicBeatState
|
|||||||
dad.playAnim('cheer', true);
|
dad.playAnim('cheer', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset)
|
||||||
|
{
|
||||||
|
lightningStrikeShit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,21 @@ class PlayerSettings
|
|||||||
static public var player1(default, null):PlayerSettings;
|
static public var player1(default, null):PlayerSettings;
|
||||||
static public var player2(default, null):PlayerSettings;
|
static public var player2(default, null):PlayerSettings;
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
static public final onAvatarAdd = new FlxTypedSignal<PlayerSettings->Void>();
|
static public final onAvatarAdd = new FlxTypedSignal<PlayerSettings->Void>();
|
||||||
static public final onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
|
static public final onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
|
||||||
|
#else
|
||||||
|
static public var onAvatarAdd = new FlxTypedSignal<PlayerSettings->Void>();
|
||||||
|
static public var onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
|
||||||
|
#end
|
||||||
|
|
||||||
public var id(default, null):Int;
|
public var id(default, null):Int;
|
||||||
|
|
||||||
|
#if (haxe >= "4.0.0")
|
||||||
public final controls:Controls;
|
public final controls:Controls;
|
||||||
|
#else
|
||||||
|
public var controls:Controls;
|
||||||
|
#end
|
||||||
|
|
||||||
// public var avatar:Player;
|
// public var avatar:Player;
|
||||||
// public var camera(get, never):PlayCamera;
|
// public var camera(get, never):PlayCamera;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class Song
|
|||||||
|
|
||||||
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
|
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
|
||||||
{
|
{
|
||||||
|
|
||||||
var rawJson = Assets.getText('assets/data/' + folder.toLowerCase() + '/' + jsonInput.toLowerCase() + '.json').trim();
|
var rawJson = Assets.getText('assets/data/' + folder.toLowerCase() + '/' + jsonInput.toLowerCase() + '.json').trim();
|
||||||
|
|
||||||
while (!rawJson.endsWith("}"))
|
while (!rawJson.endsWith("}"))
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import flixel.FlxSprite;
|
|||||||
import flixel.graphics.frames.FlxAtlasFrames;
|
import flixel.graphics.frames.FlxAtlasFrames;
|
||||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
import flixel.group.FlxGroup;
|
import flixel.group.FlxGroup;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
import flixel.text.FlxText;
|
import flixel.text.FlxText;
|
||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
import flixel.util.FlxTimer;
|
import flixel.util.FlxTimer;
|
||||||
@@ -16,12 +17,12 @@ class StoryMenuState extends MusicBeatState
|
|||||||
{
|
{
|
||||||
var scoreText:FlxText;
|
var scoreText:FlxText;
|
||||||
|
|
||||||
var weekData:Array<Dynamic> = [['Tutorial', 'Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']];
|
var weekData:Array<Dynamic> = [['Tutorial'], ['Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South']];
|
||||||
var curDifficulty:Int = 1;
|
var curDifficulty:Int = 1;
|
||||||
|
|
||||||
public static var weekUnlocked:Array<Bool> = [true, false];
|
public static var weekUnlocked:Array<Bool> = [true, true, false];
|
||||||
|
|
||||||
var weekCharacters:Array<Dynamic> = [['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']];
|
var weekCharacters:Array<Dynamic> = [['dad', 'bf', 'gf'], ['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']];
|
||||||
var curWeek:Int = 0;
|
var curWeek:Int = 0;
|
||||||
|
|
||||||
var txtTracklist:FlxText;
|
var txtTracklist:FlxText;
|
||||||
@@ -38,8 +39,11 @@ class StoryMenuState extends MusicBeatState
|
|||||||
|
|
||||||
override function create()
|
override function create()
|
||||||
{
|
{
|
||||||
if (!FlxG.sound.music.playing)
|
if (FlxG.sound.music != null)
|
||||||
FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
|
{
|
||||||
|
if (!FlxG.sound.music.playing)
|
||||||
|
FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt);
|
||||||
|
}
|
||||||
|
|
||||||
persistentUpdate = persistentDraw = true;
|
persistentUpdate = persistentDraw = true;
|
||||||
|
|
||||||
@@ -65,12 +69,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
|
|
||||||
for (i in 0...weekData.length)
|
for (i in 0...weekData.length)
|
||||||
{
|
{
|
||||||
var unlocked:Bool = true;
|
var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i);
|
||||||
|
|
||||||
if (i == 1)
|
|
||||||
unlocked = false;
|
|
||||||
|
|
||||||
var weekThing:MenuItem = new MenuItem(0, yellowBG.y + yellowBG.height + 10, i, unlocked);
|
|
||||||
weekThing.y += ((weekThing.height + 20) * i);
|
weekThing.y += ((weekThing.height + 20) * i);
|
||||||
weekThing.targetY = i;
|
weekThing.targetY = i;
|
||||||
grpWeekText.add(weekThing);
|
grpWeekText.add(weekThing);
|
||||||
@@ -79,6 +78,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
weekThing.antialiasing = true;
|
weekThing.antialiasing = true;
|
||||||
// weekThing.updateHitbox();
|
// weekThing.updateHitbox();
|
||||||
|
|
||||||
|
// Needs an offset thingie
|
||||||
if (!weekUnlocked[i])
|
if (!weekUnlocked[i])
|
||||||
{
|
{
|
||||||
var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x);
|
var lock:FlxSprite = new FlxSprite(weekThing.width + 10 + weekThing.x);
|
||||||
@@ -117,7 +117,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
difficultySelectors = new FlxGroup();
|
difficultySelectors = new FlxGroup();
|
||||||
add(difficultySelectors);
|
add(difficultySelectors);
|
||||||
|
|
||||||
leftArrow = new FlxSprite(grpWeekText.members[0].x + 370, grpWeekText.members[0].y + 10);
|
leftArrow = new FlxSprite(grpWeekText.members[0].x + grpWeekText.members[0].width + 10, grpWeekText.members[0].y + 10);
|
||||||
leftArrow.frames = ui_tex;
|
leftArrow.frames = ui_tex;
|
||||||
leftArrow.animation.addByPrefix('idle', "arrow left");
|
leftArrow.animation.addByPrefix('idle', "arrow left");
|
||||||
leftArrow.animation.addByPrefix('press', "arrow push left");
|
leftArrow.animation.addByPrefix('press', "arrow push left");
|
||||||
@@ -150,7 +150,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
txtTracklist.color = 0xFFe55777;
|
txtTracklist.color = 0xFFe55777;
|
||||||
add(txtTracklist);
|
add(txtTracklist);
|
||||||
// add(rankText);
|
// add(rankText);
|
||||||
// add(scoreText);
|
add(scoreText);
|
||||||
|
|
||||||
updateText();
|
updateText();
|
||||||
|
|
||||||
@@ -160,7 +160,9 @@ class StoryMenuState extends MusicBeatState
|
|||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
// scoreText.setFormat('VCR OSD Mono', 32);
|
// scoreText.setFormat('VCR OSD Mono', 32);
|
||||||
// scoreText.text = "Score SHIT";
|
lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.5));
|
||||||
|
|
||||||
|
scoreText.text = "WEEK SCORE:" + lerpScore;
|
||||||
// FlxG.watch.addQuick('font', scoreText.font);
|
// FlxG.watch.addQuick('font', scoreText.font);
|
||||||
|
|
||||||
difficultySelectors.visible = weekUnlocked[curWeek];
|
difficultySelectors.visible = weekUnlocked[curWeek];
|
||||||
@@ -245,6 +247,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
PlayState.storyDifficulty = curDifficulty;
|
PlayState.storyDifficulty = curDifficulty;
|
||||||
|
|
||||||
PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase());
|
PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase());
|
||||||
|
PlayState.storyWeek = curWeek;
|
||||||
new FlxTimer().start(1, function(tmr:FlxTimer)
|
new FlxTimer().start(1, function(tmr:FlxTimer)
|
||||||
{
|
{
|
||||||
if (FlxG.sound.music != null)
|
if (FlxG.sound.music != null)
|
||||||
@@ -282,10 +285,14 @@ class StoryMenuState extends MusicBeatState
|
|||||||
|
|
||||||
// USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP
|
// USING THESE WEIRD VALUES SO THAT IT DOESNT FLOAT UP
|
||||||
sprDifficulty.y = leftArrow.y - 15;
|
sprDifficulty.y = leftArrow.y - 15;
|
||||||
|
intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
|
||||||
|
|
||||||
FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07);
|
FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lerpScore:Int = 0;
|
||||||
|
var intendedScore:Int = 0;
|
||||||
|
|
||||||
function changeWeek(change:Int = 0):Void
|
function changeWeek(change:Int = 0):Void
|
||||||
{
|
{
|
||||||
curWeek += change;
|
curWeek += change;
|
||||||
@@ -300,6 +307,10 @@ class StoryMenuState extends MusicBeatState
|
|||||||
for (item in grpWeekText.members)
|
for (item in grpWeekText.members)
|
||||||
{
|
{
|
||||||
item.targetY = bullShit - curWeek;
|
item.targetY = bullShit - curWeek;
|
||||||
|
if (item.targetY == Std.int(0) && weekUnlocked[curWeek])
|
||||||
|
item.alpha = 1;
|
||||||
|
else
|
||||||
|
item.alpha = 0.6;
|
||||||
bullShit++;
|
bullShit++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,5 +337,7 @@ class StoryMenuState extends MusicBeatState
|
|||||||
|
|
||||||
txtTracklist.screenCenter(X);
|
txtTracklist.screenCenter(X);
|
||||||
txtTracklist.x -= FlxG.width * 0.35;
|
txtTracklist.x -= FlxG.width * 0.35;
|
||||||
|
|
||||||
|
intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,13 @@ class TitleState extends MusicBeatState
|
|||||||
['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'],
|
['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'],
|
||||||
['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'],
|
['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'],
|
||||||
['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'],
|
['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'],
|
||||||
['kiddbrute for president', 'vote now']];
|
['kiddbrute for president', 'vote now'], ['play dead estate', 'on newgrounds'], ['this is a god damn prototype', 'we workin on it okay'],
|
||||||
|
['WOMEN ARE real', 'this is official']];
|
||||||
|
|
||||||
var curWacky:Array<String> = [];
|
var curWacky:Array<String> = [];
|
||||||
|
|
||||||
|
var wackyImage:FlxSprite;
|
||||||
|
|
||||||
override public function create():Void
|
override public function create():Void
|
||||||
{
|
{
|
||||||
#if (!web)
|
#if (!web)
|
||||||
@@ -54,10 +57,22 @@ class TitleState extends MusicBeatState
|
|||||||
|
|
||||||
super.create();
|
super.create();
|
||||||
|
|
||||||
#if (!debug && NG_LOGIN)
|
#if (!switch && !debug && NG_LOGIN)
|
||||||
var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey);
|
var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
FlxG.save.bind('funkin', 'ninjamuffin99');
|
||||||
|
|
||||||
|
Highscore.load();
|
||||||
|
|
||||||
|
if (FlxG.save.data.weekUnlocked != null)
|
||||||
|
{
|
||||||
|
StoryMenuState.weekUnlocked = FlxG.save.data.weekUnlocked;
|
||||||
|
|
||||||
|
if (StoryMenuState.weekUnlocked.length < 3)
|
||||||
|
StoryMenuState.weekUnlocked.insert(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
#if SKIP_TO_PLAYSTATE
|
#if SKIP_TO_PLAYSTATE
|
||||||
FlxG.switchState(new StoryMenuState());
|
FlxG.switchState(new StoryMenuState());
|
||||||
#else
|
#else
|
||||||
@@ -177,6 +192,12 @@ class TitleState extends MusicBeatState
|
|||||||
override function update(elapsed:Float)
|
override function update(elapsed:Float)
|
||||||
{
|
{
|
||||||
Conductor.songPosition = FlxG.sound.music.time;
|
Conductor.songPosition = FlxG.sound.music.time;
|
||||||
|
// FlxG.watch.addQuick('amp', FlxG.sound.music.amplitude);
|
||||||
|
|
||||||
|
if (FlxG.keys.justPressed.F)
|
||||||
|
{
|
||||||
|
FlxG.fullscreen = !FlxG.fullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
var pressedEnter:Bool = FlxG.keys.justPressed.ENTER;
|
var pressedEnter:Bool = FlxG.keys.justPressed.ENTER;
|
||||||
|
|
||||||
@@ -190,7 +211,14 @@ class TitleState extends MusicBeatState
|
|||||||
|
|
||||||
if (pressedEnter && !transitioning && skippedIntro)
|
if (pressedEnter && !transitioning && skippedIntro)
|
||||||
{
|
{
|
||||||
|
#if !switch
|
||||||
NGio.unlockMedal(60960);
|
NGio.unlockMedal(60960);
|
||||||
|
|
||||||
|
// If it's Friday according to da clock
|
||||||
|
if (Date.now().getDay() == 5)
|
||||||
|
NGio.unlockMedal(61034);
|
||||||
|
#end
|
||||||
|
|
||||||
titleText.animation.play('press');
|
titleText.animation.play('press');
|
||||||
|
|
||||||
FlxG.camera.flash(FlxColor.WHITE, 1);
|
FlxG.camera.flash(FlxColor.WHITE, 1);
|
||||||
|
|||||||
@@ -1,227 +0,0 @@
|
|||||||
package io.newgrounds;
|
|
||||||
|
|
||||||
import io.newgrounds.utils.Dispatcher;
|
|
||||||
import io.newgrounds.utils.AsyncHttp;
|
|
||||||
import io.newgrounds.objects.Error;
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.objects.events.Result.ResultBase;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
|
|
||||||
import haxe.ds.StringMap;
|
|
||||||
import haxe.Json;
|
|
||||||
|
|
||||||
/** A generic way to handle calls agnostic to their type */
|
|
||||||
interface ICallable {
|
|
||||||
|
|
||||||
public var component(default, null):String;
|
|
||||||
|
|
||||||
public function send():Void;
|
|
||||||
public function queue():Void;
|
|
||||||
public function destroy():Void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Call<T:ResultBase>
|
|
||||||
implements ICallable {
|
|
||||||
|
|
||||||
public var component(default, null):String;
|
|
||||||
|
|
||||||
var _core:NGLite;
|
|
||||||
var _properties:StringMap<Dynamic>;
|
|
||||||
var _parameters:StringMap<Dynamic>;
|
|
||||||
var _requireSession:Bool;
|
|
||||||
var _isSecure:Bool;
|
|
||||||
|
|
||||||
// --- BASICALLY SIGNALS
|
|
||||||
var _dataHandlers:TypedDispatcher<Response<T>>;
|
|
||||||
var _successHandlers:Dispatcher;
|
|
||||||
var _httpErrorHandlers:TypedDispatcher<Error>;
|
|
||||||
var _statusHandlers:TypedDispatcher<Int>;
|
|
||||||
|
|
||||||
public function new (core:NGLite, component:String, requireSession:Bool = false, isSecure:Bool = false) {
|
|
||||||
|
|
||||||
_core = core;
|
|
||||||
this.component = component;
|
|
||||||
_requireSession = requireSession;
|
|
||||||
_isSecure = isSecure && core.encryptionHandler != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** adds a property to the input's object. **/
|
|
||||||
public function addProperty(name:String, value:Dynamic):Call<T> {
|
|
||||||
|
|
||||||
if (_properties == null)
|
|
||||||
_properties = new StringMap<Dynamic>();
|
|
||||||
|
|
||||||
_properties.set(name, value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** adds a parameter to the call's component object. **/
|
|
||||||
public function addComponentParameter(name:String, value:Dynamic, defaultValue:Dynamic = null):Call<T> {
|
|
||||||
|
|
||||||
if (value == defaultValue)//TODO?: allow sending null value
|
|
||||||
return this;
|
|
||||||
|
|
||||||
if (_parameters == null)
|
|
||||||
_parameters = new StringMap<Dynamic>();
|
|
||||||
|
|
||||||
_parameters.set(name, value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handy callback setter for chained call modifiers. Called when ng.io replies successfully */
|
|
||||||
public function addDataHandler(handler:Response<T>->Void):Call<T> {
|
|
||||||
|
|
||||||
if (_dataHandlers == null)
|
|
||||||
_dataHandlers = new TypedDispatcher<Response<T>>();
|
|
||||||
|
|
||||||
_dataHandlers.add(handler);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handy callback setter for chained call modifiers. Called when ng.io replies successfully */
|
|
||||||
public function addSuccessHandler(handler:Void->Void):Call<T> {
|
|
||||||
|
|
||||||
if (_successHandlers == null)
|
|
||||||
_successHandlers = new Dispatcher();
|
|
||||||
|
|
||||||
_successHandlers.add(handler);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handy callback setter for chained call modifiers. Called when ng.io does not reply for any reason */
|
|
||||||
public function addErrorHandler(handler:Error->Void):Call<T> {
|
|
||||||
|
|
||||||
if (_httpErrorHandlers == null)
|
|
||||||
_httpErrorHandlers = new TypedDispatcher<Error>();
|
|
||||||
|
|
||||||
_httpErrorHandlers.add(handler);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handy callback setter for chained call modifiers. No idea when this is called; */
|
|
||||||
public function addStatusHandler(handler:Int->Void):Call<T> {//TODO:learn what this is for
|
|
||||||
|
|
||||||
if (_statusHandlers == null)
|
|
||||||
_statusHandlers = new TypedDispatcher<Int>();
|
|
||||||
|
|
||||||
_statusHandlers.add(handler);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the call to the server, do not modify this object after calling this
|
|
||||||
* @param secure If encryption is enabled, it will encrypt the call.
|
|
||||||
**/
|
|
||||||
public function send():Void {
|
|
||||||
|
|
||||||
var data:Dynamic = {};
|
|
||||||
data.app_id = _core.appId;
|
|
||||||
data.call = {};
|
|
||||||
data.call.component = component;
|
|
||||||
|
|
||||||
if (_core.debug)
|
|
||||||
addProperty("debug", true);
|
|
||||||
|
|
||||||
if (_properties == null || !_properties.exists("session_id")) {
|
|
||||||
// --- HAS NO SESSION ID
|
|
||||||
|
|
||||||
if (_core.sessionId != null) {
|
|
||||||
// --- AUTO ADD SESSION ID
|
|
||||||
|
|
||||||
addProperty("session_id", _core.sessionId);
|
|
||||||
|
|
||||||
} else if (_requireSession){
|
|
||||||
|
|
||||||
_core.logError(new Error('cannot send "$component" call without a sessionId'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_properties != null) {
|
|
||||||
|
|
||||||
for (field in _properties.keys())
|
|
||||||
Reflect.setField(data, field, _properties.get(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_parameters != null) {
|
|
||||||
|
|
||||||
data.call.parameters = {};
|
|
||||||
|
|
||||||
for (field in _parameters.keys())
|
|
||||||
Reflect.setField(data.call.parameters, field, _parameters.get(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
_core.logVerbose('Post - ${Json.stringify(data)}');
|
|
||||||
|
|
||||||
if (_isSecure) {
|
|
||||||
|
|
||||||
var secureData = _core.encryptionHandler(Json.stringify(data.call));
|
|
||||||
data.call = {};
|
|
||||||
data.call.secure = secureData;
|
|
||||||
|
|
||||||
_core.logVerbose(' secure - $secureData');
|
|
||||||
}
|
|
||||||
|
|
||||||
_core.markCallPending(this);
|
|
||||||
|
|
||||||
AsyncHttp.send(_core, Json.stringify(data), onData, onHttpError, onStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds the call to the queue */
|
|
||||||
public function queue():Void {
|
|
||||||
|
|
||||||
_core.queueCall(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onData(reply:String):Void {
|
|
||||||
|
|
||||||
_core.logVerbose('Reply - $reply');
|
|
||||||
|
|
||||||
if (_dataHandlers == null && _successHandlers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var response = new Response<T>(_core, reply);
|
|
||||||
|
|
||||||
if (_dataHandlers != null)
|
|
||||||
_dataHandlers.dispatch(response);
|
|
||||||
|
|
||||||
if (response.success && response.result.success && _successHandlers != null)
|
|
||||||
_successHandlers.dispatch();
|
|
||||||
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onHttpError(message:String):Void {
|
|
||||||
|
|
||||||
_core.logError(message);
|
|
||||||
|
|
||||||
if (_httpErrorHandlers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var error = new Error(message);
|
|
||||||
_httpErrorHandlers.dispatch(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onStatus(status:Int):Void {
|
|
||||||
|
|
||||||
if (_statusHandlers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_statusHandlers.dispatch(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy():Void {
|
|
||||||
|
|
||||||
_core = null;
|
|
||||||
|
|
||||||
_properties = null;
|
|
||||||
_parameters = null;
|
|
||||||
|
|
||||||
_dataHandlers = null;
|
|
||||||
_successHandlers = null;
|
|
||||||
_httpErrorHandlers = null;
|
|
||||||
_statusHandlers = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,475 +0,0 @@
|
|||||||
package io.newgrounds;
|
|
||||||
|
|
||||||
#if ng_lite
|
|
||||||
typedef NG = NGLite; //TODO: test and make lite UI
|
|
||||||
#else
|
|
||||||
import io.newgrounds.utils.Dispatcher;
|
|
||||||
import io.newgrounds.objects.Error;
|
|
||||||
import io.newgrounds.objects.events.Result.SessionResult;
|
|
||||||
import io.newgrounds.objects.events.Result.MedalListResult;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreBoardResult;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.objects.User;
|
|
||||||
import io.newgrounds.objects.Medal;
|
|
||||||
import io.newgrounds.objects.Session;
|
|
||||||
import io.newgrounds.objects.ScoreBoard;
|
|
||||||
|
|
||||||
import haxe.ds.IntMap;
|
|
||||||
import haxe.Timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Newgrounds API for Haxe.
|
|
||||||
* Contains many things ripped from MSGhero
|
|
||||||
* - https://github.com/MSGhero/NG.hx
|
|
||||||
* @author GeoKureli
|
|
||||||
*/
|
|
||||||
class NG extends NGLite {
|
|
||||||
|
|
||||||
static public var core(default, null):NG;
|
|
||||||
static public var onCoreReady(default, null):Dispatcher = new Dispatcher();
|
|
||||||
|
|
||||||
// --- DATA
|
|
||||||
|
|
||||||
/** The logged in user */
|
|
||||||
public var user(get, never):User;
|
|
||||||
function get_user():User {
|
|
||||||
|
|
||||||
if (_session == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return _session.user;
|
|
||||||
}
|
|
||||||
public var passportUrl(get, never):String;
|
|
||||||
function get_passportUrl():String {
|
|
||||||
|
|
||||||
if (_session == null || _session.status != SessionStatus.REQUEST_LOGIN)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return _session.passportUrl;
|
|
||||||
}
|
|
||||||
public var medals(default, null):IntMap<Medal>;
|
|
||||||
public var scoreBoards(default, null):IntMap<ScoreBoard>;
|
|
||||||
|
|
||||||
// --- EVENTS
|
|
||||||
|
|
||||||
public var onLogin(default, null):Dispatcher;
|
|
||||||
public var onLogOut(default, null):Dispatcher;
|
|
||||||
public var onMedalsLoaded(default, null):Dispatcher;
|
|
||||||
public var onScoreBoardsLoaded(default, null):Dispatcher;
|
|
||||||
|
|
||||||
// --- MISC
|
|
||||||
|
|
||||||
public var loggedIn(default, null):Bool;
|
|
||||||
public var attemptingLogin(default, null):Bool;
|
|
||||||
|
|
||||||
var _loginCancelled:Bool;
|
|
||||||
var _passportCallback:Void->Void;
|
|
||||||
|
|
||||||
var _session:Session;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iniitializes the API, call before utilizing any other component
|
|
||||||
* @param appId The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project.
|
|
||||||
* @param sessionId A unique session id used to identify the active user.
|
|
||||||
**/
|
|
||||||
public function new(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void) {
|
|
||||||
|
|
||||||
_session = new Session(this);
|
|
||||||
onLogin = new Dispatcher();
|
|
||||||
onLogOut = new Dispatcher();
|
|
||||||
onMedalsLoaded = new Dispatcher();
|
|
||||||
onScoreBoardsLoaded = new Dispatcher();
|
|
||||||
|
|
||||||
attemptingLogin = sessionId != null;
|
|
||||||
|
|
||||||
super(appId, sessionId, onSessionFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates NG.core, the heart and soul of the API. This is not the only way to create an instance,
|
|
||||||
* nor is NG a forced singleton, but it's the only way to set the static NG.core.
|
|
||||||
**/
|
|
||||||
static public function create(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void):Void {
|
|
||||||
|
|
||||||
core = new NG(appId, sessionId, onSessionFail);
|
|
||||||
|
|
||||||
onCoreReady.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates NG.core, and tries to create a session. This is not the only way to create an instance,
|
|
||||||
* nor is NG a forced singleton, but it's the only way to set the static NG.core.
|
|
||||||
**/
|
|
||||||
static public function createAndCheckSession
|
|
||||||
( appId = "test"
|
|
||||||
, backupSession:String = null
|
|
||||||
, ?onSessionFail:Error->Void
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
var session = NGLite.getSessionId();
|
|
||||||
if (session == null)
|
|
||||||
session = backupSession;
|
|
||||||
|
|
||||||
create(appId, session, onSessionFail);
|
|
||||||
|
|
||||||
core.host = getHost();
|
|
||||||
if (core.sessionId != null)
|
|
||||||
core.attemptingLogin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// APP
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
override function checkInitialSession(failHandler:Error->Void, response:Response<SessionResult>):Void {
|
|
||||||
|
|
||||||
onSessionReceive(response, null, null, failHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins the login process
|
|
||||||
*
|
|
||||||
* @param onSuccess Called when the login is a success
|
|
||||||
* @param onPending Called when the passportUrl has been identified, call NG.core.openPassportLink
|
|
||||||
* to open the link continue the process. Leave as null to open the url automatically
|
|
||||||
* NOTE: Browser games must open links on click events or else it will be blocked by
|
|
||||||
* the popup blocker.
|
|
||||||
* @param onFail
|
|
||||||
* @param onCancel Called when the user denies the passport connection.
|
|
||||||
*/
|
|
||||||
public function requestLogin
|
|
||||||
( onSuccess:Void->Void = null
|
|
||||||
, onPending:Void->Void = null
|
|
||||||
, onFail :Error->Void = null
|
|
||||||
, onCancel :Void->Void = null
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
if (attemptingLogin) {
|
|
||||||
|
|
||||||
logError("cannot request another login until the previous attempt is complete");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loggedIn) {
|
|
||||||
|
|
||||||
logError("cannot log in, already logged in");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
attemptingLogin = true;
|
|
||||||
_loginCancelled = false;
|
|
||||||
_passportCallback = null;
|
|
||||||
|
|
||||||
var call = calls.app.startSession(true)
|
|
||||||
.addDataHandler(onSessionReceive.bind(_, onSuccess, onPending, onFail, onCancel));
|
|
||||||
|
|
||||||
if (onFail != null)
|
|
||||||
call.addErrorHandler(onFail);
|
|
||||||
|
|
||||||
call.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSessionReceive
|
|
||||||
( response :Response<SessionResult>
|
|
||||||
, onSuccess:Void->Void = null
|
|
||||||
, onPending:Void->Void = null
|
|
||||||
, onFail :Error->Void = null
|
|
||||||
, onCancel :Void->Void = null
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success) {
|
|
||||||
|
|
||||||
sessionId = null;
|
|
||||||
endLoginAndCall(null);
|
|
||||||
|
|
||||||
if (onFail != null)
|
|
||||||
onFail(!response.success ? response.error : response.result.error);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_session.parse(response.result.data.session);
|
|
||||||
sessionId = _session.id;
|
|
||||||
|
|
||||||
logVerbose('session started - status: ${_session.status}');
|
|
||||||
|
|
||||||
if (_session.status == SessionStatus.REQUEST_LOGIN) {
|
|
||||||
|
|
||||||
_passportCallback = checkSession.bind(null, onSuccess, onCancel);
|
|
||||||
if (onPending != null)
|
|
||||||
onPending();
|
|
||||||
else
|
|
||||||
openPassportUrl();
|
|
||||||
|
|
||||||
} else
|
|
||||||
checkSession(null, onSuccess, onCancel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this once the passport link is established and it will load the passport URL and
|
|
||||||
* start checking for session connect periodically
|
|
||||||
*/
|
|
||||||
public function openPassportUrl():Void {
|
|
||||||
|
|
||||||
if (passportUrl != null) {
|
|
||||||
|
|
||||||
logVerbose('loading passport: ${passportUrl}');
|
|
||||||
openPassportHelper(passportUrl);
|
|
||||||
onPassportUrlOpen();
|
|
||||||
|
|
||||||
} else
|
|
||||||
logError("Cannot open passport");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static function openPassportHelper(url:String):Void {
|
|
||||||
var window = "_blank";
|
|
||||||
|
|
||||||
#if flash
|
|
||||||
flash.Lib.getURL(new flash.net.URLRequest(url), window);
|
|
||||||
#elseif (js && html5)
|
|
||||||
js.Browser.window.open(url, window);
|
|
||||||
#elseif desktop
|
|
||||||
|
|
||||||
#if (sys && windows)
|
|
||||||
Sys.command("start", ["", url]);
|
|
||||||
#elseif mac
|
|
||||||
Sys.command("/usr/bin/open", [url]);
|
|
||||||
#elseif linux
|
|
||||||
Sys.command("/usr/bin/xdg-open", [path, "&"]);
|
|
||||||
#end
|
|
||||||
|
|
||||||
#elseif android
|
|
||||||
JNI.createStaticMethod
|
|
||||||
( "org/haxe/lime/GameActivity"
|
|
||||||
, "openURL"
|
|
||||||
, "(Ljava/lang/String;Ljava/lang/String;)V"
|
|
||||||
) (url, window);
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this once the passport link is established and it will start checking for session connect periodically
|
|
||||||
*/
|
|
||||||
public function onPassportUrlOpen():Void {
|
|
||||||
|
|
||||||
if (_passportCallback != null)
|
|
||||||
_passportCallback();
|
|
||||||
|
|
||||||
_passportCallback = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSession(response:Response<SessionResult>, onSucceess:Void->Void, onCancel:Void->Void):Void {
|
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success) {
|
|
||||||
|
|
||||||
log("login cancelled via passport");
|
|
||||||
|
|
||||||
endLoginAndCall(onCancel);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_session.parse(response.result.data.session);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_session.status == SessionStatus.USER_LOADED) {
|
|
||||||
|
|
||||||
loggedIn = true;
|
|
||||||
endLoginAndCall(onSucceess);
|
|
||||||
onLogin.dispatch();
|
|
||||||
|
|
||||||
} else if (_session.status == SessionStatus.REQUEST_LOGIN){
|
|
||||||
|
|
||||||
var call = calls.app.checkSession()
|
|
||||||
.addDataHandler(checkSession.bind(_, onSucceess, onCancel));
|
|
||||||
|
|
||||||
// Wait 3 seconds and try again
|
|
||||||
timer(3.0,
|
|
||||||
function():Void {
|
|
||||||
|
|
||||||
// Check if cancelLoginRequest was called
|
|
||||||
if (!_loginCancelled)
|
|
||||||
call.send();
|
|
||||||
else {
|
|
||||||
|
|
||||||
log("login cancelled via cancelLoginRequest");
|
|
||||||
endLoginAndCall(onCancel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
} else
|
|
||||||
// The user cancelled the passport
|
|
||||||
endLoginAndCall(onCancel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function cancelLoginRequest():Void {
|
|
||||||
|
|
||||||
if (attemptingLogin)
|
|
||||||
_loginCancelled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function endLoginAndCall(callback:Void->Void):Void {
|
|
||||||
|
|
||||||
attemptingLogin = false;
|
|
||||||
_loginCancelled = false;
|
|
||||||
|
|
||||||
if (callback != null)
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logOut(onComplete:Void->Void = null):Void {
|
|
||||||
|
|
||||||
var call = calls.app.endSession()
|
|
||||||
.addSuccessHandler(onLogOutSuccessful);
|
|
||||||
|
|
||||||
if (onComplete != null)
|
|
||||||
call.addSuccessHandler(onComplete);
|
|
||||||
|
|
||||||
call.addSuccessHandler(onLogOut.dispatch)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLogOutSuccessful():Void {
|
|
||||||
|
|
||||||
_session.expire();
|
|
||||||
sessionId = null;
|
|
||||||
loggedIn = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// MEDALS
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function requestMedals(onSuccess:Void->Void = null, onFail:Error->Void = null):Void {
|
|
||||||
|
|
||||||
var call = calls.medal.getList()
|
|
||||||
.addDataHandler(onMedalsReceived);
|
|
||||||
|
|
||||||
if (onSuccess != null)
|
|
||||||
call.addSuccessHandler(onSuccess);
|
|
||||||
|
|
||||||
if (onFail != null)
|
|
||||||
call.addErrorHandler(onFail);
|
|
||||||
|
|
||||||
call.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMedalsReceived(response:Response<MedalListResult>):Void {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var idList:Array<Int> = new Array<Int>();
|
|
||||||
|
|
||||||
if (medals == null) {
|
|
||||||
|
|
||||||
medals = new IntMap<Medal>();
|
|
||||||
|
|
||||||
for (medalData in response.result.data.medals) {
|
|
||||||
|
|
||||||
var medal = new Medal(this, medalData);
|
|
||||||
medals.set(medal.id, medal);
|
|
||||||
idList.push(medal.id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for (medalData in response.result.data.medals) {
|
|
||||||
|
|
||||||
medals.get(medalData.id).parse(medalData);
|
|
||||||
idList.push(medalData.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logVerbose('${response.result.data.medals.length} Medals received [${idList.join(", ")}]');
|
|
||||||
|
|
||||||
onMedalsLoaded.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// SCOREBOARDS
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function requestScoreBoards(onSuccess:Void->Void = null, onFail:Error->Void = null):Void {
|
|
||||||
|
|
||||||
if (scoreBoards != null) {
|
|
||||||
|
|
||||||
log("aborting scoreboard request, all scoreboards are loaded");
|
|
||||||
|
|
||||||
if (onSuccess != null)
|
|
||||||
onSuccess();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var call = calls.scoreBoard.getBoards()
|
|
||||||
.addDataHandler(onBoardsReceived);
|
|
||||||
|
|
||||||
if (onSuccess != null)
|
|
||||||
call.addSuccessHandler(onSuccess);
|
|
||||||
|
|
||||||
if (onFail != null)
|
|
||||||
call.addErrorHandler(onFail);
|
|
||||||
|
|
||||||
call.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onBoardsReceived(response:Response<ScoreBoardResult>):Void {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var idList:Array<Int> = new Array<Int>();
|
|
||||||
|
|
||||||
if (scoreBoards == null) {
|
|
||||||
|
|
||||||
scoreBoards = new IntMap<ScoreBoard>();
|
|
||||||
|
|
||||||
for (boardData in response.result.data.scoreboards) {
|
|
||||||
|
|
||||||
var board = new ScoreBoard(this, boardData);
|
|
||||||
scoreBoards.set(board.id, board);
|
|
||||||
idList.push(board.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logVerbose('${response.result.data.scoreboards.length} ScoreBoards received [${idList.join(", ")}]');
|
|
||||||
|
|
||||||
onScoreBoardsLoaded.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// HELPERS
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function timer(delay:Float, callback:Void->Void):Void {
|
|
||||||
|
|
||||||
var timer = new Timer(Std.int(delay * 1000));
|
|
||||||
timer.run = function func():Void {
|
|
||||||
|
|
||||||
timer.stop();
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static var urlParser:EReg = ~/^(?:http[s]?:\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?$/i;//TODO:trim
|
|
||||||
/** Used to get the current web host of your game. */
|
|
||||||
static public function getHost():String {
|
|
||||||
|
|
||||||
var url = NGLite.getUrl();
|
|
||||||
|
|
||||||
if (url == null || url == "")
|
|
||||||
return "<AppView>";
|
|
||||||
|
|
||||||
if (url.indexOf("file") == 0)
|
|
||||||
return "<LocalHost>";
|
|
||||||
|
|
||||||
if (urlParser.match(url))
|
|
||||||
return urlParser.matched(1);
|
|
||||||
|
|
||||||
return "<Unknown>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
package io.newgrounds;
|
|
||||||
|
|
||||||
import haxe.crypto.Base64;
|
|
||||||
import haxe.io.Bytes;
|
|
||||||
import haxe.PosInfos;
|
|
||||||
|
|
||||||
import io.newgrounds.Call.ICallable;
|
|
||||||
import io.newgrounds.components.ComponentList;
|
|
||||||
import io.newgrounds.crypto.EncryptionFormat;
|
|
||||||
import io.newgrounds.crypto.Cipher;
|
|
||||||
import io.newgrounds.crypto.Rc4;
|
|
||||||
import io.newgrounds.objects.Error;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.objects.events.Result.ResultBase;
|
|
||||||
import io.newgrounds.objects.events.Result.SessionResult;
|
|
||||||
import io.newgrounds.utils.Dispatcher;
|
|
||||||
|
|
||||||
#if !(html5 || flash || desktop || neko)
|
|
||||||
#error "Target not supported, use: Flash, JS/HTML5, cpp or maybe neko";
|
|
||||||
#end
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The barebones NG.io API. Allows API calls with code completion
|
|
||||||
* and retrieves server data via strongly typed Objects
|
|
||||||
*
|
|
||||||
* Contains many things ripped from MSGhero's repo
|
|
||||||
* - https://github.com/MSGhero/NG.hx
|
|
||||||
*
|
|
||||||
* @author GeoKureli
|
|
||||||
*/
|
|
||||||
class NGLite {
|
|
||||||
|
|
||||||
static public var core(default, null):NGLite;
|
|
||||||
static public var onCoreReady(default, null):Dispatcher = new Dispatcher();
|
|
||||||
|
|
||||||
/** Enables verbose logging */
|
|
||||||
public var verbose:Bool;
|
|
||||||
public var debug:Bool;
|
|
||||||
/** The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project. */
|
|
||||||
public var appId(default, null):String;
|
|
||||||
/** The name of the host the game is being played on */
|
|
||||||
public var host:String;
|
|
||||||
|
|
||||||
@:isVar
|
|
||||||
public var sessionId(default, set):String;
|
|
||||||
function set_sessionId(value:String):String {
|
|
||||||
|
|
||||||
return this.sessionId = value == "" ? null : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Components used to call the NG server directly */
|
|
||||||
public var calls(default, null):ComponentList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts an object to an encrypted string that can be decrypted by the server.
|
|
||||||
* Set your preffered encrypter here,
|
|
||||||
* or just call setDefaultEcryptionHandler with your app's encryption settings
|
|
||||||
**/
|
|
||||||
public var encryptionHandler:String->String;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iniitializes the API, call before utilizing any other component
|
|
||||||
* @param appId The unique ID of your app as found in the 'API Tools' tab of your Newgrounds.com project.
|
|
||||||
* @param sessionId A unique session id used to identify the active user.
|
|
||||||
**/
|
|
||||||
public function new(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void) {
|
|
||||||
|
|
||||||
this.appId = appId;
|
|
||||||
this.sessionId = sessionId;
|
|
||||||
|
|
||||||
calls = new ComponentList(this);
|
|
||||||
|
|
||||||
if (this.sessionId != null) {
|
|
||||||
|
|
||||||
calls.app.checkSession()
|
|
||||||
.addDataHandler(checkInitialSession.bind(onSessionFail))
|
|
||||||
.addErrorHandler(initialSessionFail.bind(onSessionFail))
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkInitialSession(onFail:Error->Void, response:Response<SessionResult>):Void {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success || response.result.data.session.expired) {
|
|
||||||
|
|
||||||
initialSessionFail(onFail, response.success ? response.result.error : response.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initialSessionFail(onFail:Error->Void, error:Error):Void {
|
|
||||||
|
|
||||||
sessionId = null;
|
|
||||||
|
|
||||||
if (onFail != null)
|
|
||||||
onFail(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates NG.core, the heart and soul of the API. This is not the only way to create an instance,
|
|
||||||
* nor is NG a forced singleton, but it's the only way to set the static NG.core.
|
|
||||||
**/
|
|
||||||
static public function create(appId = "test", sessionId:String = null, ?onSessionFail:Error->Void):Void {
|
|
||||||
|
|
||||||
core = new NGLite(appId, sessionId, onSessionFail);
|
|
||||||
|
|
||||||
onCoreReady.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates NG.core, and tries to create a session. This is not the only way to create an instance,
|
|
||||||
* nor is NG a forced singleton, but it's the only way to set the static NG.core.
|
|
||||||
**/
|
|
||||||
static public function createAndCheckSession
|
|
||||||
( appId = "test"
|
|
||||||
, backupSession:String = null
|
|
||||||
, ?onSessionFail:Error->Void
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
var session = getSessionId();
|
|
||||||
if (session == null)
|
|
||||||
session = backupSession;
|
|
||||||
|
|
||||||
create(appId, session, onSessionFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static public function getUrl():String {
|
|
||||||
|
|
||||||
#if html5
|
|
||||||
return js.Browser.document.location.href;
|
|
||||||
#elseif flash
|
|
||||||
return flash.Lib.current.stage.loaderInfo != null
|
|
||||||
? flash.Lib.current.stage.loaderInfo.url
|
|
||||||
: null;
|
|
||||||
#else
|
|
||||||
return null;
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function getSessionId():String {
|
|
||||||
|
|
||||||
#if html5
|
|
||||||
|
|
||||||
var url = getUrl();
|
|
||||||
|
|
||||||
// Check for URL params
|
|
||||||
var index = url.indexOf("?");
|
|
||||||
if (index != -1) {
|
|
||||||
|
|
||||||
// Check for session ID in params
|
|
||||||
for (param in url.substr(index + 1).split("&")) {
|
|
||||||
|
|
||||||
index = param.indexOf("=");
|
|
||||||
if (index != -1 && param.substr(0, index) == "ngio_session_id")
|
|
||||||
return param.substr(index + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#elseif flash
|
|
||||||
|
|
||||||
if (flash.Lib.current.stage.loaderInfo != null
|
|
||||||
&& Reflect.hasField(flash.Lib.current.stage.loaderInfo.parameters, "ngio_session_id"))
|
|
||||||
return Reflect.field(flash.Lib.current.stage.loaderInfo.parameters, "ngio_session_id");
|
|
||||||
|
|
||||||
#end
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// --- EXAMPLE LOADER PARAMS
|
|
||||||
//{ "1517703669" : ""
|
|
||||||
//, "ng_username" : "GeoKureli"
|
|
||||||
//, "NewgroundsAPI_SessionID" : "F1LusbG6P8Qf91w7zeUE37c1752563f366688ac6153996d12eeb111a2f60w2xn"
|
|
||||||
//, "NewgroundsAPI_PublisherID" : 1
|
|
||||||
//, "NewgroundsAPI_UserID" : 488329
|
|
||||||
//, "NewgroundsAPI_SandboxID" : "5a76520e4ae1e"
|
|
||||||
//, "ngio_session_id" : "0c6c4e02567a5116734ba1a0cd841dac28a42e79302290"
|
|
||||||
//, "NewgroundsAPI_UserName" : "GeoKureli"
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// CALLS
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
var _queuedCalls:Array<ICallable> = new Array<ICallable>();
|
|
||||||
var _pendingCalls:Array<ICallable> = new Array<ICallable>();
|
|
||||||
|
|
||||||
@:allow(io.newgrounds.Call)
|
|
||||||
@:generic
|
|
||||||
function queueCall<T:ResultBase>(call:Call<T>):Void {
|
|
||||||
|
|
||||||
logVerbose('queued - ${call.component}');
|
|
||||||
|
|
||||||
_queuedCalls.push(call);
|
|
||||||
checkQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@:allow(io.newgrounds.Call)
|
|
||||||
@:generic
|
|
||||||
function markCallPending<T:ResultBase>(call:Call<T>):Void {
|
|
||||||
|
|
||||||
_pendingCalls.push(call);
|
|
||||||
|
|
||||||
call.addDataHandler(function (_):Void { onCallComplete(call); });
|
|
||||||
call.addErrorHandler(function (_):Void { onCallComplete(call); });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCallComplete(call:ICallable):Void {
|
|
||||||
|
|
||||||
_pendingCalls.remove(call);
|
|
||||||
checkQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkQueue():Void {
|
|
||||||
|
|
||||||
if (_pendingCalls.length == 0 && _queuedCalls.length > 0)
|
|
||||||
_queuedCalls.shift().send();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// LOGGING / ERRORS
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Called internally, set this to your preferred logging method */
|
|
||||||
dynamic public function log(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow
|
|
||||||
|
|
||||||
haxe.Log.trace('[Newgrounds API] :: ${any}', pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** used internally, logs if verbose is true */
|
|
||||||
inline public function logVerbose(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
log(any, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used internally. Logs by default, set this to your preferred error handling method */
|
|
||||||
dynamic public function logError(any:Dynamic, ?pos:PosInfos):Void {//TODO: limit access via @:allow
|
|
||||||
|
|
||||||
log('Error: $any', pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** used internally, calls log error if the condition is false. EX: if (assert(data != null, "null data")) */
|
|
||||||
inline public function assert(condition:Bool, msg:Dynamic, ?pos:PosInfos):Bool {//TODO: limit access via @:allow
|
|
||||||
if (!condition)
|
|
||||||
logError(msg, pos);
|
|
||||||
|
|
||||||
return condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// ENCRYPTION
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Sets */
|
|
||||||
public function initEncryption
|
|
||||||
( key :String
|
|
||||||
, cipher:Cipher = Cipher.RC4
|
|
||||||
, format:EncryptionFormat = EncryptionFormat.BASE_64
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
if (cipher == Cipher.NONE)
|
|
||||||
encryptionHandler = null;
|
|
||||||
else if (cipher == Cipher.RC4)
|
|
||||||
encryptionHandler = encryptRc4.bind(key, format);
|
|
||||||
else
|
|
||||||
throw "aes not yet implemented";
|
|
||||||
}
|
|
||||||
|
|
||||||
function encryptRc4(key:String, format:EncryptionFormat, data:String):String {
|
|
||||||
|
|
||||||
if (format == EncryptionFormat.HEX)
|
|
||||||
throw "hex format not yet implemented";
|
|
||||||
|
|
||||||
var keyBytes:Bytes;
|
|
||||||
if (format == EncryptionFormat.BASE_64)
|
|
||||||
keyBytes = Base64.decode(key);
|
|
||||||
else
|
|
||||||
keyBytes = null;//TODO
|
|
||||||
|
|
||||||
var dataBytes = new Rc4(keyBytes).crypt(Bytes.ofString(data));
|
|
||||||
|
|
||||||
if (format == EncryptionFormat.BASE_64)
|
|
||||||
return Base64.encode(dataBytes);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.objects.events.Result.SessionResult;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class AppComponent extends Component {
|
|
||||||
|
|
||||||
public function new (core:NGLite) { super(core); }
|
|
||||||
|
|
||||||
public function startSession(force:Bool = false):Call<SessionResult> {
|
|
||||||
|
|
||||||
return new Call<SessionResult>(_core, "App.startSession")
|
|
||||||
.addComponentParameter("force", force, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkSession():Call<SessionResult> {
|
|
||||||
|
|
||||||
return new Call<SessionResult>(_core, "App.checkSession", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function endSession():Call<SessionResult> {
|
|
||||||
|
|
||||||
return new Call<SessionResult>(_core, "App.endSession", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCurrentVersion(version:String):Call<GetCurrentVersionResult> {
|
|
||||||
|
|
||||||
return new Call<GetCurrentVersionResult>(_core, "App.getCurrentVersion")
|
|
||||||
.addComponentParameter("version", version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHostLicense():Call<GetHostResult> {
|
|
||||||
|
|
||||||
return new Call<GetHostResult>(_core, "App.getHostLicense")
|
|
||||||
.addComponentParameter("host", _core.host);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function logView():Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "App.logView")
|
|
||||||
.addComponentParameter("host", _core.host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class Component {
|
|
||||||
|
|
||||||
var _core:NGLite;
|
|
||||||
|
|
||||||
public function new(core:NGLite) {
|
|
||||||
|
|
||||||
this._core = core;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
class ComponentList {
|
|
||||||
|
|
||||||
var _core:NGLite;
|
|
||||||
|
|
||||||
// --- COMPONENTS
|
|
||||||
public var medal : MedalComponent;
|
|
||||||
public var app : AppComponent;
|
|
||||||
public var event : EventComponent;
|
|
||||||
public var scoreBoard: ScoreBoardComponent;
|
|
||||||
public var loader : LoaderComponent;
|
|
||||||
public var gateway : GatewayComponent;
|
|
||||||
|
|
||||||
public function new(core:NGLite) {
|
|
||||||
|
|
||||||
_core = core;
|
|
||||||
|
|
||||||
medal = new MedalComponent (_core);
|
|
||||||
app = new AppComponent (_core);
|
|
||||||
event = new EventComponent (_core);
|
|
||||||
scoreBoard = new ScoreBoardComponent(_core);
|
|
||||||
loader = new LoaderComponent (_core);
|
|
||||||
gateway = new GatewayComponent (_core);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result.LogEventResult;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class EventComponent extends Component {
|
|
||||||
|
|
||||||
public function new (core:NGLite){ super(core); }
|
|
||||||
|
|
||||||
public function logEvent(eventName:String):Call<LogEventResult> {
|
|
||||||
|
|
||||||
return new Call<LogEventResult>(_core, "Event.logEvent")
|
|
||||||
.addComponentParameter("event_name", eventName)
|
|
||||||
.addComponentParameter("host", _core.host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class GatewayComponent extends Component {
|
|
||||||
|
|
||||||
public function new (core:NGLite){ super(core); }
|
|
||||||
|
|
||||||
public function getDatetime():Call<GetDateTimeResult> {
|
|
||||||
|
|
||||||
return new Call<GetDateTimeResult>(_core, "Gateway.getDatetime");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersion():Call<GetVersionResult> {
|
|
||||||
|
|
||||||
return new Call<GetVersionResult>(_core, "Gateway.getVersion");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ping():Call<PingResult> {
|
|
||||||
|
|
||||||
return new Call<PingResult>(_core, "Gateway.ping");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class LoaderComponent extends Component {
|
|
||||||
|
|
||||||
public function new (core:NGLite){ super(core); }
|
|
||||||
|
|
||||||
public function loadAuthorUrl(redirect:Bool = false):Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "Loader.loadAuthorUrl")
|
|
||||||
.addComponentParameter("host", _core.host)
|
|
||||||
.addComponentParameter("redirect", redirect, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadMoreGames(redirect:Bool = false):Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "Loader.loadMoreGames")
|
|
||||||
.addComponentParameter("host", _core.host)
|
|
||||||
.addComponentParameter("redirect", redirect, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadNewgrounds(redirect:Bool = false):Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "Loader.loadNewgrounds")
|
|
||||||
.addComponentParameter("host", _core.host)
|
|
||||||
.addComponentParameter("redirect", redirect, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadOfficialUrl(redirect:Bool = false):Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "Loader.loadOfficialUrl")
|
|
||||||
.addComponentParameter("host", _core.host)
|
|
||||||
.addComponentParameter("redirect", redirect, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadReferral(redirect:Bool = false):Call<ResultBase> {
|
|
||||||
|
|
||||||
return new Call<ResultBase>(_core, "Loader.loadReferral")
|
|
||||||
.addComponentParameter("host", _core.host)
|
|
||||||
.addComponentParameter("redirect", redirect, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.Call;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class MedalComponent extends Component {
|
|
||||||
|
|
||||||
public function new(core:NGLite):Void { super(core); }
|
|
||||||
|
|
||||||
public function unlock(id:Int):Call<MedalUnlockResult> {
|
|
||||||
|
|
||||||
return new Call<MedalUnlockResult>(_core, "Medal.unlock", true, true)
|
|
||||||
.addComponentParameter("id", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getList():Call<MedalListResult> {
|
|
||||||
|
|
||||||
return new Call<MedalListResult>(_core, "Medal.getList");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package io.newgrounds.components;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.User;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreBoardResult;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreResult;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
import io.newgrounds.objects.ScoreBoard;
|
|
||||||
|
|
||||||
import haxe.ds.IntMap;
|
|
||||||
|
|
||||||
class ScoreBoardComponent extends Component {
|
|
||||||
|
|
||||||
public var allById:IntMap<ScoreBoard>;
|
|
||||||
|
|
||||||
public function new (core:NGLite){ super(core); }
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// GET SCORES
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function getBoards():Call<ScoreBoardResult> {
|
|
||||||
|
|
||||||
return new Call<ScoreBoardResult>(_core, "ScoreBoard.getBoards");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*function onBoardsReceive(response:Response<ScoreBoardResult>):Void {
|
|
||||||
|
|
||||||
if (!response.result.success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
allById = new IntMap<ScoreBoard>();
|
|
||||||
|
|
||||||
for (boardData in response.result.scoreboards)
|
|
||||||
createBoard(boardData);
|
|
||||||
|
|
||||||
_core.log('${response.result.scoreboards.length} ScoreBoards loaded');
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// GET SCORES
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function getScores
|
|
||||||
( id :Int
|
|
||||||
, limit :Int = 10
|
|
||||||
, skip :Int = 0
|
|
||||||
, period:Period = Period.DAY
|
|
||||||
, social:Bool = false
|
|
||||||
, tag :String = null
|
|
||||||
, user :Dynamic = null
|
|
||||||
):Call<ScoreResult> {
|
|
||||||
|
|
||||||
if (user != null && !Std.is(user, String) && !Std.is(user, Int))
|
|
||||||
user = user.id;
|
|
||||||
|
|
||||||
return new Call<ScoreResult>(_core, "ScoreBoard.getScores")
|
|
||||||
.addComponentParameter("id" , id )
|
|
||||||
.addComponentParameter("limit" , limit , 10)
|
|
||||||
.addComponentParameter("skip" , skip , 0)
|
|
||||||
.addComponentParameter("period", period, Period.DAY)
|
|
||||||
.addComponentParameter("social", social, false)
|
|
||||||
.addComponentParameter("tag" , tag , null)
|
|
||||||
.addComponentParameter("user" , user , null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
// POST SCORE
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function postScore(id:Int, value:Int, tag:String = null):Call<PostScoreResult> {
|
|
||||||
|
|
||||||
return new Call<PostScoreResult>(_core, "ScoreBoard.postScore", true, true)
|
|
||||||
.addComponentParameter("id" , id)
|
|
||||||
.addComponentParameter("value", value)
|
|
||||||
.addComponentParameter("tag" , tag , null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*function onScorePosted(response:Response<ResultBase>):Void {
|
|
||||||
|
|
||||||
if (!response.result.success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
allById = new IntMap<ScoreBoard>();
|
|
||||||
|
|
||||||
//createBoard(data.data.scoreBoard).parseScores(data.data.scores);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
inline function createBoard(data:Dynamic):ScoreBoard {
|
|
||||||
|
|
||||||
var board = new ScoreBoard(_core, data);
|
|
||||||
_core.logVerbose('created $board');
|
|
||||||
|
|
||||||
allById.set(board.id, board);
|
|
||||||
|
|
||||||
return board;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@:enum
|
|
||||||
abstract Period(String) to String from String{
|
|
||||||
|
|
||||||
/** Indicates scores are from the current day. */
|
|
||||||
var DAY = "D";
|
|
||||||
/** Indicates scores are from the current week. */
|
|
||||||
var WEEK = "W";
|
|
||||||
/** Indicates scores are from the current month. */
|
|
||||||
var MONTH = "M";
|
|
||||||
/** Indicates scores are from the current year. */
|
|
||||||
var YEAR = "Y";
|
|
||||||
/** Indicates scores are from all-time. */
|
|
||||||
var ALL = "A";
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.newgrounds.crypto;
|
|
||||||
|
|
||||||
@:enum
|
|
||||||
abstract Cipher(String) to String{
|
|
||||||
var NONE = "none";
|
|
||||||
var AES_128 = "aes128";
|
|
||||||
var RC4 = "rc4";
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package io.newgrounds.crypto;
|
|
||||||
|
|
||||||
@:enum
|
|
||||||
abstract EncryptionFormat(String) to String {
|
|
||||||
var BASE_64 = "base64";
|
|
||||||
var HEX = "hex";
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package io.newgrounds.crypto;
|
|
||||||
|
|
||||||
import haxe.io.Bytes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The following was straight-up ganked from https://github.com/iskolbin/rc4hx
|
|
||||||
*
|
|
||||||
* You da real MVP iskolbin...
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 iskolbin
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
**/
|
|
||||||
class Rc4 {
|
|
||||||
var perm = Bytes.alloc( 256 );
|
|
||||||
var index1: Int = 0;
|
|
||||||
var index2: Int = 0;
|
|
||||||
|
|
||||||
public function new( key: Bytes ) {
|
|
||||||
for ( i in 0...256 ) {
|
|
||||||
perm.set( i, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
var j: Int = 0;
|
|
||||||
for ( i in 0...256 ) {
|
|
||||||
j = ( j + perm.get( i ) + key.get( i % key.length )) % 256;
|
|
||||||
swap( i, j );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline function swap( i: Int, j: Int ): Void {
|
|
||||||
var temp = perm.get( i );
|
|
||||||
perm.set( i, perm.get( j ));
|
|
||||||
perm.set( j, temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function crypt( input: Bytes ): Bytes {
|
|
||||||
var output = Bytes.alloc( input.length );
|
|
||||||
|
|
||||||
for ( i in 0...input.length ) {
|
|
||||||
index1 = ( index1 + 1 ) % 256;
|
|
||||||
index2 = ( index2 + perm.get( index1 )) % 256;
|
|
||||||
swap( index1, index2 );
|
|
||||||
var j = ( perm.get( index1 ) + perm.get( index2 )) % 256;
|
|
||||||
output.set( i, input.get( i ) ^ perm.get( j ));
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
class Error {
|
|
||||||
|
|
||||||
public var code(default, null):Int;
|
|
||||||
public var message(default, null):String;
|
|
||||||
|
|
||||||
public function new (message:String, code:Int = 0) {
|
|
||||||
|
|
||||||
this.message = message;
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toString():String {
|
|
||||||
|
|
||||||
if (code > 0)
|
|
||||||
return '#$code - $message';
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.objects.events.Result.MedalUnlockResult;
|
|
||||||
import io.newgrounds.utils.Dispatcher;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class Medal extends Object {
|
|
||||||
|
|
||||||
inline static public var EASY :Int = 1;
|
|
||||||
inline static public var MODERATE :Int = 2;
|
|
||||||
inline static public var CHALLENGING:Int = 3;
|
|
||||||
inline static public var DIFFICULT :Int = 4;
|
|
||||||
inline static public var BRUTAL :Int = 5;
|
|
||||||
|
|
||||||
static var difficultyNames:Array<String> =
|
|
||||||
[ "Easy"
|
|
||||||
, "Moderate"
|
|
||||||
, "Challenging"
|
|
||||||
, "Difficult"
|
|
||||||
, "Brutal"
|
|
||||||
];
|
|
||||||
// --- FROM SERVER
|
|
||||||
public var id (default, null):Int;
|
|
||||||
public var name (default, null):String;
|
|
||||||
public var description(default, null):String;
|
|
||||||
public var icon (default, null):String;
|
|
||||||
public var value (default, null):Int;
|
|
||||||
public var difficulty (default, null):Int;
|
|
||||||
public var secret (default, null):Bool;
|
|
||||||
public var unlocked (default, null):Bool;
|
|
||||||
// --- HELPERS
|
|
||||||
public var difficultyName(get, never):String;
|
|
||||||
|
|
||||||
public var onUnlock:Dispatcher;
|
|
||||||
|
|
||||||
public function new(core:NGLite, data:Dynamic = null):Void {
|
|
||||||
|
|
||||||
onUnlock = new Dispatcher();
|
|
||||||
|
|
||||||
super(core, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@:allow(io.newgrounds.NG)
|
|
||||||
override function parse(data:Dynamic):Void {
|
|
||||||
|
|
||||||
var wasLocked = !unlocked;
|
|
||||||
|
|
||||||
id = data.id;
|
|
||||||
name = data.name;
|
|
||||||
description = data.description;
|
|
||||||
icon = data.icon;
|
|
||||||
value = data.value;
|
|
||||||
difficulty = data.difficulty;
|
|
||||||
secret = data.secret == 1;
|
|
||||||
unlocked = data.unlocked;
|
|
||||||
|
|
||||||
super.parse(data);
|
|
||||||
|
|
||||||
if (wasLocked && unlocked)
|
|
||||||
onUnlock.dispatch();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendUnlock():Void {
|
|
||||||
|
|
||||||
if (_core.sessionId == null) {
|
|
||||||
// --- Unlock regardless, show medal popup to encourage NG signup
|
|
||||||
unlocked = true;
|
|
||||||
onUnlock.dispatch();
|
|
||||||
//TODO: save unlock in local save
|
|
||||||
}
|
|
||||||
|
|
||||||
_core.calls.medal.unlock(id)
|
|
||||||
.addDataHandler(onUnlockResponse)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUnlockResponse(response:Response<MedalUnlockResult>):Void {
|
|
||||||
|
|
||||||
if (response.success && response.result.success) {
|
|
||||||
|
|
||||||
parse(response.result.data.medal);
|
|
||||||
|
|
||||||
// --- Unlock response doesn't include unlock=true, so parse won't change it.
|
|
||||||
if (!unlocked) {
|
|
||||||
|
|
||||||
unlocked = true;
|
|
||||||
onUnlock.dispatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Locks the medal on the client and sends an unlock request, Server responds the same either way. */
|
|
||||||
public function sendDebugUnlock():Void {
|
|
||||||
|
|
||||||
if (NG.core.sessionId == null) {
|
|
||||||
|
|
||||||
onUnlock.dispatch();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
unlocked = false;
|
|
||||||
|
|
||||||
sendUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_difficultyName():String {
|
|
||||||
|
|
||||||
return difficultyNames[difficulty - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toString():String {
|
|
||||||
|
|
||||||
return 'Medal: $id@$name (${unlocked ? "unlocked" : "locked"}, $value pts, $difficultyName).';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
import io.newgrounds.utils.Dispatcher;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class Object {
|
|
||||||
|
|
||||||
var _core:NGLite;
|
|
||||||
|
|
||||||
public var onUpdate(default, null):Dispatcher;
|
|
||||||
|
|
||||||
public function new(core:NGLite, data:Dynamic = null) {
|
|
||||||
|
|
||||||
this._core = core;
|
|
||||||
|
|
||||||
onUpdate = new Dispatcher();
|
|
||||||
|
|
||||||
if (data != null)
|
|
||||||
parse(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@:allow(io.newgrounds.NGLite)
|
|
||||||
function parse(data:Dynamic):Void {
|
|
||||||
|
|
||||||
onUpdate.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function destroy():Void {
|
|
||||||
|
|
||||||
_core = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
/** We don't want to serialize scores since there's a bajillion of them. */
|
|
||||||
typedef Score = {
|
|
||||||
|
|
||||||
/** The value value in the format selected in your scoreboard settings. */
|
|
||||||
var formatted_value:String;
|
|
||||||
|
|
||||||
/** The tag attached to this value (if any). */
|
|
||||||
var tag:String;
|
|
||||||
|
|
||||||
/** The user who earned value. If this property is absent, the value belongs to the active user. */
|
|
||||||
var user:User;
|
|
||||||
|
|
||||||
/** The integer value of the value. */
|
|
||||||
var value:Int;
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
import io.newgrounds.components.ScoreBoardComponent.Period;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.objects.events.Result;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreResult;
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
class ScoreBoard extends Object {
|
|
||||||
|
|
||||||
public var scores(default, null):Array<Score>;
|
|
||||||
|
|
||||||
/** The numeric ID of the scoreboard.*/
|
|
||||||
public var id(default, null):Int;
|
|
||||||
|
|
||||||
/** The name of the scoreboard. */
|
|
||||||
public var name(default, null):String;
|
|
||||||
|
|
||||||
public function new(core:NGLite, data:Dynamic):Void {super(core, data); }
|
|
||||||
|
|
||||||
override function parse(data:Dynamic):Void {
|
|
||||||
|
|
||||||
id = data.id;
|
|
||||||
name = data.name;
|
|
||||||
|
|
||||||
super.parse(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches score data from the server, this removes all of the existing scores cached
|
|
||||||
*
|
|
||||||
* We don't unify the old and new scores because a user's rank or score may change between requests
|
|
||||||
*/
|
|
||||||
public function requestScores
|
|
||||||
( limit :Int = 10
|
|
||||||
, skip :Int = 0
|
|
||||||
, period:Period = Period.ALL
|
|
||||||
, social:Bool = false
|
|
||||||
, tag :String = null
|
|
||||||
, user :Dynamic = null
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
_core.calls.scoreBoard.getScores(id, limit, skip, period, social, tag, user)
|
|
||||||
.addDataHandler(onScoresReceived)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onScoresReceived(response:Response<ScoreResult>):Void {
|
|
||||||
|
|
||||||
if (!response.success || !response.result.success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scores = response.result.data.scores;
|
|
||||||
_core.logVerbose('received ${scores.length} scores');
|
|
||||||
|
|
||||||
onUpdate.dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function postScore(value :Int, tag:String = null):Void {
|
|
||||||
|
|
||||||
_core.calls.scoreBoard.postScore(id, value, tag)
|
|
||||||
.addDataHandler(onScorePosted)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onScorePosted(response:Response<PostScoreResult>):Void {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toString():String {
|
|
||||||
|
|
||||||
return 'ScoreBoard: $id@$name';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
class Session extends Object {
|
|
||||||
|
|
||||||
/** If true, the session_id is expired. Use App.startSession to get a new one.*/
|
|
||||||
public var expired(default, null):Bool;
|
|
||||||
|
|
||||||
/** A unique session identifier */
|
|
||||||
public var id(default, null):String;
|
|
||||||
|
|
||||||
/** If the session has no associated user but is not expired, this property will provide a URL that can be used to sign the user in. */
|
|
||||||
public var passportUrl(default, null):String;
|
|
||||||
|
|
||||||
/** If true, the user would like you to remember their session id. */
|
|
||||||
public var remember(default, null):Bool;
|
|
||||||
|
|
||||||
/** If the user has not signed in, or granted access to your app, this will be null */
|
|
||||||
public var user(default, null):User;
|
|
||||||
|
|
||||||
//TODO:desciption
|
|
||||||
public var status(get, never):SessionStatus;
|
|
||||||
|
|
||||||
public function new(core:NGLite, data:Dynamic = null) { super(core, data); }
|
|
||||||
|
|
||||||
override public function parse(data:Dynamic):Void {
|
|
||||||
|
|
||||||
id = data.id;
|
|
||||||
expired = data.expired;
|
|
||||||
passportUrl = data.passport_url;
|
|
||||||
remember = data.remember;
|
|
||||||
|
|
||||||
// --- KEEP THE SAME INSTANCE
|
|
||||||
if (user == null)
|
|
||||||
user = data.user;
|
|
||||||
// TODO?: update original user instance with new data. (probly not)
|
|
||||||
|
|
||||||
super.parse(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_status():SessionStatus {
|
|
||||||
|
|
||||||
if (expired || id == null || id == "")
|
|
||||||
return SessionStatus.SESSION_EXPIRED;
|
|
||||||
|
|
||||||
if (user != null && user.name != null && user.name != "")
|
|
||||||
return SessionStatus.USER_LOADED;
|
|
||||||
|
|
||||||
return SessionStatus.REQUEST_LOGIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function expire():Void {
|
|
||||||
|
|
||||||
expired = true;
|
|
||||||
id = null;
|
|
||||||
user = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@:enum
|
|
||||||
abstract SessionStatus(String) {
|
|
||||||
|
|
||||||
var SESSION_EXPIRED = "session-expired";
|
|
||||||
var REQUEST_LOGIN = "request-login";
|
|
||||||
var USER_LOADED = "user-loaded";
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
typedef User = {
|
|
||||||
|
|
||||||
/** The user's icon images. */
|
|
||||||
var icons:UserIcons;
|
|
||||||
|
|
||||||
/** The user's numeric ID. */
|
|
||||||
var id:Int;
|
|
||||||
|
|
||||||
/** The user's textual name. */
|
|
||||||
var name:String;
|
|
||||||
|
|
||||||
/** Returns true if the user has a Newgrounds Supporter upgrade. */
|
|
||||||
var supporter:Bool;
|
|
||||||
|
|
||||||
/** The user's NG profile url. */
|
|
||||||
var url:String;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package io.newgrounds.objects;
|
|
||||||
|
|
||||||
typedef UserIcons = {
|
|
||||||
|
|
||||||
/**The URL of the user's large icon. */
|
|
||||||
var large:String;
|
|
||||||
|
|
||||||
/** The URL of the user's medium icon. */
|
|
||||||
var medium:String;
|
|
||||||
|
|
||||||
/** The URL of the user's small icon. */
|
|
||||||
var small:String;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package io.newgrounds.objects.events;
|
|
||||||
|
|
||||||
import io.newgrounds.objects.events.Result.ResultBase;
|
|
||||||
import haxe.Json;
|
|
||||||
import io.newgrounds.objects.Error;
|
|
||||||
|
|
||||||
typedef DebugResponse = {
|
|
||||||
|
|
||||||
var exec_time:Int;
|
|
||||||
var input:Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Response<T:ResultBase> {
|
|
||||||
|
|
||||||
public var success(default, null):Bool;
|
|
||||||
public var error(default, null):Error;
|
|
||||||
public var debug(default, null):DebugResponse;
|
|
||||||
public var result(default, null):Result<T>;
|
|
||||||
|
|
||||||
public function new (core:NGLite, reply:String) {
|
|
||||||
|
|
||||||
var data:Dynamic;
|
|
||||||
|
|
||||||
try {
|
|
||||||
data = Json.parse(reply);
|
|
||||||
|
|
||||||
} catch (e:Dynamic) {
|
|
||||||
|
|
||||||
data = Json.parse('{"success":false,"error":{"message":"${Std.string(reply)}","code":0}}');
|
|
||||||
}
|
|
||||||
|
|
||||||
success = data.success;
|
|
||||||
debug = data.debug;
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
error = new Error(data.error.message, data.error.code);
|
|
||||||
core.logError('Call unseccessful: $error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = new Result<T>(core, data.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package io.newgrounds.objects.events;
|
|
||||||
|
|
||||||
class Result<T:ResultBase> {
|
|
||||||
|
|
||||||
public var echo(default, null):String;
|
|
||||||
public var component(default, null):String;
|
|
||||||
|
|
||||||
public var data(default, null):T;
|
|
||||||
public var success(default, null):Bool;
|
|
||||||
public var debug(default, null):Bool;
|
|
||||||
public var error(default, null):Error;
|
|
||||||
|
|
||||||
public function new(core:NGLite, data:Dynamic) {
|
|
||||||
|
|
||||||
echo = data.echo;
|
|
||||||
component = data.component;
|
|
||||||
|
|
||||||
data = data.data;
|
|
||||||
success = data.success;
|
|
||||||
debug = data.debug;
|
|
||||||
|
|
||||||
if(!data.success) {
|
|
||||||
|
|
||||||
error = new Error(data.error.message, data.error.code);
|
|
||||||
core.logError('$component fail: $error');
|
|
||||||
|
|
||||||
} else
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef ResultBase = { };
|
|
||||||
|
|
||||||
typedef SessionResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var session:Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GetHostResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var host_approved:Bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GetCurrentVersionResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var current_version:String;
|
|
||||||
var client_deprecated:Bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef LogEventResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var event_name:String;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GetDateTimeResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var datetime:String;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef GetVersionResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var version:String;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef PingResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var pong:String;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef MedalListResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var medals:Array<Dynamic>;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef MedalUnlockResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var medal_score:String;
|
|
||||||
var medal:Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef ScoreBoardResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var scoreboards:Array<Dynamic>;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef ScoreResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var scores:Array<Score>;
|
|
||||||
var scoreboard:Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef PostScoreResult = {
|
|
||||||
> ResultBase,
|
|
||||||
|
|
||||||
var tag:String;
|
|
||||||
var scoreboard:Dynamic;
|
|
||||||
var score:Score;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package io.newgrounds.swf;
|
|
||||||
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
|
|
||||||
class LoadingBar extends MovieClip {
|
|
||||||
|
|
||||||
public var bar(default, null):MovieClip;
|
|
||||||
|
|
||||||
public function new() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
setProgress(0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param value The ratio of bytes loaded to bytes total
|
|
||||||
*/
|
|
||||||
public function setProgress(value:Float):Void {
|
|
||||||
|
|
||||||
bar.gotoAndStop(1 + Std.int(value * (bar.totalFrames - 1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
package io.newgrounds.swf;
|
|
||||||
|
|
||||||
import io.newgrounds.swf.common.BaseAsset;
|
|
||||||
import io.newgrounds.objects.Medal;
|
|
||||||
|
|
||||||
import openfl.text.TextFieldAutoSize;
|
|
||||||
import openfl.text.TextField;
|
|
||||||
import openfl.display.DisplayObject;
|
|
||||||
import openfl.display.Loader;
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
import openfl.net.URLRequest;
|
|
||||||
import openfl.events.Event;
|
|
||||||
|
|
||||||
class MedalPopup extends BaseAsset {
|
|
||||||
|
|
||||||
static inline var FRAME_HIDDEN:String = "hidden";
|
|
||||||
static inline var FRAME_MEDAL_UNLOCKED:String = "medalUnlocked";
|
|
||||||
static inline var FRAME_INTRO_COMPLETE:String = "introComplete";
|
|
||||||
static inline var FRAME_UNLOCK_COMPLETE:String = "unlockComplete";
|
|
||||||
static inline var MIN_TEXT_SIZE:Int = 12;
|
|
||||||
|
|
||||||
public var medalIcon(default, null):MovieClip;
|
|
||||||
public var medalName(default, null):MovieClip;
|
|
||||||
public var medalPoints(default, null):MovieClip;
|
|
||||||
|
|
||||||
public var alwaysOnTop:Bool;
|
|
||||||
#if !ng_lite
|
|
||||||
public var requiresSession:Bool;
|
|
||||||
#end
|
|
||||||
|
|
||||||
var _animQueue = new Array<Void->Void>();
|
|
||||||
var _scrollSpeed:Float;
|
|
||||||
|
|
||||||
public function new() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
mouseEnabled = false;
|
|
||||||
mouseChildren = false;
|
|
||||||
|
|
||||||
hide();
|
|
||||||
addFrameScript(totalFrames - 1, onUnlockAnimComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide():Void {
|
|
||||||
|
|
||||||
visible = false;
|
|
||||||
gotoAndStop(FRAME_HIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !ng_lite
|
|
||||||
override function onReady():Void {
|
|
||||||
super.onReady();
|
|
||||||
|
|
||||||
if (NG.core.medals != null)
|
|
||||||
onMedalsLoaded();
|
|
||||||
else
|
|
||||||
NG.core.onLogin.addOnce(NG.core.requestMedals.bind(onMedalsLoaded));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMedalsLoaded():Void {
|
|
||||||
|
|
||||||
for (medal in NG.core.medals)
|
|
||||||
medal.onUnlock.add(onMedalOnlock.bind(medal));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMedalOnlock(medal:Medal):Void {
|
|
||||||
|
|
||||||
if (requiresSession && !NG.core.loggedIn)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var loader = new Loader();
|
|
||||||
loader.load(new URLRequest(medal.icon));
|
|
||||||
|
|
||||||
playAnim(loader, medal.name, medal.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#end
|
|
||||||
|
|
||||||
public function playAnim(icon:DisplayObject, name:String, value:Int):Void {
|
|
||||||
|
|
||||||
if (currentLabel == FRAME_HIDDEN)
|
|
||||||
playNextAnim(icon, name, value);
|
|
||||||
else
|
|
||||||
_animQueue.push(playNextAnim.bind(icon, name, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
function playNextAnim(icon:DisplayObject, name:String, value:Int):Void {
|
|
||||||
|
|
||||||
visible = true;
|
|
||||||
gotoAndPlay(FRAME_MEDAL_UNLOCKED);
|
|
||||||
|
|
||||||
if (alwaysOnTop && parent != null) {
|
|
||||||
|
|
||||||
parent.setChildIndex(this, parent.numChildren - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(medalIcon.numChildren > 0)
|
|
||||||
medalIcon.removeChildAt(0);
|
|
||||||
|
|
||||||
cast(medalPoints.getChildByName("field"), TextField).text = Std.string(value);
|
|
||||||
|
|
||||||
var field:TextField = cast medalName.getChildByName("field");
|
|
||||||
field.autoSize = TextFieldAutoSize.LEFT;
|
|
||||||
field.x = 0;
|
|
||||||
field.text = "";
|
|
||||||
var oldWidth = medalName.width;
|
|
||||||
field.text = name;
|
|
||||||
|
|
||||||
_scrollSpeed = 0;
|
|
||||||
if (field.width > oldWidth + 4) {
|
|
||||||
|
|
||||||
field.x = oldWidth + 4;
|
|
||||||
initScroll(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
medalIcon.addChild(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initScroll(field:TextField):Void {
|
|
||||||
//TODO: Find out why scrollrect didn't work
|
|
||||||
|
|
||||||
var animDuration = 0;
|
|
||||||
|
|
||||||
for (frame in currentLabels){
|
|
||||||
|
|
||||||
if (frame.name == FRAME_INTRO_COMPLETE )
|
|
||||||
animDuration -= frame.frame;
|
|
||||||
else if (frame.name == FRAME_UNLOCK_COMPLETE)
|
|
||||||
animDuration += frame.frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
_scrollSpeed = (field.width + field.x + 4) / animDuration;
|
|
||||||
field.addEventListener(Event.ENTER_FRAME, updateScroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateScroll(e:Event):Void{
|
|
||||||
|
|
||||||
if (currentLabel == FRAME_INTRO_COMPLETE)
|
|
||||||
cast (e.currentTarget, TextField).x -= _scrollSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUnlockAnimComplete():Void {
|
|
||||||
|
|
||||||
cast (medalName.getChildByName("field"), TextField).removeEventListener(Event.ENTER_FRAME, updateScroll);
|
|
||||||
|
|
||||||
if (_animQueue.length == 0)
|
|
||||||
hide();
|
|
||||||
else
|
|
||||||
(_animQueue.shift())();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
package io.newgrounds.swf;
|
|
||||||
|
|
||||||
import openfl.events.Event;
|
|
||||||
import io.newgrounds.swf.common.DropDown;
|
|
||||||
import io.newgrounds.objects.Score;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreBoardResult;
|
|
||||||
import io.newgrounds.objects.events.Result.ScoreResult;
|
|
||||||
import io.newgrounds.objects.events.Response;
|
|
||||||
import io.newgrounds.swf.common.BaseAsset;
|
|
||||||
import io.newgrounds.swf.common.Button;
|
|
||||||
import io.newgrounds.components.ScoreBoardComponent.Period;
|
|
||||||
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
import openfl.text.TextField;
|
|
||||||
|
|
||||||
class ScoreBrowser extends BaseAsset {
|
|
||||||
|
|
||||||
public var prevButton (default, null):MovieClip;
|
|
||||||
public var nextButton (default, null):MovieClip;
|
|
||||||
public var reloadButton (default, null):MovieClip;
|
|
||||||
public var listBox (default, null):MovieClip;
|
|
||||||
public var loadingIcon (default, null):MovieClip;
|
|
||||||
public var errorIcon (default, null):MovieClip;
|
|
||||||
public var scoreContainer(default, null):MovieClip;
|
|
||||||
public var titleField (default, null):TextField;
|
|
||||||
public var pageField (default, null):TextField;
|
|
||||||
|
|
||||||
public var period(get, set):Period;
|
|
||||||
function get_period():Period { return _periodDropDown.value; }
|
|
||||||
function set_period(value:Period):Period { return _periodDropDown.value = value; }
|
|
||||||
|
|
||||||
public var title(get, set):String;
|
|
||||||
function get_title():String { return titleField.text; }
|
|
||||||
function set_title(value:String):String { return titleField.text = value; }
|
|
||||||
|
|
||||||
public var tag(default, set):String;
|
|
||||||
function set_tag(value:String):String {
|
|
||||||
|
|
||||||
if (this.tag != value) {
|
|
||||||
|
|
||||||
this.tag = value;
|
|
||||||
delayReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public var social(default, set):Bool;
|
|
||||||
function set_social(value:Bool):Bool {
|
|
||||||
|
|
||||||
if (this.social != value) {
|
|
||||||
|
|
||||||
this.social = value;
|
|
||||||
delayReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public var boardId(default, set):Int;
|
|
||||||
function set_boardId(value:Int):Int {
|
|
||||||
|
|
||||||
_boardIDSet = true;
|
|
||||||
|
|
||||||
if (this.boardId != value) {
|
|
||||||
|
|
||||||
this.boardId = value;
|
|
||||||
delayReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public var page(default, set):Int;
|
|
||||||
function set_page(value:Int):Int {
|
|
||||||
|
|
||||||
if (this.page != value) {
|
|
||||||
|
|
||||||
this.page = value;
|
|
||||||
delayReload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var _scores:Array<MovieClip>;
|
|
||||||
var _limit:Int = 0;
|
|
||||||
var _periodDropDown:DropDown;
|
|
||||||
var _boardIDSet:Bool;
|
|
||||||
|
|
||||||
public function new() { super(); }
|
|
||||||
|
|
||||||
override function setDefaults():Void {
|
|
||||||
super.setDefaults();
|
|
||||||
|
|
||||||
boardId = -1;
|
|
||||||
_boardIDSet = false;
|
|
||||||
|
|
||||||
scoreContainer.visible = false;
|
|
||||||
loadingIcon.visible = false;
|
|
||||||
reloadButton.visible = false;
|
|
||||||
errorIcon.visible = false;
|
|
||||||
errorIcon.addFrameScript(errorIcon.totalFrames - 1, errorIcon.stop);
|
|
||||||
|
|
||||||
//TODO: prevent memory leaks?
|
|
||||||
new Button(prevButton, onPrevClick);
|
|
||||||
new Button(nextButton, onNextClick);
|
|
||||||
new Button(reloadButton, reload);
|
|
||||||
_periodDropDown = new DropDown(listBox, delayReload);
|
|
||||||
_periodDropDown.addItem("Current day" , Period.DAY );
|
|
||||||
_periodDropDown.addItem("Current week" , Period.WEEK );
|
|
||||||
_periodDropDown.addItem("Current month", Period.MONTH);
|
|
||||||
_periodDropDown.addItem("Current year" , Period.YEAR );
|
|
||||||
_periodDropDown.addItem("All time" , Period.ALL );
|
|
||||||
_periodDropDown.value = Period.ALL;
|
|
||||||
|
|
||||||
_scores = new Array<MovieClip>();
|
|
||||||
while(true) {
|
|
||||||
|
|
||||||
var score:MovieClip = cast scoreContainer.getChildByName('score${_scores.length}');
|
|
||||||
if (score == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
new Button(score);
|
|
||||||
_scores.push(score);
|
|
||||||
}
|
|
||||||
|
|
||||||
_limit = _scores.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
override function onReady():Void {
|
|
||||||
super.onReady();
|
|
||||||
|
|
||||||
if (boardId == -1 && !_boardIDSet) {
|
|
||||||
|
|
||||||
#if ng_lite
|
|
||||||
NG.core.calls.scoreBoard.getBoards()
|
|
||||||
.addDataHandler(onBoardsRecieved)
|
|
||||||
.queue();
|
|
||||||
#else
|
|
||||||
if (NG.core.scoreBoards != null)
|
|
||||||
onBoardsLoaded();
|
|
||||||
else
|
|
||||||
NG.core.requestScoreBoards(onBoardsLoaded);
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ng_lite
|
|
||||||
function onBoardsRecieved(response:Response<ScoreBoardResult>):Void {
|
|
||||||
|
|
||||||
if (response.success && response.result.success) {
|
|
||||||
|
|
||||||
for (board in response.result.data.scoreboards) {
|
|
||||||
|
|
||||||
NG.core.log('No boardId specified defaulting to ${board.name}');
|
|
||||||
boardId = board.id;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
function onBoardsLoaded():Void {
|
|
||||||
|
|
||||||
for (board in NG.core.scoreBoards) {
|
|
||||||
|
|
||||||
NG.core.log('No boardId specified defaulting to ${board.name}');
|
|
||||||
boardId = board.id;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
|
|
||||||
/** Used internally to avoid multiple server requests from various property changes in a small time-frame. **/
|
|
||||||
function delayReload():Void {
|
|
||||||
|
|
||||||
addEventListener(Event.EXIT_FRAME, onDelayComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDelayComplete(e:Event):Void { reload(); }
|
|
||||||
|
|
||||||
public function reload():Void {
|
|
||||||
removeEventListener(Event.EXIT_FRAME, onDelayComplete);
|
|
||||||
|
|
||||||
errorIcon.visible = false;
|
|
||||||
scoreContainer.visible = false;
|
|
||||||
pageField.text = 'page ${page + 1}';
|
|
||||||
|
|
||||||
if (_coreReady && boardId != -1 && _limit > 0 && period != null) {
|
|
||||||
|
|
||||||
loadingIcon.visible = true;
|
|
||||||
|
|
||||||
NG.core.calls.scoreBoard.getScores(boardId, _limit, _limit * page, period, social, tag)
|
|
||||||
.addDataHandler(onScoresReceive)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onScoresReceive(response:Response<ScoreResult>):Void {
|
|
||||||
|
|
||||||
loadingIcon.visible = false;
|
|
||||||
|
|
||||||
if (response.success && response.result.success) {
|
|
||||||
|
|
||||||
scoreContainer.visible = true;
|
|
||||||
|
|
||||||
var i = _limit;
|
|
||||||
while(i > 0) {
|
|
||||||
i--;
|
|
||||||
|
|
||||||
if (i < response.result.data.scores.length)
|
|
||||||
drawScore(i, response.result.data.scores[i], _scores[i]);
|
|
||||||
else
|
|
||||||
drawScore(i, null, _scores[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
errorIcon.visible = true;
|
|
||||||
errorIcon.gotoAndPlay(1);
|
|
||||||
reloadButton.visible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline function drawScore(rank:Int, score:Score, asset:MovieClip):Void {
|
|
||||||
|
|
||||||
if (score == null)
|
|
||||||
asset.visible = false;
|
|
||||||
else {
|
|
||||||
|
|
||||||
asset.visible = true;
|
|
||||||
cast (asset.getChildByName("nameField" ), TextField).text = score.user.name;
|
|
||||||
cast (asset.getChildByName("scoreField"), TextField).text = score.formatted_value;
|
|
||||||
cast (asset.getChildByName("rankField" ), TextField).text = Std.string(rank + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPrevClick():Void {
|
|
||||||
|
|
||||||
if (page > 0)
|
|
||||||
page--;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onNextClick():Void {
|
|
||||||
|
|
||||||
page++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package io.newgrounds.swf.common;
|
|
||||||
|
|
||||||
import openfl.events.Event;
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
|
|
||||||
class BaseAsset extends MovieClip {
|
|
||||||
|
|
||||||
var _coreReady:Bool = false;
|
|
||||||
|
|
||||||
public function new() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
setDefaults();
|
|
||||||
|
|
||||||
if (stage != null)
|
|
||||||
onAdded(null);
|
|
||||||
else
|
|
||||||
addEventListener(Event.ADDED_TO_STAGE, onAdded);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDefaults():Void { }
|
|
||||||
|
|
||||||
function onAdded(e:Event):Void {
|
|
||||||
|
|
||||||
if (NG.core != null)
|
|
||||||
onReady();
|
|
||||||
else
|
|
||||||
NG.onCoreReady.add(onReady);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onReady():Void {
|
|
||||||
|
|
||||||
_coreReady = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
package io.newgrounds.swf.common;
|
|
||||||
|
|
||||||
import openfl.display.Stage;
|
|
||||||
import openfl.events.Event;
|
|
||||||
import openfl.events.MouseEvent;
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
|
|
||||||
class Button {
|
|
||||||
|
|
||||||
var _enabled:Bool;
|
|
||||||
public var enabled(get, set):Bool;
|
|
||||||
function get_enabled():Bool { return _enabled; }
|
|
||||||
function set_enabled(value:Bool):Bool {
|
|
||||||
|
|
||||||
if (value != _enabled) {
|
|
||||||
|
|
||||||
_enabled = value;
|
|
||||||
updateEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public var onClick:Void->Void;
|
|
||||||
public var onOver:Void->Void;
|
|
||||||
public var onOut:Void->Void;
|
|
||||||
|
|
||||||
var _target:MovieClip;
|
|
||||||
var _down:Bool;
|
|
||||||
var _over:Bool;
|
|
||||||
var _foundLabels:Array<String>;
|
|
||||||
|
|
||||||
public function new(target:MovieClip, onClick:Void->Void = null, onOver:Void->Void = null, onOut:Void->Void = null) {
|
|
||||||
|
|
||||||
_target = target;
|
|
||||||
this.onClick = onClick;
|
|
||||||
this.onOver = onOver;
|
|
||||||
this.onOut = onOut;
|
|
||||||
|
|
||||||
_foundLabels = new Array<String>();
|
|
||||||
for (label in _target.currentLabels)
|
|
||||||
_foundLabels.push(label.name);
|
|
||||||
|
|
||||||
_target.stop();
|
|
||||||
_target.addEventListener(Event.ADDED_TO_STAGE, onAdded);
|
|
||||||
if (target.stage != null)
|
|
||||||
onAdded(null);
|
|
||||||
|
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAdded(e:Event):Void {
|
|
||||||
|
|
||||||
var stage = _target.stage;
|
|
||||||
stage.addEventListener(MouseEvent.MOUSE_UP, mouseHandler);
|
|
||||||
_target.addEventListener(MouseEvent.MOUSE_OVER, mouseHandler);
|
|
||||||
_target.addEventListener(MouseEvent.MOUSE_OUT, mouseHandler);
|
|
||||||
_target.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
|
|
||||||
_target.addEventListener(MouseEvent.CLICK, mouseHandler);
|
|
||||||
|
|
||||||
function selfRemoveEvent(e:Event):Void {
|
|
||||||
|
|
||||||
_target.removeEventListener(Event.REMOVED_FROM_STAGE, selfRemoveEvent);
|
|
||||||
onRemove(e, stage);
|
|
||||||
}
|
|
||||||
_target.addEventListener(Event.REMOVED_FROM_STAGE, selfRemoveEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRemove(e:Event, stage:Stage):Void {
|
|
||||||
|
|
||||||
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseHandler);
|
|
||||||
_target.removeEventListener(MouseEvent.MOUSE_OVER, mouseHandler);
|
|
||||||
_target.removeEventListener(MouseEvent.MOUSE_OUT, mouseHandler);
|
|
||||||
_target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
|
|
||||||
_target.removeEventListener(MouseEvent.CLICK, mouseHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseHandler(event:MouseEvent):Void {
|
|
||||||
|
|
||||||
switch(event.type) {
|
|
||||||
|
|
||||||
case MouseEvent.MOUSE_OVER:
|
|
||||||
|
|
||||||
_over = true;
|
|
||||||
|
|
||||||
if (onOver != null)
|
|
||||||
onOver();
|
|
||||||
|
|
||||||
case MouseEvent.MOUSE_OUT:
|
|
||||||
|
|
||||||
_over = false;
|
|
||||||
|
|
||||||
if (onOut != null)
|
|
||||||
onOut();
|
|
||||||
|
|
||||||
case MouseEvent.MOUSE_DOWN:
|
|
||||||
|
|
||||||
_down = true;
|
|
||||||
|
|
||||||
case MouseEvent.MOUSE_UP:
|
|
||||||
|
|
||||||
_down = false;
|
|
||||||
|
|
||||||
case MouseEvent.CLICK:
|
|
||||||
|
|
||||||
if (enabled && onClick != null)
|
|
||||||
onClick();
|
|
||||||
}
|
|
||||||
updateState();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateEnabled():Void {
|
|
||||||
|
|
||||||
updateState();
|
|
||||||
|
|
||||||
_target.useHandCursor = enabled;
|
|
||||||
_target.buttonMode = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateState():Void {
|
|
||||||
|
|
||||||
var state = determineState();
|
|
||||||
|
|
||||||
if (_target.currentLabel != state && _foundLabels.indexOf(state) != -1)
|
|
||||||
_target.gotoAndStop(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
function determineState():String {
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
|
|
||||||
if (_over)
|
|
||||||
return _down ? "down" : "over";
|
|
||||||
|
|
||||||
return "up";
|
|
||||||
|
|
||||||
}
|
|
||||||
return "disabled";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy():Void {
|
|
||||||
|
|
||||||
_target.removeEventListener(Event.ADDED_TO_STAGE, onAdded);
|
|
||||||
|
|
||||||
_target = null;
|
|
||||||
onClick = null;
|
|
||||||
onOver = null;
|
|
||||||
onOut = null;
|
|
||||||
_foundLabels = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package io.newgrounds.swf.common;
|
|
||||||
|
|
||||||
|
|
||||||
import haxe.ds.StringMap;
|
|
||||||
|
|
||||||
import openfl.display.MovieClip;
|
|
||||||
import openfl.display.Sprite;
|
|
||||||
import openfl.text.TextField;
|
|
||||||
|
|
||||||
class DropDown {
|
|
||||||
|
|
||||||
public var value(default, set):String;
|
|
||||||
function set_value(v:String):String {
|
|
||||||
|
|
||||||
if (this.value == v)
|
|
||||||
return v;
|
|
||||||
|
|
||||||
this.value = v;
|
|
||||||
_selectedLabel.text = _values.get(v);
|
|
||||||
|
|
||||||
if (_onChange != null)
|
|
||||||
_onChange();
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
var _choiceContainer:Sprite;
|
|
||||||
var _selectedLabel:TextField;
|
|
||||||
var _onChange:Void->Void;
|
|
||||||
var _values:StringMap<String>;
|
|
||||||
var _unusedChoices:Array<MovieClip>;
|
|
||||||
|
|
||||||
public function new(target:MovieClip, label:String = "", onChange:Void->Void = null) {
|
|
||||||
|
|
||||||
_onChange = onChange;
|
|
||||||
|
|
||||||
_selectedLabel = cast cast(target.getChildByName("currentItem"), MovieClip).getChildByName("label");
|
|
||||||
_selectedLabel.text = label;
|
|
||||||
|
|
||||||
_values = new StringMap<String>();
|
|
||||||
|
|
||||||
new Button(cast target.getChildByName("button"), onClickExpand);
|
|
||||||
new Button(cast target.getChildByName("currentItem"), onClickExpand);
|
|
||||||
_choiceContainer = new Sprite();
|
|
||||||
_choiceContainer.visible = false;
|
|
||||||
target.addChild(_choiceContainer);
|
|
||||||
|
|
||||||
_unusedChoices = new Array<MovieClip>();
|
|
||||||
while(true) {
|
|
||||||
|
|
||||||
var item:MovieClip = cast target.getChildByName('item${_unusedChoices.length}');
|
|
||||||
if (item == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
target.removeChild(item);
|
|
||||||
_unusedChoices.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addItem(name:String, value:String):Void {
|
|
||||||
|
|
||||||
_values.set(value, name);
|
|
||||||
|
|
||||||
if (_unusedChoices.length == 0) {
|
|
||||||
|
|
||||||
NG.core.logError('cannot create another dropBox item max=${_choiceContainer.numChildren}');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var button = _unusedChoices.shift();
|
|
||||||
cast(button.getChildByName("label"), TextField).text = name;
|
|
||||||
_choiceContainer.addChild(button);
|
|
||||||
|
|
||||||
new Button(button, onChoiceClick.bind(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClickExpand():Void {
|
|
||||||
|
|
||||||
_choiceContainer.visible = !_choiceContainer.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChoiceClick(name:String):Void {
|
|
||||||
|
|
||||||
value = name;
|
|
||||||
|
|
||||||
_choiceContainer.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
package io.newgrounds.utils;
|
|
||||||
|
|
||||||
import io.newgrounds.NGLite;
|
|
||||||
|
|
||||||
import haxe.Http;
|
|
||||||
import haxe.Timer;
|
|
||||||
|
|
||||||
#if neko
|
|
||||||
import neko.vm.Thread;
|
|
||||||
#elseif java
|
|
||||||
import java.vm.Thread;
|
|
||||||
#elseif cpp
|
|
||||||
import cpp.vm.Thread;
|
|
||||||
#end
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses Threading to turn hxcpp's synchronous http requests into asynchronous processes
|
|
||||||
*
|
|
||||||
* @author GeoKureli
|
|
||||||
*/
|
|
||||||
class AsyncHttp {
|
|
||||||
|
|
||||||
inline static var PATH:String = "https://newgrounds.io/gateway_v3.php";
|
|
||||||
|
|
||||||
static public function send
|
|
||||||
( core:NGLite
|
|
||||||
, data:String
|
|
||||||
, onData:String->Void
|
|
||||||
, onError:String->Void
|
|
||||||
, onStatus:Int->Void
|
|
||||||
) {
|
|
||||||
|
|
||||||
core.logVerbose('sending: $data');
|
|
||||||
|
|
||||||
#if (neko || java || cpp)
|
|
||||||
sendAsync(core, data, onData, onError, onStatus);
|
|
||||||
#else
|
|
||||||
sendSync(core, data, onData, onError, onStatus);
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
static function sendSync
|
|
||||||
( core:NGLite
|
|
||||||
, data:String
|
|
||||||
, onData:String->Void
|
|
||||||
, onError:String->Void
|
|
||||||
, onStatus:Int->Void
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
var http = new Http(PATH);
|
|
||||||
http.setParameter("input", data);
|
|
||||||
http.onData = onData;
|
|
||||||
http.onError = onError;
|
|
||||||
http.onStatus = onStatus;
|
|
||||||
// #if js http.async = async; #end
|
|
||||||
http.request(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (neko || java || cpp)
|
|
||||||
static var _deadPool:Array<AsyncHttp> = [];
|
|
||||||
static var _livePool:Array<AsyncHttp> = [];
|
|
||||||
static var _map:Map<Int, AsyncHttp> = new Map();
|
|
||||||
static var _timer:Timer;
|
|
||||||
|
|
||||||
static var _count:Int = 0;
|
|
||||||
|
|
||||||
var _core:NGLite;
|
|
||||||
var _key:Int;
|
|
||||||
var _onData:String->Void;
|
|
||||||
var _onError:String->Void;
|
|
||||||
var _onStatus:Int->Void;
|
|
||||||
var _worker:Thread;
|
|
||||||
|
|
||||||
public function new (core:NGLite) {
|
|
||||||
|
|
||||||
_core = core;
|
|
||||||
_worker = Thread.create(sendThreaded);
|
|
||||||
_key = _count++;
|
|
||||||
_map[_key] = this;
|
|
||||||
_core.logVerbose('async http created: $_key');
|
|
||||||
}
|
|
||||||
|
|
||||||
function start(data:String, onData:String->Void, onError:String->Void, onStatus:Int->Void) {
|
|
||||||
|
|
||||||
_core.logVerbose('async http started: $_key');
|
|
||||||
|
|
||||||
if (_livePool.length == 0)
|
|
||||||
startTimer();
|
|
||||||
|
|
||||||
_deadPool.remove(this);
|
|
||||||
_livePool.push(this);
|
|
||||||
|
|
||||||
_onData = onData;
|
|
||||||
_onError = onError;
|
|
||||||
_onStatus = onStatus;
|
|
||||||
_worker.sendMessage({ source:Thread.current(), args:data, key:_key, core:_core });
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMessage(data:ReplyData):Void {
|
|
||||||
|
|
||||||
_core.logVerbose('handling message: $_key');
|
|
||||||
|
|
||||||
if (data.status != null) {
|
|
||||||
|
|
||||||
_core.logVerbose('\t- status: ${data.status}');
|
|
||||||
_onStatus(cast data.status);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tempFunc:Void->Void;
|
|
||||||
if (data.data != null) {
|
|
||||||
|
|
||||||
_core.logVerbose('\t- data');
|
|
||||||
tempFunc = _onData.bind(data.data);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
_core.logVerbose('\t- error');
|
|
||||||
tempFunc = _onError.bind(data.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanUp();
|
|
||||||
// Delay the call until destroy so that we're more likely to use a single
|
|
||||||
// thread on daisy-chained calls
|
|
||||||
tempFunc();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline function cleanUp():Void {
|
|
||||||
|
|
||||||
_onData = null;
|
|
||||||
_onError = null;
|
|
||||||
|
|
||||||
_deadPool.push(this);
|
|
||||||
_livePool.remove(this);
|
|
||||||
|
|
||||||
if (_livePool.length == 0)
|
|
||||||
stopTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
static function sendAsync
|
|
||||||
( core:NGLite
|
|
||||||
, data:String
|
|
||||||
, onData:String->Void
|
|
||||||
, onError:String->Void
|
|
||||||
, onStatus:Int->Void
|
|
||||||
):Void {
|
|
||||||
|
|
||||||
var http:AsyncHttp;
|
|
||||||
if (_deadPool.length == 0)
|
|
||||||
http = new AsyncHttp(core);
|
|
||||||
else
|
|
||||||
http = _deadPool[0];
|
|
||||||
|
|
||||||
http.start(data, onData, onError, onStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function startTimer():Void {
|
|
||||||
|
|
||||||
if (_timer != null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_timer = new Timer(1000 / 60.0);
|
|
||||||
_timer.run = update;
|
|
||||||
}
|
|
||||||
|
|
||||||
static function stopTimer():Void {
|
|
||||||
|
|
||||||
_timer.stop();
|
|
||||||
_timer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function update():Void {
|
|
||||||
|
|
||||||
var message:ReplyData = cast Thread.readMessage(false);
|
|
||||||
if (message != null)
|
|
||||||
_map[message.key].handleMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
static function sendThreaded():Void {
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
|
|
||||||
var data:LoaderData = cast Thread.readMessage(true);
|
|
||||||
data.core.logVerbose('start message received: ${data.key}');
|
|
||||||
|
|
||||||
sendSync
|
|
||||||
( data.core
|
|
||||||
, data.args
|
|
||||||
, function(reply ) { data.source.sendMessage({ key:data.key, data :reply }); }
|
|
||||||
, function(error ) { data.source.sendMessage({ key:data.key, error :error }); }
|
|
||||||
, function(status) { data.source.sendMessage({ key:data.key, status:status }); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (neko || java || cpp)
|
|
||||||
typedef LoaderData = { source:Thread, key:Int, args:String, core:NGLite };
|
|
||||||
typedef ReplyData = { key:Int, ?data:String, ?error:String, ?status:Null<Int> };
|
|
||||||
#end
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package io.newgrounds.utils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basically shitty signals, but I didn't want to have external references.
|
|
||||||
**/
|
|
||||||
class Dispatcher {
|
|
||||||
|
|
||||||
var _list:Array<Void->Void>;
|
|
||||||
var _once:Array<Void->Void>;
|
|
||||||
|
|
||||||
public function new() {
|
|
||||||
|
|
||||||
_list = new Array<Void->Void>();
|
|
||||||
_once = new Array<Void->Void>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add(handler:Void->Void, once:Bool = false):Bool {
|
|
||||||
|
|
||||||
if (_list.indexOf(handler) != -1) {
|
|
||||||
|
|
||||||
// ---- REMOVE ONCE
|
|
||||||
if (!once && _once.indexOf(handler) != -1)
|
|
||||||
_once.remove(handler);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_list.unshift(handler);
|
|
||||||
if (once)
|
|
||||||
_once.unshift(handler);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline public function addOnce(handler:Void->Void):Bool {
|
|
||||||
|
|
||||||
return add(handler, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function remove(handler:Void->Void):Bool {
|
|
||||||
|
|
||||||
_once.remove(handler);
|
|
||||||
return _list.remove(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dispatch():Void {
|
|
||||||
|
|
||||||
var i = _list.length - 1;
|
|
||||||
while(i >= 0) {
|
|
||||||
|
|
||||||
var handler = _list[i];
|
|
||||||
|
|
||||||
if (_once.remove(handler))
|
|
||||||
_list.remove(handler);
|
|
||||||
|
|
||||||
handler();
|
|
||||||
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TypedDispatcher<T> {
|
|
||||||
|
|
||||||
var _list:Array<T->Void>;
|
|
||||||
var _once:Array<T->Void>;
|
|
||||||
|
|
||||||
public function new() {
|
|
||||||
|
|
||||||
_list = new Array<T->Void>();
|
|
||||||
_once = new Array<T->Void>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add(handler:T->Void, once:Bool = false):Bool {
|
|
||||||
|
|
||||||
if (_list.indexOf(handler) != -1) {
|
|
||||||
|
|
||||||
// ---- REMOVE ONCE
|
|
||||||
if (!once && _once.indexOf(handler) != -1)
|
|
||||||
_once.remove(handler);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_list.unshift(handler);
|
|
||||||
if (once)
|
|
||||||
_once.unshift(handler);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline public function addOnce(handler:T->Void):Bool {
|
|
||||||
|
|
||||||
return add(handler, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function remove(handler:T->Void):Bool {
|
|
||||||
|
|
||||||
_once.remove(handler);
|
|
||||||
return _list.remove(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dispatch(arg:T):Void {
|
|
||||||
|
|
||||||
var i = _list.length - 1;
|
|
||||||
while(i >= 0) {
|
|
||||||
|
|
||||||
var handler = _list[i];
|
|
||||||
|
|
||||||
if (_once.remove(handler))
|
|
||||||
_list.remove(handler);
|
|
||||||
|
|
||||||
handler(arg);
|
|
||||||
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||