Merge branch 'main' into translations-system
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
ko_fi: codename_engine
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
build:
|
||||
name: Linux Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Pulling the source
|
||||
uses: actions/checkout@v2
|
||||
@@ -35,13 +35,13 @@ jobs:
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build linux
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin .
|
||||
# - name: Tar files
|
||||
# run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin .
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine
|
||||
path: CodenameEngine.tar.gz
|
||||
path: export/release/linux/bin/
|
||||
# - name: Uploading artifact (executable)
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export/
|
||||
dump/
|
||||
latest/windows/obj/
|
||||
latest/windows/haxe/
|
||||
latest/*
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
@@ -9,5 +8,8 @@ latest/windows/haxe/
|
||||
pages/
|
||||
docs/doc.xml
|
||||
mods/*
|
||||
addons/*
|
||||
!mods/readme.txt
|
||||
addons/*
|
||||
!addons/readme.txt
|
||||
dev-libs/
|
||||
|
||||
@@ -5,7 +5,7 @@ This changelog lists every change that has been added since the last update (inc
|
||||
## Flags System
|
||||
|
||||
- Added a brand new flags system, which allows you to modify the game constants using a simple `flags.ini` file ([f8d1cf0](https://github.com/CodenameCrew/CodenameEngine/commit/f8d1cf08ad9f6cdda4e971a3d8adff6fce5130d2))
|
||||
- Added the ability to change the way the mod songs/weeks are added to the menu ([cb1d6fc](https://github.com/CodenameCrew/CodenameEngine/commit/cb1d6fcacf4ad0e2888ed7e76d16a6f85c09b021))
|
||||
- Added the ability to change the way the mod songs/weeks are added into the menu ([cb1d6fc](https://github.com/CodenameCrew/CodenameEngine/commit/cb1d6fcacf4ad0e2888ed7e76d16a6f85c09b021))
|
||||
- Added the ability to disable editors, transtions and beta warning state ([90a8c27](https://github.com/CodenameCrew/CodenameEngine/commit/90a8c2711ce36c9eaf85e705d551d46876991aa9))
|
||||
- Added the ability to set the default Transition, Pause, Game Over scripts ([fd0c188](https://github.com/CodenameCrew/CodenameEngine/commit/fd0c188577cf58e34e8ed706e59903a989ee2d11))
|
||||
- Added the ability to set the default glsl version ([cbbb598](https://github.com/CodenameCrew/CodenameEngine/commit/cbbb598f52b3f7c0f156cf72cd03e165aa38a4f1))
|
||||
@@ -16,13 +16,14 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Added a function ``WindowUtils.resetAffixes()`` to reset the prefix and suffix of the engine's window title, and fixed a typo ([1d94945](https://github.com/CodenameCrew/CodenameEngine/commit/1d94945faeea86af02bcaecd715f5bea22ef48fd))
|
||||
- Added a field `extra` to FunkinSprite, which can be used to store any extra data you want (e.g. sprite.extra.set("name", value)) ([fb48570](https://github.com/CodenameCrew/CodenameEngine/commit/fb485701b451d6a7a22a1e696bfc081699f1c6d2))
|
||||
- Added default icon colors to every base game character ([814bd71](https://github.com/CodenameCrew/CodenameEngine/commit/814bd712fe2ea2dd21116e9903d9c2babe5341b1))
|
||||
- Added more features to cne.bat/cne.sh: ([4ef43df](https://github.com/CodenameCrew/CodenameEngine/commit/4ef43dfbecc79283d038d939f94671966802039e), [0dc166c](https://github.com/CodenameCrew/CodenameEngine/commit/0dc166c601b25e3167a1d04542840265484576b4))
|
||||
- Added more features to cne.bat/cne.sh: ([4ef43df](https://github.com/CodenameCrew/CodenameEngine/commit/4ef43dfbecc79283d038d939f94671966802039e), [0dc166c](https://github.com/CodenameCrew/CodenameEngine/commit/0dc166c601b25e3167a1d04542840265484576b4), [21bba98](https://github.com/CodenameCrew/CodenameEngine/commit/21bba98923307fe75667e1395781d068a7ec47ad))
|
||||
- Setup
|
||||
- `--reinstall` to reinstall all libraries
|
||||
- `--no-vscheck` to skip the Visual Studio check
|
||||
- `--silent` to not print the download progress
|
||||
- project file has conditionals now
|
||||
- libs file has conditionals now
|
||||
- `--lib=path.xml` to use a specific setup file
|
||||
- `--fast` for quickly downloading git libraries, but requires you to reinstall it fully when updates happen
|
||||
- Alphabet now allows multiple lines in the text ([d519db0](https://github.com/CodenameCrew/CodenameEngine/commit/d519db011a14aac0ddfc052089836c6b445f7f44))
|
||||
- Allow importing mod root level modules in hscript, instead of only source/ ([7e66ee8](https://github.com/CodenameCrew/CodenameEngine/commit/7e66ee81e24204cd152de20046fa1500bb9d204b))
|
||||
- Added a way to force animations in the `Play Animation` event ([d7b6fbe](https://github.com/CodenameCrew/CodenameEngine/commit/d7b6fbe510edeb832112ab5adc8ab19dfe97d77f))
|
||||
@@ -63,7 +64,6 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Added `bf` shorthand for `boyfriend` in playstate ([2b81220](https://github.com/CodenameCrew/CodenameEngine/commit/2b81220c15ed77acecd17c09a975ed401677165f))
|
||||
- Added character script extensions ([682358c](https://github.com/CodenameCrew/CodenameEngine/commit/682358c93a0c17469d1a481de0523e4c4e19c6ec))
|
||||
- Folder support in the character editor selection ([68c2fea](https://github.com/CodenameCrew/CodenameEngine/commit/68c2feab373db69d4a00b6f274f98afb3d8e3803))
|
||||
- cne.bat/cne.sh setup --fast for quickly downloading git libraries ([21bba98](https://github.com/CodenameCrew/CodenameEngine/commit/21bba98923307fe75667e1395781d068a7ec47ad))
|
||||
- Allow hold notes to be force deleted ([25b5630](https://github.com/CodenameCrew/CodenameEngine/commit/25b563066fc53ac92ebe3064175c80b5f1ae64bc))
|
||||
- Allow tweening shaders and array values using FlxTween ([3de3c3f](https://github.com/CodenameCrew/CodenameEngine/commit/3de3c3f8286b2b07c9690334e2d85ce052a909c5))
|
||||
- Made the advanced info show `Mod State: {name}` instead of `State: funkin.backend.scripting.ModState` ([3de3c3f](https://github.com/CodenameCrew/CodenameEngine/commit/3de3c3f8286b2b07c9690334e2d85ce052a909c5))
|
||||
@@ -91,6 +91,9 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Improved readability of the events macro ([47cf72d](https://github.com/CodenameCrew/CodenameEngine/commit/47cf72d53b985bcc818286a90fdbbaa92f4a9396))
|
||||
- Changed how editor icons are stored ([16672e9](https://github.com/CodenameCrew/CodenameEngine/commit/16672e9f597fd4e621d7ee2c000ba559d3837662), [18ea916](https://github.com/CodenameCrew/CodenameEngine/commit/18ea916f1af4c03db765ba55841acc13d7108766))
|
||||
- Changed `WindowUtils.winTitle` to `WindowUtils.title` ([a6c9975](https://github.com/CodenameCrew/CodenameEngine/commit/a6c99754fd1bfe56db61b82b9749f073a1a0a170))
|
||||
- Added property parsing and cloning property values ([503ff87](https://github.com/CodenameCrew/CodenameEngine/commit/503ff87ab3f6ccd4b0ab74e2403a29fff70cc1e1))
|
||||
- Added syncing booleans between strums and notes ([1af6931](https://github.com/CodenameCrew/CodenameEngine/commit/1af69313bb30a1d8faf91bc34b29c319290e0ea5))
|
||||
- Added ``onReturnToMenu`` event in GameOverSubstate ([cda9311](https://github.com/CodenameCrew/CodenameEngine/commit/cda9311a905a8b9d226f14b8f1e3430f54e70ee5))
|
||||
|
||||
## Removals
|
||||
|
||||
@@ -152,10 +155,12 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Fixed pasting and added copying in `UITextBox` ([c4abac4](https://github.com/CodenameCrew/CodenameEngine/commit/c4abac4ba1ef0692325a736f1123a511965368a6))
|
||||
- Made the Freeplay Autoplay change the bpm ([f90782d](https://github.com/CodenameCrew/CodenameEngine/commit/f90782d7123970215324ace99c55584ad78ca028))
|
||||
- Prevent accidental mouse inputs when pressing on the unfocused window ([300f38d](https://github.com/CodenameCrew/CodenameEngine/commit/300f38d290bb8c31a5c1e67afdf981c644b27f8a))
|
||||
- Fix notes not being destroyed when the strumline is destroyed ([1f224be](https://github.com/CodenameCrew/CodenameEngine/commit/1f224bef228c496d789aeed1f44c6517668107a9))
|
||||
- Fixed notes not being destroyed when the strumline is destroyed ([1f224be](https://github.com/CodenameCrew/CodenameEngine/commit/1f224bef228c496d789aeed1f44c6517668107a9))
|
||||
- Fixed the credits and options menu backgorunds not being animated if the background is animated ([1facc82](https://github.com/CodenameCrew/CodenameEngine/commit/1facc82073b9a06b861d1987a162f8aecbec46f1))
|
||||
- Fixed duplicated line messages in the log ([1aa1364](https://github.com/CodenameCrew/CodenameEngine/commit/1aa136469d1ecadb4e9c49c04d6d6287d4b39884))
|
||||
- Selection fixes in Editors ([0102cbb](https://github.com/CodenameCrew/CodenameEngine/commit/0102cbbdb6812f315697f6e389760ce948ff1993), [accc197](https://github.com/CodenameCrew/CodenameEngine/commit/accc197407c86a6fe9aaf1c557c93148674879ff))
|
||||
- Fixed Hscript Call event not calling public and static functions (also can now call character scripts) ([650c0f4](https://github.com/CodenameCrew/CodenameEngine/commit/650c0f4aed546ff80a0a590365b59427e4e45db6))
|
||||
- Made some menus remember the current selected item ([d36f4fa](https://github.com/CodenameCrew/CodenameEngine-Dev/commit/d36f4fa48430ac73d7f2c8701894283041898ce6), [6bed0a7](https://github.com/CodenameCrew/CodenameEngine-Dev/commit/6bed0a789f2b809dc6311c8227c8307c0f2fe522))
|
||||
|
||||
## Crash fixes
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ If you don't have a github account please go onto https://fnf-cne-devs.github.io
|
||||
<details>
|
||||
<summary><h2>Credits</h2></summary>
|
||||
|
||||
- Credits to [Ne_Eo](https://twitter.com/Ne_Eo_Twitch) and the [3D-HaxeFlixel](https://github.com/lunarcleint/3D-HaxeFlixel) repository for Away3D Flixel support
|
||||
- Credits to the [FlxAnimate](https://github.com/Dot-Stuff/flxanimate) team for the Animate Atlas support
|
||||
- Credits to Smokey555 for the backup Animate Atlas to spritesheet code
|
||||
- Credits to MAJigsaw77 for [hxvlc](https://github.com/MAJigsaw77/hxvlc) (video cutscene/mp4 support) and [hxdiscord_rpc](https://github.com/MAJigsaw77/hxdiscord_rpc) (discord rpc integration)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
╔═══════════════════════════════════════╗
|
||||
║ HOW TO USE ║
|
||||
╚═══════════════════════════════════════╝
|
||||
DRAG AND DROP YOUR ADDON FOLDER HERE!
|
||||
|
||||
╔═══════════════════════════════════════╗
|
||||
║ ZIP ADDONS ║
|
||||
╚═══════════════════════════════════════╝
|
||||
Zip files are also supported at condition it follows this hierarchy:
|
||||
|
||||
📁addon.zip/
|
||||
📁data
|
||||
📁images
|
||||
📁...
|
||||
|
||||
Instead of this one
|
||||
|
||||
📁addon.zip
|
||||
📁my addon
|
||||
📁data
|
||||
📁images
|
||||
📁...
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 216 B |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 447 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 424 B |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 131 KiB |
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="-50" y="330" isGF="false" flipX="true" isPlayer="true" antialiasing="true" sprite="bf-holding-gf-dead" color="#31B0D1">
|
||||
<character x="-50" y="330" flipX="true" isPlayer="true" antialiasing="true" sprite="bf-holding-gf-dead" color="#31B0D1">
|
||||
<anim x="0" loop="false" y="0" fps="24" anim="BF Dies with GF" name="firstDeath"/>
|
||||
<anim x="0" loop="false" y="-17" fps="24" anim="BF Dead with GF Loop" name="deathLoop"/>
|
||||
<anim x="0" loop="false" y="14" fps="24" anim="RETRY confirm holding gf" name="deathConfirm"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character icon="bf-pixel-dead" x="200" y="570" isGF="false" scale="6" flipX="true" isPlayer="true" antialiasing="false" sprite="bf-pixel-dead" color="#7BD6F6">
|
||||
<character icon="bf-pixel-dead" x="200" y="570" scale="6" flipX="true" isPlayer="true" antialiasing="false" sprite="bf-pixel-dead" color="#7BD6F6">
|
||||
<anim x="0" loop="false" y="0" fps="24" anim="BF Dies pixel" name="firstDeath"/>
|
||||
<anim x="-5" loop="true" y="-2" fps="24" anim="Retry Loop" name="deathLoop"/>
|
||||
<anim x="-5" loop="false" y="-2" fps="24" anim="RETRY CONFIRM" name="deathConfirm"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character isPlayer="false" flipX="false" isGF="true" x="75" y="335" icon="gf" color="#A5004D">
|
||||
<character isPlayer="false" flipX="false" x="75" y="335" icon="gf" color="#A5004D">
|
||||
<anim name="danceLeft" anim="GF Dancing Beat Hair blowing CAR" fps="24" loop="false" x="0" y="0" indices="0..15" />
|
||||
<anim name="danceRight" anim="GF Dancing Beat Hair blowing CAR" fps="24" loop="false" x="0" y="0" indices="16..30" />
|
||||
</character>
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="115" y="325" sprite="gf-christmas" icon="gf" color="#A5004D" isGF="true">
|
||||
<character x="115" y="325" sprite="gf-christmas" icon="gf" color="#A5004D">
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character sprite="gf-tankmen" icon="gf" color="#A5004D" isGF="true">
|
||||
<character sprite="gf-tankmen" icon="gf" color="#A5004D">
|
||||
<anim name="danceLeft" anim="GF Dancing at Gunpoint" x="0" y="0" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing at Gunpoint" x="0" y="0" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="dance-cutscene" anim="GF Dancing at Gunpoint" x="0" y="0" fps="24" loop="true"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="100" y="275" sprite="gf" icon="gf" color="#A5004D" isGF="true">
|
||||
<character x="100" y="275" sprite="gf" icon="gf" color="#A5004D">
|
||||
<anim name="cheer" anim="GF Cheer" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="GF left note" x="0" y="0" fps="24" loop="false"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="150" y="360" sprite="senpai" scale="6" antialiasing="false" camx="100" camy="87" icon="senpai" color="#FFAA6F" isGF="false">
|
||||
<character x="150" y="360" sprite="senpai" scale="6" antialiasing="false" camx="100" camy="87" icon="senpai" color="#FFAA6F">
|
||||
<anim name="idle" anim="Angry Senpai Idle" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="Angry Senpai LEFT NOTE" x="3" y="0" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="Angry Senpai DOWN NOTE" x="-1" y="0" fps="24" loop="false"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character y="180" sprite="tankman" flipX="true" isPlayer="true" icon="tankman" color="#FFFFFF" isGF="false">
|
||||
<character y="180" sprite="tankman" flipX="true" isPlayer="true" icon="tankman" color="#FFFFFF">
|
||||
<anim name="idle" anim="Tankman Idle Dance instance 100" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singRIGHT" anim="Tankman Right Note instance 1000" x="-24" y="-13" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="Tankman DOWN note instance 1000" x="75" y="-105" fps="24" loop="false"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"clientID": "1027994136193810442",
|
||||
"clientID": "1383853614589673472",
|
||||
"logoKey": "icon"
|
||||
}
|
||||
@@ -8,7 +8,7 @@ function onDiscordPresenceUpdate(e) {
|
||||
var data = e.presence;
|
||||
|
||||
if(data.button1Label == null)
|
||||
data.button1Label = "Codename Engine Discord";
|
||||
data.button1Label = "meow"; // "Codename Engine Discord"
|
||||
if(data.button1Url == null)
|
||||
data.button1Url = "https://discord.gg/2NTCdsQvx4";
|
||||
}
|
||||
@@ -33,8 +33,8 @@ function onEditorTreeLoaded(name:String) {
|
||||
DiscordUtil.changePresenceSince("Choosing a Character", null);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Choosing a Chart", null);
|
||||
case "Stage Editor":
|
||||
DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
//case "Stage Editor": // secret for now
|
||||
// DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function onEditorLoaded(name:String, editingThing:String) {
|
||||
DiscordUtil.changePresenceSince("Editing a Character", editingThing);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Chart", editingThing);
|
||||
case "Stage Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
//case "Stage Editor":
|
||||
// DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<window width="550" height="570" title="Editing Character ${button.getName()}">
|
||||
<set name="XOFFSET" value="30" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
|
||||
<exec>
|
||||
function col(c:Int) {
|
||||
return 20 + (150 + XOFFSET) * c;
|
||||
}
|
||||
previewSprite = null;
|
||||
if(char.animateAtlas == null) {
|
||||
previewSprite = new FunkinSprite(0, 0);
|
||||
previewSprite.frame = char.frame;
|
||||
|
||||
self.add(previewSprite);
|
||||
}
|
||||
</exec>
|
||||
|
||||
<title name="title" x="20" y="30 + 16" text="Character Data" />
|
||||
|
||||
<section>
|
||||
<set name="curY" value="title.y + TO" />
|
||||
|
||||
<stepper name="xStepper" label="X" value="char.x" x="col(0)" y="curY" step="1" width="100" />
|
||||
<stepper name="yStepper" label="Y" value="char.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" step="1" width="100" />
|
||||
|
||||
<stepper name="scrollXStepper" label="Scroll X" value="char.scrollFactor.x" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="scrollYStepper" label="Scroll Y" value="char.scrollFactor.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<stepper name="scaleXStepper" label="Scale X" value="char.scale.x / charScale" x="col(2)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="scaleYStepper" label="Scale Y" value="char.scale.y / charScale" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="xStepper.y + xStepper.bHeight + YOFFSET" />
|
||||
|
||||
<stepper name="camxStepper" label="Cam X" value="getEx('camX')" x="col(0)" y="curY" step="1" width="100" />
|
||||
<stepper name="camyStepper" label="Cam Y" value="getEx('camY')" x="last.x + last.bWidth + XOFFSET - 20" y="curY" step="1" width="100" />
|
||||
|
||||
<label name="spacingLabel" text="Spacing (X, Y)" x="col(1)" y="curY" size="15" />
|
||||
<stepper name="spacingXStepper" value="getEx('spacingX')" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="spacingYStepper" value="getEx('spacingY')" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<stepper name="skewXStepper" label="Skew X" value="char.skew.x" x="col(2)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="skewYStepper" label="Skew Y" value="char.skew.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="camxStepper.y + camxStepper.bHeight + YOFFSET" />
|
||||
|
||||
<stepper name="alphaStepper" label="Alpha" value="char.alpha / 0.75" x="col(0)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="angleStepper" label="Angle" value="char.angle" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<stepper name="zoomFactorStepper" label="Zoom Factor" value="char.zoomFactor" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<section if="!StringTools.startsWith(char.name, 'NO_DELETE_')">
|
||||
<textbox name="charName" label="Position Name" value="char.name" x="col(2)" y="curY" width="100"/>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="alphaStepper.y + alphaStepper.bHeight + YOFFSET - 20" />
|
||||
|
||||
<checkbox name="flipXCheckbox" text="Flip X" value="char.isPlayer" x="col(0)" y="curY" />
|
||||
|
||||
<radio for="memoryCheck" name="highMemoryRadio" text="High Memory Only" value="getEx('highMemory')" x="last.field.x + last.field.width + XOFFSET * 2" y="curY" />
|
||||
<radio for="memoryCheck" name="lowMemoryRadio" text="Low Memory Only" value="getEx('lowMemory')" x="last.field.x + last.field.width + XOFFSET * 2" y="curY" />
|
||||
</section>
|
||||
|
||||
<section if="previewSprite != null">
|
||||
<title name="previewTitle" x="20" y="self.winHeight - 220" text="Preview Transform:" size="15" />
|
||||
</section>
|
||||
<section if="previewSprite == null">
|
||||
<exec>
|
||||
self.windowSpr.bHeight -= 170;
|
||||
</exec>
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onUpdate() {
|
||||
if(previewSprite == null) return;
|
||||
previewSprite.skew.x = skewXStepper.value;
|
||||
previewSprite.skew.y = skewYStepper.value;
|
||||
previewSprite.angle = angleStepper.value;
|
||||
previewSprite.antialiasing = char.antialiasing;
|
||||
var ratio = char.frameWidth / char.frameHeight;
|
||||
previewSprite.setGraphicSize(145 * scaleXStepper.value * ratio, 145 * scaleYStepper.value);
|
||||
previewSprite.updateHitbox();
|
||||
if(flipXCheckbox.checked != char.playerOffsets)
|
||||
previewSprite.scale.x *= -1;
|
||||
|
||||
previewSprite.x = 30;
|
||||
previewSprite.y = self.winHeight - previewSprite.height - 30;
|
||||
}
|
||||
|
||||
function onSave() {
|
||||
setEx("highMemory", highMemoryRadio.checked);
|
||||
setEx("lowMemory", lowMemoryRadio.checked);
|
||||
|
||||
if (!StringTools.startsWith(char.name, 'NO_DELETE_'))
|
||||
char.name = charName.field.text;
|
||||
|
||||
char.x = xStepper.value;
|
||||
char.y = yStepper.value;
|
||||
char.scrollFactor.set(scrollXStepper.value, scrollYStepper.value);
|
||||
char.scale.set(scaleXStepper.value * charScale, scaleYStepper.value * charScale);
|
||||
char.cameraOffset.x -= getEx("camX");
|
||||
char.cameraOffset.x += camxStepper.value;
|
||||
setEx("camX", camxStepper.value);
|
||||
char.cameraOffset.y -= getEx("camY");
|
||||
char.cameraOffset.y += camyStepper.value;
|
||||
setEx("camY", camyStepper.value);
|
||||
char.skew.x = skewXStepper.value;
|
||||
char.skew.y = skewYStepper.value;
|
||||
char.alpha = alphaStepper.value * 0.75;
|
||||
setEx("spacingX", spacingXStepper.value);
|
||||
setEx("spacingY", spacingYStepper.value);
|
||||
if (flipXCheckbox.checked != char.isPlayer) {
|
||||
char.isPlayer = flipXCheckbox.checked;
|
||||
char.swapLeftRightAnimations();
|
||||
}
|
||||
char.zoomFactor = zoomFactorStepper.value;
|
||||
char.angle = angleStepper.value;
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -0,0 +1,185 @@
|
||||
<window width="1056" height="520" title="Editing Sprite ${button.getName()}">
|
||||
<set name="MARGIN" value="20" />
|
||||
<set name="XOFFSET" value="50" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
|
||||
<exec>
|
||||
function col(c:Int) {
|
||||
return 20 + (200 + XOFFSET) * c;
|
||||
}
|
||||
|
||||
if(sprite.animateAtlas == null) {
|
||||
previewSprite = new FunkinSprite(50, self.winHeight - 100);
|
||||
previewSprite.frame = sprite.frame;
|
||||
|
||||
self.add(previewSprite);
|
||||
}
|
||||
</exec>
|
||||
|
||||
<title name="title" x="20" y="30 + 16" text="Sprite Data" />
|
||||
|
||||
<section> <!-- ROW 1 -->
|
||||
<set name="curY" value="title.y + TO" />
|
||||
|
||||
<textbox name="nameTextBox" label="Name Identifier" value="button.getName()" x="col(0)" y="curY" width="200" height="32" />
|
||||
<textbox name="spriteTextBox" value="getEx('imageFile')" x="last.x + last.bWidth + XOFFSET" y="curY" width="200" height="32" />
|
||||
<stepper name="alphaStepper" label="Alpha" value="sprite.alpha" x="spriteTextBox.x + spriteTextBox.bWidth + XOFFSET" y="curY" precision="2" step="0.01" width="100" />
|
||||
<label name="imageFile" text="Image File (WIP: needs reload) In (${stage.spritesParentFolder})" x="spriteTextBox.x" y="spriteTextBox.y - 14" size="15" />
|
||||
</section>
|
||||
|
||||
<section> <!-- ROW 2 -->
|
||||
<set name="curY" value="nameTextBox.y + nameTextBox.bHeight + YOFFSET" />
|
||||
|
||||
<stepper name="xStepper" label="X" value="sprite.x" x="col(0)" y="curY" step="1" width="100" />
|
||||
<stepper name="yStepper" label="Y" value="sprite.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" step="1" width="100" />
|
||||
|
||||
<stepper name="scrollXStepper" label="Scroll X" value="sprite.scrollFactor.x" x="spriteTextBox.x" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="scrollYStepper" label="Scroll Y" value="sprite.scrollFactor.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<stepper name="scaleXStepper" label="Scale X" value="sprite.scale.x" x="col(2)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="scaleYStepper" label="Scale Y" value="sprite.scale.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section> <!-- ROW 3 -->
|
||||
<set name="curY" value="xStepper.y + xStepper.bHeight + YOFFSET" />
|
||||
|
||||
<stepper name="angleStepper" label="Angle" value="sprite.angle" x="col(0)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="zoomFactorStepper" label="Zoom Factor" value="sprite.zoomFactor" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
|
||||
<!-- TODO: Simplify this -->
|
||||
<dropdown name="animType" label="Animation Type" value="sprite.spriteAnimType" x="col(1)" y="curY" width="150" height="32">
|
||||
<item label="NONE" value="0" />
|
||||
<item label="BEAT" value="1" />
|
||||
<item label="LOOP" value="2" />
|
||||
</dropdown>
|
||||
|
||||
<stepper name="skewXStepper" label="Skew X" value="sprite.skew.x" x="col(2)" y="curY" precision="2" step="0.01" width="100" />
|
||||
<stepper name="skewYStepper" label="Skew Y" value="sprite.skew.y" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section> <!-- ROW 4 -->
|
||||
<set name="curY" value="angleStepper.y + angleStepper.bHeight + YOFFSET" />
|
||||
|
||||
<checkbox name="antialiasingCheckbox" text="Antialiasing" value="sprite.antialiasing" x="col(0)" y="curY" />
|
||||
<radio for="memoryCheck" name="highMemoryRadio" text="High Memory Only" value="getEx('highMemory')" x="col(1)" y="curY" />
|
||||
<radio for="memoryCheck" name="lowMemoryRadio" text="Low Memory Only" value="getEx('lowMemory')" x="col(2)" y="curY" />
|
||||
|
||||
<!-- TODO: Animation list -->
|
||||
</section>
|
||||
|
||||
<section> <!-- RIGHT SIDE -->
|
||||
<set name="curY" value="title.y + TO" />
|
||||
<set name="listWidth" value="250" />
|
||||
|
||||
<buttonlist name="animations" label="Animations (TODO)" x="col(3)" y="curY" width="listWidth" height="330" buttonSizeX="listWidth-10" buttonSizeY="35" buttonSpacing="5">
|
||||
<texture path="editors/ui/inputbox" />
|
||||
<camSpacing value="0" />
|
||||
|
||||
<code>
|
||||
buttonlist.addButton.exists = false;
|
||||
</code>
|
||||
|
||||
<!-- <code>
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
|
||||
var buttonList = buttonlist; // important for now, since it gets reset after the code is run
|
||||
|
||||
var width = buttonList.buttonSize.x;
|
||||
var height = buttonList.buttonSize.y;
|
||||
|
||||
buttonList.addButton.callback = function() {
|
||||
buttonList.add(new PropertyButton("newProperty", "valueHere", buttonList, width, height, 150, 220, 25));
|
||||
}
|
||||
|
||||
//var defaultAttribs = Stage.DEFAULT_ATTRIBUTES;
|
||||
//for (i in stage.stageXML.attributes()) {
|
||||
// trace(i, defaultAttribs);
|
||||
// if (!defaultAttribs.contains(i))
|
||||
// buttonList.add(new PropertyButton(i, stage.stageXML.get(i), buttonList, width, height, 150, 220, 25));
|
||||
//}
|
||||
for(key => val in stage.extra)
|
||||
buttonList.add(new PropertyButton(key, val, buttonList, width, height, 150, 220, 25));
|
||||
</code> -->
|
||||
</buttonlist>
|
||||
|
||||
<text text="Tip: To access custom properties, hold shift when clicking edit" x="col(2) - 60" y="self.winHeight - 50" size="15" />
|
||||
</section>
|
||||
|
||||
|
||||
<!-- Preview Transform -->
|
||||
|
||||
<section if="previewSprite != null">
|
||||
<title name="previewTitle" x="20" y="self.winHeight - 150" text="Preview Transform:" size="15" />
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onUpdate() {
|
||||
if(previewSprite == null) return;
|
||||
previewSprite.color = 0xFFFFFFFF; // TODO: Color Wheel
|
||||
previewSprite.skew.x = skewXStepper.value;
|
||||
previewSprite.skew.y = skewYStepper.value;
|
||||
previewSprite.angle = angleStepper.value;
|
||||
previewSprite.alpha = alphaStepper.value;
|
||||
previewSprite.antialiasing = antialiasingCheckbox.checked;
|
||||
var ratio = sprite.width / sprite.height;
|
||||
previewSprite.setGraphicSize(50 * scaleXStepper.value * ratio, 50 * scaleYStepper.value);
|
||||
previewSprite.updateHitbox();
|
||||
}
|
||||
|
||||
function onSave() {
|
||||
sprite.name = nameTextBox.label.text;
|
||||
setEx("imageFile", spriteTextBox.label.text);
|
||||
|
||||
setEx("highMemory", highMemoryRadio.checked);
|
||||
setEx("lowMemory", lowMemoryRadio.checked);
|
||||
|
||||
//sprite.x = xStepper.value;
|
||||
//sprite.y = yStepper.value;
|
||||
//sprite.zoomFactor = zoomFactorStepper.value;
|
||||
//sprite.antialiasing = antialiasingCheckbox.checked;
|
||||
//sprite.color = colorWheel.color;
|
||||
//sprite.spriteAnimType = animType.value;
|
||||
sprite.angle = angleStepper.value;
|
||||
sprite.alpha = alphaStepper.value;
|
||||
|
||||
function saveXY(obj:Dynamic, name:String, x:UINumericStepper, y:UINumericStepper) {
|
||||
button.xml.remove(name + "");
|
||||
button.xml.remove(name + "x");
|
||||
button.xml.remove(name + "y");
|
||||
|
||||
obj.x = x.value;
|
||||
obj.y = y.value;
|
||||
|
||||
if(x.value == y.value)
|
||||
button.xml.set(name, x.value);
|
||||
else {
|
||||
button.xml.set(name + "x", x.value);
|
||||
button.xml.set(name + "y", y.value);
|
||||
}
|
||||
}
|
||||
function save(name:String, value:Dynamic) {
|
||||
button.xml.remove(name);
|
||||
button.xml.set(name, value);
|
||||
}
|
||||
|
||||
// TODO: remove old attributes to prevent possible errors
|
||||
// button.xml.remove();
|
||||
|
||||
button.xml.set("name", nameTextBox.label.text);
|
||||
button.xml.set("sprite", spriteTextBox.label.text);
|
||||
button.xml.set("x", xStepper.value);
|
||||
button.xml.set("y", yStepper.value);
|
||||
button.xml.set("zoom", zoomFactorStepper.value);
|
||||
button.xml.set("type", animType.key);
|
||||
button.xml.set("antialiasing", antialiasingCheckbox.checked);
|
||||
button.xml.set("angle", angleStepper.value);
|
||||
button.xml.set("alpha", alphaStepper.value);
|
||||
|
||||
saveXY(sprite.scrollFactor, "scroll", scrollXStepper, scrollYStepper);
|
||||
saveXY(sprite.scale, "scale", scaleXStepper, scaleYStepper);
|
||||
saveXY(sprite.skew, "skew", skewXStepper, skewYStepper);
|
||||
XMLUtil.loadSpriteFromXML(sprite, button.xml, stage.spritesParentFolder);
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -0,0 +1,110 @@
|
||||
<window width="470" height="620" title="Editing Stage Info '${stage.stageName}'">
|
||||
<set name="MARGIN" value="20" />
|
||||
<set name="XOFFSET" value="50" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
<set name="storedProps" value="[]" />
|
||||
|
||||
<exec>
|
||||
import haxe.ds.StringMap;
|
||||
var oldInfo = {
|
||||
name: stage.stageName,
|
||||
folder: stage.spritesParentFolder,
|
||||
startCamX: stage.startCam.x,
|
||||
startCamY: stage.startCam.y,
|
||||
zoom: stage.defaultZoom,
|
||||
attrib: new StringMap()
|
||||
};
|
||||
|
||||
function col(c:Int) {
|
||||
return MARGIN + (170 + XOFFSET) * c;
|
||||
}
|
||||
|
||||
for(prop => val in stage.extra) {
|
||||
if(!StringTools.startsWith(prop, "stageEditor.")) {
|
||||
storedProps.push(prop);
|
||||
oldInfo.attrib.set(prop, val);
|
||||
}
|
||||
}
|
||||
</exec>
|
||||
|
||||
<title name="title" x="MARGIN" y="30 + 16" text="Stage Info" />
|
||||
|
||||
<section> <!-- ROW 1 -->
|
||||
<set name="curY" value="title.y + TO" />
|
||||
|
||||
<textbox name="nameTextBox" label="Stage Name" value="stage.stageName" x="col(0)" y="curY" width="200" height="32" />
|
||||
<textbox name="spritePathTextBox" value="stage.spritesParentFolder" x="col(1)" y="curY" width="200" height="32" />
|
||||
<label text="Sprite Path (Needs Refresh)" x="spritePathTextBox.x" y="spritePathTextBox.y - 14" size="15" />
|
||||
</section>
|
||||
|
||||
<section> <!-- ROW 2 -->
|
||||
<set name="curY" value="nameTextBox.y + nameTextBox.bHeight + YOFFSET" />
|
||||
|
||||
<label text="Start Cam Pos (X, Y)" x="col(0)" y="curY" />
|
||||
<stepper name="camxStepper" value="stage.startCam.x" x="col(0)" y="curY" step="1" width="120" />
|
||||
<stepper name="camyStepper" value="stage.startCam.y" x="last.x + last.bWidth + XOFFSET - 30" y="curY" step="1" width="120" />
|
||||
|
||||
<stepper name="zoomStepper" label="Zoom" value="stage.defaultZoom" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="camxStepper.y + camxStepper.bHeight + YOFFSET" />
|
||||
<set name="listWidth" value="self.winWidth - MARGIN * 2" />
|
||||
|
||||
<buttonlist name="attributesList" label="Custom Attributes" x="col(0)" y="curY" width="listWidth" height="290" buttonSizeX="listWidth-10" buttonSizeY="35" buttonSpacing="5">
|
||||
<texture path="editors/ui/inputbox" />
|
||||
<camSpacing value="0" />
|
||||
|
||||
<code>
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
|
||||
var buttonList = buttonlist; // important for now, since it gets reset after the code is run
|
||||
|
||||
var width = buttonList.buttonSize.x;
|
||||
var height = buttonList.buttonSize.y;
|
||||
|
||||
buttonList.addButton.callback = function() {
|
||||
buttonList.add(new PropertyButton("newProperty", "valueHere", buttonList, width, height, 150, 220, 25));
|
||||
}
|
||||
|
||||
//var defaultAttribs = Stage.DEFAULT_ATTRIBUTES;
|
||||
//for (i in stage.stageXML.attributes()) {
|
||||
// trace(i, defaultAttribs);
|
||||
// if (!defaultAttribs.contains(i))
|
||||
// buttonList.add(new PropertyButton(i, stage.stageXML.get(i), buttonList, width, height, 150, 220, 25));
|
||||
//}
|
||||
for(key => val in stage.extra)
|
||||
buttonList.add(new PropertyButton(key, val, buttonList, width, height, 150, 220, 25));
|
||||
</code>
|
||||
</buttonlist>
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onSave() {
|
||||
stage.startCam.x = camxStepper.value;
|
||||
stage.startCam.y = camyStepper.value;
|
||||
stage.defaultZoom = zoomStepper.value;
|
||||
stage.stageName = nameTextBox.label.text;
|
||||
stage.spritesParentFolder = spritePathTextBox.label.text;
|
||||
|
||||
for(prop in storedProps)
|
||||
stage.extra.remove(prop);
|
||||
|
||||
var newInfo = {
|
||||
name: stage.stageName,
|
||||
folder: stage.spritesParentFolder,
|
||||
startCamX: stage.startCam.x,
|
||||
startCamY: stage.startCam.y,
|
||||
zoom: stage.defaultZoom,
|
||||
attrib: new StringMap()
|
||||
};
|
||||
for(prop in attributesList.buttons.members) {
|
||||
stage.extra.set(prop.propertyText.label.text, prop.valueText.label.text);
|
||||
newInfo.attrib.set(prop.propertyText.label.text, prop.valueText.label.text);
|
||||
}
|
||||
|
||||
FlxG.state.undos.addToUndo(CEditInfo(oldInfo, newInfo));
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -0,0 +1,66 @@
|
||||
<window width="350" height="570" title="Editing XML <${button.getName()} />">
|
||||
<set name="MARGIN" value="20" />
|
||||
<set name="XOFFSET" value="30" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
|
||||
<exec>
|
||||
function col(c:Int) {
|
||||
return MARGIN + (150 + XOFFSET) * c;
|
||||
}
|
||||
</exec>
|
||||
|
||||
<title name="title" x="MARGIN" y="30 + 16" text="Xml Data" />
|
||||
|
||||
<section>
|
||||
<set name="curY" value="title.y + TO" />
|
||||
|
||||
<textbox name="nodeNameTextBox" label="Element Name" value="button.getName()" x="col(0)" y="curY" width="280" height="32" />
|
||||
</section>
|
||||
<section>
|
||||
<set name="curY" value="nodeNameTextBox.y + nodeNameTextBox.bHeight + YOFFSET - 30" />
|
||||
|
||||
<radio for="memoryCheck" name="highMemoryRadio" text="High Memory Only" value="button.highMemory" x="col(0)" y="curY" />
|
||||
<radio for="memoryCheck" name="lowMemoryRadio" text="Low Memory Only" value="button.lowMemory" x="col(0)" y="last.y + last.check.height + YOFFSET - 30" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="lowMemoryRadio.y + lowMemoryRadio.check.height + YOFFSET" />
|
||||
<set name="listWidth" value="self.winWidth - MARGIN * 2" />
|
||||
|
||||
<buttonlist name="attributesList" label="Attributes" x="col(0)" y="curY" width="listWidth" height="260" buttonSizeX="listWidth-10" buttonSizeY="35" buttonSpacing="5">
|
||||
<texture path="editors/ui/inputbox" />
|
||||
<camSpacing value="0" />
|
||||
|
||||
<code>
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
|
||||
var buttonList = buttonlist; // important for now, since it gets reset after the code is run
|
||||
|
||||
var width = buttonList.buttonSize.x;
|
||||
var height = buttonList.buttonSize.y;
|
||||
|
||||
buttonList.addButton.callback = function() {
|
||||
buttonList.add(new PropertyButton("newProperty", "valueHere", buttonList, width, height, 110, 145, 25));
|
||||
}
|
||||
|
||||
for (i in xml.attributes())
|
||||
buttonList.add(new PropertyButton(i, xml.get(i), buttonList, width, height, 110, 145, 25));
|
||||
</code>
|
||||
</buttonlist>
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onSave() {
|
||||
button.xml.nodeName = nodeNameTextBox.label.text;
|
||||
button.highMemory = highMemoryRadio.checked;
|
||||
button.lowMemory = lowMemoryRadio.checked;
|
||||
|
||||
for (i in xml.attributes())
|
||||
xml.remove(i);
|
||||
|
||||
for (val in attributesList.buttons.members)
|
||||
xml.set(val.propertyText.label.text, val.valueText.label.text);
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -0,0 +1,51 @@
|
||||
<window width="450" height="570" title="Editing XML ${type}">
|
||||
<!-- BASED ON unknownEditScreen.xml -->
|
||||
<set name="MARGIN" value="20" />
|
||||
<set name="XOFFSET" value="30" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
|
||||
<exec>
|
||||
function col(c:Int) {
|
||||
return MARGIN + (150 + XOFFSET) * c;
|
||||
}
|
||||
</exec>
|
||||
|
||||
<title name="title" x="MARGIN" y="30 + 16" text="Xml Data" />
|
||||
|
||||
<section>
|
||||
<set name="curY" value="title.y + TO" />
|
||||
<set name="listWidth" value="self.winWidth - MARGIN * 2" />
|
||||
|
||||
<buttonlist name="attributesList" label="Attributes" x="col(0)" y="curY" width="listWidth" height="400" buttonSizeX="listWidth-10" buttonSizeY="35" buttonSpacing="5">
|
||||
<texture path="editors/ui/inputbox" />
|
||||
<camSpacing value="0" />
|
||||
|
||||
<code>
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
|
||||
var buttonList = buttonlist; // important for now, since it gets reset after the code is run
|
||||
|
||||
var width = buttonList.buttonSize.x;
|
||||
var height = buttonList.buttonSize.y;
|
||||
|
||||
buttonList.addButton.callback = function() {
|
||||
buttonList.add(new PropertyButton("newProperty", "valueHere", buttonList, width, height, 160, 195, 25));
|
||||
}
|
||||
|
||||
for (i in xml.attributes())
|
||||
buttonList.add(new PropertyButton(i, xml.get(i), buttonList, width, height, 160, 195, 25));
|
||||
</code>
|
||||
</buttonlist>
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onSave() {
|
||||
for (i in xml.attributes())
|
||||
xml.remove(i);
|
||||
|
||||
for (val in attributesList.buttons.members)
|
||||
xml.set(val.propertyText.label.text, val.valueText.label.text);
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -1,3 +0,0 @@
|
||||
//
|
||||
function update(elapsed:Float)
|
||||
if (FlxG.keys.justPressed.F5) FlxG.resetState();
|
||||
@@ -1,2 +1,2 @@
|
||||
function onNoteHit(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "-alt";
|
||||
function onPlayerMiss(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "-alt";
|
||||
function onPlayerMiss(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "miss-alt";
|
||||
@@ -18,44 +18,47 @@ public var daPixelZoom = PlayState.daPixelZoom;
|
||||
* UI
|
||||
*/
|
||||
function onNoteCreation(event) {
|
||||
if (event.note.strumLine == playerStrums && !pixelNotesForBF) return;
|
||||
if (event.note.strumLine == cpuStrums && !pixelNotesForDad) return;
|
||||
|
||||
if ((event.note.strumLine == playerStrums && !pixelNotesForBF) || (event.note.strumLine == cpuStrums && !pixelNotesForDad)) return;
|
||||
event.cancel();
|
||||
|
||||
var note = event.note;
|
||||
var strumID = event.strumID;
|
||||
if (event.note.isSustainNote) {
|
||||
note.loadGraphic(Paths.image('stages/school/ui/arrowEnds'), true, 7, 6);
|
||||
note.animation.add("hold", [event.strumID]);
|
||||
note.animation.add("holdend", [4 + event.strumID]);
|
||||
var maxCol = Math.floor(note.graphic.width / 7);
|
||||
note.animation.add("hold", [strumID%maxCol]);
|
||||
note.animation.add("holdend", [maxCol + strumID%maxCol]);
|
||||
} else {
|
||||
note.loadGraphic(Paths.image('stages/school/ui/arrows-pixels'), true, 17, 17);
|
||||
note.animation.add("scroll", [4 + event.strumID]);
|
||||
var maxCol = Math.floor(note.graphic.width / 17);
|
||||
note.animation.add("scroll", [maxCol + strumID%maxCol]);
|
||||
}
|
||||
note.scale.set(daPixelZoom, daPixelZoom);
|
||||
var strumScale = event.note.strumLine.strumScale;
|
||||
note.scale.set(daPixelZoom*strumScale, daPixelZoom*strumScale);
|
||||
note.updateHitbox();
|
||||
note.antialiasing = false;
|
||||
}
|
||||
|
||||
function onPostNoteCreation(event) {
|
||||
var splashes = event.note;
|
||||
if (pixelSplashes)
|
||||
splashes.splash = "pixel-default";
|
||||
}
|
||||
function onPostNoteCreation(event) if (pixelSplashes)
|
||||
event.note.splash = "pixel-default";
|
||||
|
||||
function onStrumCreation(event) {
|
||||
if (event.player == 1 && !pixelNotesForBF) return;
|
||||
if (event.player == 0 && !pixelNotesForDad) return;
|
||||
|
||||
if ((event.player == 1 && !pixelNotesForBF) || (event.player == 0 && !pixelNotesForDad)) return;
|
||||
event.cancel();
|
||||
|
||||
var strum = event.strum;
|
||||
strum.loadGraphic(Paths.image('stages/school/ui/arrows-pixels'), true, 17, 17);
|
||||
strum.animation.add("static", [event.strumID]);
|
||||
strum.animation.add("pressed", [4 + event.strumID, 8 + event.strumID], 12, false);
|
||||
strum.animation.add("confirm", [12 + event.strumID, 16 + event.strumID], 24, false);
|
||||
var maxCol = Math.floor(strum.graphic.width / 17);
|
||||
var strumID = event.strumID % maxCol;
|
||||
|
||||
strum.scale.set(daPixelZoom, daPixelZoom);
|
||||
strum.animation.add("static", [strumID]);
|
||||
strum.animation.add("pressed", [maxCol + strumID, (maxCol*2) + strumID], 12, false);
|
||||
strum.animation.add("confirm", [(maxCol*3) + strumID, (maxCol*4) + strumID], 24, false);
|
||||
|
||||
var strumScale = strumLines.members[event.player].strumScale;
|
||||
strum.scale.set(daPixelZoom*strumScale, daPixelZoom*strumScale);
|
||||
strum.updateHitbox();
|
||||
strum.antialiasing = false;
|
||||
}
|
||||
|
||||
function onCountdown(event) {
|
||||
@@ -86,9 +89,9 @@ function onPlayerHit(event:NoteHitEvent) {
|
||||
* CAMERA HACKS!!
|
||||
*/
|
||||
function postCreate() {
|
||||
if (enablePauseMenu) {
|
||||
if (enablePauseMenu)
|
||||
PauseSubState.script = 'data/scripts/week6-pause';
|
||||
}
|
||||
|
||||
if (enableCameraHacks) {
|
||||
camGame.pixelPerfectRender = true;
|
||||
camGame.antialiasing = false;
|
||||
@@ -97,9 +100,6 @@ function postCreate() {
|
||||
defaultCamZoom /= daPixelZoom;
|
||||
}
|
||||
|
||||
iconP1.antialiasing = false;
|
||||
iconP2.antialiasing = false;
|
||||
|
||||
if (enablePixelGameOver) {
|
||||
gameOverSong = "pixel/gameOver";
|
||||
lossSFX = "pixel/gameOverSFX";
|
||||
@@ -107,8 +107,8 @@ function postCreate() {
|
||||
}
|
||||
}
|
||||
|
||||
function onStartCountdown() {
|
||||
/*var newNoteCamera = new HudCamera();
|
||||
/*function onStartCountdown() {
|
||||
var newNoteCamera = new HudCamera();
|
||||
newNoteCamera.bgColor = 0; // transparent
|
||||
FlxG.cameras.add(newNoteCamera, false);
|
||||
|
||||
@@ -122,8 +122,8 @@ function onStartCountdown() {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
makeCameraPixely(newNoteCamera);*/
|
||||
}
|
||||
makeCameraPixely(newNoteCamera);
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Use this to make any camera pixelly (you wont be able to zoom with it anymore!)
|
||||
@@ -148,33 +148,29 @@ function destroy() {
|
||||
FlxG.game.stage.quality = oldStageQuality;
|
||||
}
|
||||
|
||||
function pixelCam(cam) {
|
||||
function pixelCam(cam)
|
||||
makeCameraPixely(cam);
|
||||
}
|
||||
|
||||
var pixellyCameras = [];
|
||||
var pixellyShaders = [];
|
||||
|
||||
function postUpdate(elapsed) {
|
||||
for(e in pixellyCameras) {
|
||||
if (Std.isOfType(e, HudCamera))
|
||||
e.downscroll = camHUD.downscroll;
|
||||
}
|
||||
if (enableCameraHacks) {
|
||||
for(p in strumLines)
|
||||
p.notes.forEach(function(n) {
|
||||
if(n.isSustainNote) return; // hacky fix for hold
|
||||
n.y -= n.y % daPixelZoom;
|
||||
n.x -= n.x % daPixelZoom;
|
||||
});
|
||||
function postUpdate() {
|
||||
for (e in pixellyCameras) if (Std.isOfType(e, HudCamera))
|
||||
e.downscroll = camHUD.downscroll;
|
||||
|
||||
if (enableCameraHacks) for (p in strumLines) {
|
||||
p.notes.forEach(function(n) {
|
||||
if(n.isSustainNote) return; // hacky fix for hold
|
||||
n.y -= n.y % daPixelZoom;
|
||||
n.x -= n.x % daPixelZoom;
|
||||
});
|
||||
}
|
||||
|
||||
var zoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y);
|
||||
for(e in pixellyCameras) {
|
||||
for (e in pixellyCameras) {
|
||||
if (!e.exists) continue;
|
||||
e.zoom = zoom;
|
||||
}
|
||||
for(e in pixellyShaders) {
|
||||
for (e in pixellyShaders)
|
||||
e.pixelZoom = zoom;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import flixel.text.FlxText;
|
||||
import flixel.text.FlxTextBorderStyle;
|
||||
import flixel.util.FlxAxes;
|
||||
|
||||
var pixelScript:Script;
|
||||
var pixelScript:Script = game.scripts.getByName("pixel.hx");
|
||||
var pauseCam = new FlxCamera();
|
||||
|
||||
var bg:FlxSprite;
|
||||
@@ -19,47 +19,40 @@ function create(event) {
|
||||
|
||||
event.music = isThorns ? "pixel/LunchboxScary" : "pixel/breakfast";
|
||||
|
||||
cameras = [];
|
||||
|
||||
pixelScript = game.scripts.getByName("pixel.hx");
|
||||
pixelScript.call("pixelCam", [pauseCam]);
|
||||
// allowing this pause script even if the pixel script is not loaded - Nex
|
||||
pixelScript?.call("pixelCam", [pauseCam]);
|
||||
|
||||
FlxG.cameras.add(pauseCam, false);
|
||||
cameras = [pauseCam];
|
||||
|
||||
pauseCam.bgColor = isThorns ? 0x88000000 : 0x88FF99CC;
|
||||
pauseCam.alpha = 0;
|
||||
|
||||
bg = new FlxSprite(44 * 6, 14 * 6);
|
||||
bg.loadGraphic(Paths.image('stages/school/pause/bg'));
|
||||
if (isThorns)
|
||||
bg.color = 0xFF000000;
|
||||
bg = new FlxSprite(44 * 6, 14 * 6, Paths.image('stages/school/pause/bg'));
|
||||
bg.antialiasing = false;
|
||||
if (isThorns) bg.color = 0xFF000000;
|
||||
bg.scale.set(6, 6);
|
||||
bg.updateHitbox();
|
||||
bg.scale.y = 4;
|
||||
bg.cameras = [pauseCam];
|
||||
add(bg);
|
||||
|
||||
songText = new FlxText(0, 22 * 6, 0, "Pause", 8, false);
|
||||
confText(songText);
|
||||
add(songText);
|
||||
|
||||
var i = 2;
|
||||
for(e in menuItems) {
|
||||
text = new FlxText(0, (22 * 6) + (i * 9 * 6), 0, e, 8, false);
|
||||
for (i=>e in menuItems) {
|
||||
text = new FlxText(0, (22 * 6) + ((i+2) * 9 * 6), 0, e, 8, false);
|
||||
confText(text);
|
||||
add(text);
|
||||
texts.push(text);
|
||||
i++;
|
||||
}
|
||||
|
||||
hand = new FlxSprite().loadGraphic(Paths.image('stages/school/ui/hand_textbox'));
|
||||
hand.antialiasing = false;
|
||||
hand.scale.set(6, 6);
|
||||
hand.updateHitbox();
|
||||
add(hand);
|
||||
|
||||
FlxTween.tween(bg, {"scale.y": 6}, 0.75, {ease: FlxEase.elasticOut});
|
||||
FlxTween.tween(bg.scale, {y: 6}, 0.75, {ease: FlxEase.elasticOut});
|
||||
|
||||
cameras = [pauseCam];
|
||||
|
||||
FlxG.sound.play(Paths.sound(isThorns ? 'pixel/ANGRY' : 'pixel/clickText'));
|
||||
}
|
||||
@@ -70,55 +63,50 @@ function confText(text) {
|
||||
text.screenCenter(FlxAxes.X);
|
||||
text.borderStyle = FlxTextBorderStyle.OUTLINE;
|
||||
if (!isThorns) text.borderColor = 0xFF953E3E;
|
||||
|
||||
text.antialiasing = false;
|
||||
texts.push(text);
|
||||
add(text);
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
if(FlxG.cameras.list.contains(pauseCam))
|
||||
FlxG.cameras.remove(pauseCam);
|
||||
}
|
||||
function destroy() if (FlxG.cameras.list.contains(pauseCam))
|
||||
FlxG.cameras.remove(pauseCam);
|
||||
|
||||
var canDoShit = true;
|
||||
var time:Float = 0;
|
||||
function update(elapsed) {
|
||||
pixelScript.call("postUpdate", [elapsed]);
|
||||
pixelScript?.call("postUpdate", [elapsed]);
|
||||
|
||||
pauseCam.alpha = lerp(pauseCam.alpha, 1, 0.25);
|
||||
time += elapsed;
|
||||
|
||||
var curText = texts[curSelected];
|
||||
var curText = texts[curSelected + 1];
|
||||
hand.setPosition(curText.x - hand.width - 18 + (Math.sin(time * Math.PI * 2) * 12), curText.y + (text.height - hand.height) - 6);
|
||||
hand.x -= hand.x % 6;
|
||||
hand.y -= hand.y % 6;
|
||||
|
||||
if (!canDoShit) return;
|
||||
var oldSec = curSelected;
|
||||
|
||||
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0) - FlxG.mouse.wheel);
|
||||
|
||||
if (oldSec != curSelected)
|
||||
FlxG.sound.play(Paths.sound(isThorns ? 'pixel/type' : 'pixel/pixelText'));
|
||||
if (controls.ACCEPT) enterOption();
|
||||
}
|
||||
|
||||
if (controls.ACCEPT) {
|
||||
FlxG.sound.play(Paths.sound(isThorns ? 'pixel/ANGRY' : 'pixel/clickText'));
|
||||
var option = menuItems[curSelected];
|
||||
if (option == "Resume" || option == "Exit to menu") {
|
||||
var scrollSFX = FlxG.sound.load(Paths.sound(isThorns ? 'pixel/type' : 'pixel/pixelText'));
|
||||
function changeSelection(change) if (canDoShit) { // this overrides the function inside of the normal pause btw, so no event gets called - Nex
|
||||
curSelected = FlxMath.wrap(curSelected + change, 0, menuItems.length - 1);
|
||||
if (change != 0) scrollSFX.play();
|
||||
}
|
||||
|
||||
var enterSFX = FlxG.sound.load(Paths.sound(isThorns ? 'pixel/ANGRY' : 'pixel/clickText'));
|
||||
function enterOption() if (canDoShit) {
|
||||
var option = menuItems[curSelected];
|
||||
enterSFX.play();
|
||||
|
||||
switch(option) {
|
||||
case "Resume", "Exit to menu":
|
||||
canDoShit = false;
|
||||
for(t in texts) t.visible = false;
|
||||
hand.visible = songText.visible = false;
|
||||
FlxTween.tween(bg, {"scale.y": 0}, 0.125, {ease: FlxEase.cubeOut, onComplete: function() {
|
||||
selectOption();
|
||||
}});
|
||||
} else {
|
||||
selectOption();
|
||||
}
|
||||
FlxTween.tween(bg.scale, {y: 0}, 0.125, {ease: FlxEase.cubeOut, onComplete: selectOption});
|
||||
default: selectOption();
|
||||
}
|
||||
}
|
||||
|
||||
function changeSelection(change) { // this overrides the function inside of the normal pause btw, so no event gets called - Nex
|
||||
curSelected += change;
|
||||
|
||||
if (curSelected < 0)
|
||||
curSelected = menuItems.length - 1;
|
||||
if (curSelected >= menuItems.length)
|
||||
curSelected = 0;
|
||||
}
|
||||
@@ -3,13 +3,7 @@ var sound:Sound;
|
||||
function create()
|
||||
sound = Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, !Options.naughtyness ? [1, 3, 8, 13, 17, 21] : null));
|
||||
|
||||
function beatHit(cur:Int) {
|
||||
if(cur != 0) return;
|
||||
|
||||
function beatHit(cur:Int) if (cur == 0) {
|
||||
FlxG.sound.play(sound, 1, false, null, true, () -> if (!isEnding) FlxG.sound.music.fadeIn(4, 0.2, 1));
|
||||
FlxG.sound.music.volume = 0.2;
|
||||
FlxG.sound.play(sound, 1, false, null, true, function()
|
||||
{
|
||||
if (!isEnding)
|
||||
FlxG.sound.music.fadeIn(4, 0.2, 1);
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
var tankAngle:Float = FlxG.random.int(-90, 45);
|
||||
var tankSpeed:Float = FlxG.random.float(5, 7);
|
||||
|
||||
function postCreate() if(PlayState.isStoryMode)
|
||||
function postCreate() if (PlayState.isStoryMode)
|
||||
GameOverSubstate.script = 'data/scripts/week7-balledLines';
|
||||
|
||||
function update(elapsed:Float) {
|
||||
@@ -12,7 +12,7 @@ function update(elapsed:Float) {
|
||||
}
|
||||
|
||||
function onPostCountdown(event) {
|
||||
if(!playCutscenes || event.sprite == null) return;
|
||||
if (!playCutscenes || event.sprite == null) return;
|
||||
var lastIndex:Int = members.indexOf(event.sprite);
|
||||
remove(event.sprite);
|
||||
insert(lastIndex + 4, event.sprite);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<!-- praying to god we remove this file later on -->
|
||||
|
||||
<stage zoom="0.9" name="stage" folder="stages/default/" startCamPosY="600" startCamPosX="1000" example="value">
|
||||
<sprite name="normBG" sprite="stagefront" x="-500" y="100" scale="0.75" updateHitbox="true" />
|
||||
<sprite name="noUpdateHitbox" sprite="stagefront" x="-500" y="300" scale="0.75" />
|
||||
<sprite name="ro-tat-ay" sprite="stagefront" x="-500" y="700" scale="0.75" updateHitbox="true" angle="37" />
|
||||
<box name="box" x="0" y="0" width="200" height="200" color="0xFF0000" />
|
||||
<solid name="box2" x="0" y="300" width="200" height="200" color="0x00FF00" />
|
||||
<unknown-sprite />
|
||||
|
||||
<unknown-sprite-1-attr name="test" />
|
||||
</stage>
|
||||
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* THIS FILE IS TEMPORARY UNTIL TRANSFORMS ARE AT A USEABLE STATE.
|
||||
* TODO:
|
||||
* - !!!! MOVE BACK TO SOURCE !!!!
|
||||
* - Rotation
|
||||
* - Skewing
|
||||
* - Angle + Scale (like already at a angle)
|
||||
*/
|
||||
|
||||
import funkin.editors.stage.StageEditor;
|
||||
import funkin.editors.ui.UIWarningSubstate;
|
||||
import funkin.backend.utils.WindowUtils;
|
||||
import funkin.backend.utils.MatrixUtil;
|
||||
import flixel.math.FlxAngle;
|
||||
import openfl.Lib;
|
||||
|
||||
var exID = StageEditor.exID;
|
||||
|
||||
function tryUpdateHitbox(sprite) {
|
||||
var spriteNode = sprite.extra.get(exID("node"));
|
||||
if (spriteNode.exists("updateHitbox") && spriteNode.get("updateHitbox") == "true") {
|
||||
sprite.updateHitbox();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!FlxG.keys.pressed.ALT) {
|
||||
sprite.x = storedPos.x - (sprite.frameWidth * (storedScale.x - sprite.scale.x) * 0.5);
|
||||
sprite.y = storedPos.y - (sprite.frameHeight * (storedScale.y - sprite.scale.y) * 0.5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var allowClose = false;
|
||||
function create() {
|
||||
WindowUtils.preventClosing = true;
|
||||
WindowUtils.resetClosing();
|
||||
WindowUtils.onClosing = function() {
|
||||
if(!allowClose)
|
||||
Lib.application.window.onClose.cancel();
|
||||
|
||||
var substate;
|
||||
substate = new UIWarningSubstate("nuh uh", "you dont need to close goofus doofus", [
|
||||
{
|
||||
label: "Actually Exit",
|
||||
onClick: function(t) {
|
||||
allowClose = true;
|
||||
Lib.application.window.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "Reload State",
|
||||
onClick: function(t) {
|
||||
FlxG.switchState(new StageEditor(StageEditor.__stage));
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "oh whoops",
|
||||
onClick: function(t) {
|
||||
substate.close();
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
openSubState(substate);
|
||||
}
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
WindowUtils.preventClosing = false;
|
||||
WindowUtils.resetClosing();
|
||||
WindowUtils.onClosing = null;
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (FlxG.mouse.justPressed)
|
||||
lastRelative.set();
|
||||
|
||||
if(FlxG.keys.justPressed.R) {
|
||||
trace("reloading");
|
||||
FlxG.switchState(new StageEditor(StageEditor.__stage));
|
||||
}
|
||||
}
|
||||
|
||||
function genericScale(sprite, relative, doX, doY) {
|
||||
|
||||
var relativeMult = 1 / (FlxMath.lerp(1, stageCamera.zoom, sprite.zoomFactor) / stageCamera.zoom) * (FlxG.keys.pressed.ALT ? 2 : 1);
|
||||
relative.x *= relativeMult;
|
||||
relative.y *= relativeMult;
|
||||
|
||||
var width = sprite.frameWidth * storedScale.x;
|
||||
var height = sprite.frameHeight * storedScale.y;
|
||||
if(doX) width -= relative.x;
|
||||
if(doY) height -= relative.y;
|
||||
CoolUtil.setGraphicSizeFloat(sprite, width, height);
|
||||
|
||||
if(FlxG.keys.pressed.SHIFT) {
|
||||
var nscale = Math.max(sprite.scale.x, sprite.scale.y);
|
||||
sprite.scale.set(nscale, nscale);
|
||||
}
|
||||
|
||||
var updatedHitbox = tryUpdateHitbox(sprite);
|
||||
if (FlxG.keys.pressed.ALT) {
|
||||
sprite.x = storedPos.x;
|
||||
sprite.y = storedPos.y;
|
||||
if(updatedHitbox) {
|
||||
sprite.x += (sprite.frameWidth * (storedScale.x - sprite.scale.x) * 0.5);
|
||||
sprite.y += (sprite.frameHeight * (storedScale.y - sprite.scale.y) * 0.5);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return !updatedHitbox;
|
||||
}
|
||||
|
||||
function genericOppositeScale(sprite, relative, scaleX, scaleY, repositionX, repositionY) {
|
||||
if(repositionX) relative.x *= -1;
|
||||
if(repositionY) relative.y *= -1;
|
||||
var repositioned = genericScale(sprite, relative, scaleX, scaleY);
|
||||
if (!repositioned) {
|
||||
if(repositionX) sprite.x = storedPos.x + (sprite.frameWidth * (storedScale.x - sprite.scale.x));
|
||||
if(repositionY) sprite.y = storedPos.y + (sprite.frameHeight * (storedScale.y - sprite.scale.y));
|
||||
} else if (!FlxG.keys.pressed.ALT) {
|
||||
if(repositionX) sprite.x += (sprite.frameWidth * (storedScale.x - sprite.scale.x));
|
||||
if(repositionY) sprite.y += (sprite.frameHeight * (storedScale.y - sprite.scale.y));
|
||||
}
|
||||
}
|
||||
|
||||
var oldSpritePos = FlxPoint.get();
|
||||
function SCALE_BOTTOM_RIGHT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericScale(sprite, relative, true, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
/**
|
||||
ROTATION
|
||||
**/
|
||||
function preRotBullshit(sprite, relative) {
|
||||
if (sprite.angle != 0)
|
||||
relative = rotateByDegrees(relative, -sprite.angle);
|
||||
|
||||
if (FlxG.mouse.justPressed) {
|
||||
oldSpritePos.x = sprite.x;
|
||||
oldSpritePos.y = sprite.y;
|
||||
}
|
||||
}
|
||||
|
||||
function postRotBullshit(sprite, relative) {
|
||||
if (sprite.angle != 0) {
|
||||
var p = rotateAround(FlxPoint.get(sprite.x, sprite.y), oldSpritePos, sprite.angle);
|
||||
sprite.x = p.x;
|
||||
sprite.y = p.y;
|
||||
}
|
||||
}
|
||||
|
||||
function rotateAround(p, origin, angle) {
|
||||
var rel = FlxPoint.get(p.x - origin.x, p.y - origin.y);
|
||||
rotateByDegrees(rel, angle);
|
||||
p.x = origin.x + rel.x;
|
||||
p.y = origin.y + rel.y;
|
||||
rel.put();
|
||||
return p;
|
||||
}
|
||||
function rotateByDegrees(p, angle) {
|
||||
var rads = angle * FlxAngle.TO_RAD;
|
||||
var s:Float = Math.sin(rads);
|
||||
var c:Float = Math.cos(rads);
|
||||
var tempX:Float = p.x;
|
||||
|
||||
p.x = tempX * c - p.y * s;
|
||||
p.y = tempX * s + p.y * c;
|
||||
}
|
||||
/**
|
||||
END OF ROTATION
|
||||
**/
|
||||
|
||||
|
||||
function SCALE_TOP_RIGHT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericOppositeScale(sprite, relative, true, true, false, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function MOVE_CENTER(sprite, relative) {
|
||||
sprite.x = storedPos.x-relative.x;
|
||||
sprite.y = storedPos.y-relative.y;
|
||||
}
|
||||
|
||||
function SCALE_TOP_LEFT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericOppositeScale(sprite, relative, true, true, true, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function SCALE_BOTTOM_LEFT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericOppositeScale(sprite, relative, true, true, true, false);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function SCALE_LEFT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericOppositeScale(sprite, relative, true, false, true, false);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function SCALE_RIGHT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericScale(sprite, relative, true, false);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function SCALE_TOP(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericOppositeScale(sprite, relative, false, true, false, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
function SCALE_BOTTOM(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
genericScale(sprite, relative, false, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
var lastRelative = FlxPoint.get();
|
||||
var skewPoint1 = FlxPoint.get();
|
||||
var skewPoint2 = FlxPoint.get();
|
||||
|
||||
function SKEW_LEFT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
if (!FlxG.keys.pressed.SHIFT) {
|
||||
genericOppositeScale(sprite, relative, true, false, true, false);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
skewPoint1.set(0, 0);
|
||||
skewPoint2.set(1, 0);
|
||||
gimmeSkewCorners(sprite, 0, 1);
|
||||
|
||||
sprite.y = storedPos.y - relative.y * 0.5;
|
||||
sprite.skew.y += ((relative.y - lastRelative.y) * 0.02);
|
||||
|
||||
lastRelative.set((FlxG.keys.pressed.SHIFT ? lastRelative.x : relative.x), relative.y);
|
||||
}
|
||||
|
||||
function SKEW_BOTTOM(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
if (!FlxG.keys.pressed.SHIFT) {
|
||||
genericScale(sprite, relative, false, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
skewPoint1.set(0, 0);
|
||||
skewPoint2.set(0, 1);
|
||||
gimmeSkewCorners(sprite, 0, 2);
|
||||
|
||||
sprite.x = storedPos.x - relative.x * 0.4;
|
||||
sprite.skew.x -= ((relative.x - lastRelative.x) * 0.03);
|
||||
|
||||
lastRelative.set(relative.x, (FlxG.keys.pressed.SHIFT ? lastRelative.y : relative.y));
|
||||
}
|
||||
|
||||
function SKEW_TOP(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
if (!FlxG.keys.pressed.SHIFT) {
|
||||
genericOppositeScale(sprite, relative, false, true, false, true);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
skewPoint1.set(0, 0);
|
||||
skewPoint2.set(0, 1);
|
||||
gimmeSkewCorners(sprite, 0, 2);
|
||||
|
||||
sprite.x = storedPos.x - relative.x * 0.4;
|
||||
sprite.skew.x += ((relative.x - lastRelative.x) * 0.03);
|
||||
|
||||
lastRelative.set(relative.x, (FlxG.keys.pressed.SHIFT ? lastRelative.y : relative.y));
|
||||
}
|
||||
|
||||
function SKEW_RIGHT(sprite, relative) {
|
||||
preRotBullshit(sprite, relative);
|
||||
if (!FlxG.keys.pressed.SHIFT) {
|
||||
genericScale(sprite, relative, true, false);
|
||||
postRotBullshit(sprite, relative);
|
||||
}
|
||||
|
||||
skewPoint1.set(0, 0);
|
||||
skewPoint2.set(1, 0);
|
||||
gimmeSkewCorners(sprite, 0, 1);
|
||||
|
||||
sprite.y = storedPos.y - relative.y * 0.5;
|
||||
sprite.skew.y -= ((relative.y - lastRelative.y) * 0.02);
|
||||
|
||||
lastRelative.set((FlxG.keys.pressed.SHIFT ? lastRelative.x : relative.x), relative.y);
|
||||
}
|
||||
|
||||
function ROTATE(sprite, relative) {
|
||||
var buttonBoxes:Array<FlxPoint> = sprite.extra.get(exID("buttonBoxes"));
|
||||
var p:FlxPoint = buttonBoxes[8];
|
||||
|
||||
FlxG.mouse.getWorldPosition(stageCamera, _point);
|
||||
|
||||
var dx:Float = _point.x - p.x;
|
||||
var dy:Float = _point.y - p.y;
|
||||
var angle = FlxAngle.angleFromOrigin(dx, dy, true) + angleOffset;
|
||||
if(FlxG.keys.pressed.SHIFT) angle = Std.int(angle / 45) * 45;
|
||||
sprite.angle = angle;
|
||||
}
|
||||
|
||||
|
||||
/*function postDraw() {
|
||||
if(storedCenter.x != 0 || storedCenter.y != 0) {
|
||||
drawLine(storedCenter, storedRelative, 0.3);
|
||||
}
|
||||
}*/
|
||||
|
||||
function gimmeSkewCorners(sprite, index1, index2) {
|
||||
if (sprite.angle == 0) {
|
||||
var corners = sprite.extra.get(exID("buttonBoxes"));
|
||||
skewPoint1.set(corners[index1].x, corners[index1].y);
|
||||
skewPoint2.set(corners[index2].x, corners[index2].y);
|
||||
return;
|
||||
}
|
||||
|
||||
var ogAngle = sprite.angle;
|
||||
sprite.angle = 0;
|
||||
MatrixUtil.getMatrixPosition(sprite, [skewPoint1, skewPoint2], sprite.camera, sprite.frameWidth, sprite.frameHeight);
|
||||
sprite.angle = ogAngle;
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
<!DOCTYPE codename-engine-week-character>
|
||||
<char scale="0.5" x="80" y="-50"/>
|
||||
<char scale="0.5" x="80" y="-50" beatInterval="1"/>
|
||||
|
Before Width: | Height: | Size: 978 KiB After Width: | Height: | Size: 960 KiB |
|
Before Width: | Height: | Size: 459 KiB After Width: | Height: | Size: 456 KiB |
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 488 KiB After Width: | Height: | Size: 481 KiB |
|
Before Width: | Height: | Size: 579 KiB After Width: | Height: | Size: 562 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 993 KiB After Width: | Height: | Size: 972 KiB |
|
Before Width: | Height: | Size: 792 KiB After Width: | Height: | Size: 779 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 4.4 MiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 946 KiB After Width: | Height: | Size: 932 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 394 KiB After Width: | Height: | Size: 390 KiB |
|
Before Width: | Height: | Size: 652 KiB After Width: | Height: | Size: 630 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 271 KiB |
|
Before Width: | Height: | Size: 130 B After Width: | Height: | Size: 117 B |
|
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 250 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 460 KiB After Width: | Height: | Size: 457 KiB |
|
After Width: | Height: | Size: 362 B |
|
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 190 B |
|
Before Width: | Height: | Size: 215 B |
|
After Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 158 B |
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 131 B |
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 639 B After Width: | Height: | Size: 618 B |
|
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 177 B |
|
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 166 B |
|
After Width: | Height: | Size: 112 B |
|
Before Width: | Height: | Size: 139 B After Width: | Height: | Size: 126 B |