├── settings.gradle
├── html
├── webapp
│ ├── soundmanager2-setup.js
│ ├── WEB-INF
│ │ └── web.xml
│ ├── refresh.png
│ ├── styles.css
│ ├── index.html
│ └── soundmanager2-jsmin.js
├── src
│ └── io
│ │ └── piotrjastrzebski
│ │ └── dungen
│ │ ├── GdxDefinition.gwt.xml
│ │ ├── GdxDefinitionSuperdev.gwt.xml
│ │ └── client
│ │ └── HtmlLauncher.java
└── build.gradle
├── core
├── assets
│ ├── ss-v1.png
│ ├── ss-v2.png
│ └── badlogic.jpg
├── build.gradle
└── src
│ ├── Dungen.gwt.xml
│ └── io
│ └── piotrjastrzebski
│ └── dungen
│ ├── gui
│ ├── Saver.java
│ ├── Restarter.java
│ ├── HelpGUI.java
│ ├── DrawSettingsGUI.java
│ └── GenSettingsGUI.java
│ ├── PlatformBridge.java
│ ├── DungenGame.java
│ ├── Grid.java
│ ├── RoomNode.java
│ ├── RoomEdge.java
│ ├── Utils.java
│ ├── DrawSettings.java
│ ├── Room.java
│ ├── RoomGraph.java
│ ├── HallwayPath.java
│ ├── GenSettings.java
│ ├── BaseScreen.java
│ ├── DungenScreen.java
│ └── DungeonGenerator.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── CONTRIBUTORS
├── AUTHORS
├── README.md
├── .gitignore
├── desktop
├── build.gradle
└── src
│ └── io
│ └── piotrjastrzebski
│ └── dungen
│ └── desktop
│ └── DesktopLauncher.java
├── gradlew.bat
├── gradlew
└── LICENSE
/settings.gradle:
--------------------------------------------------------------------------------
1 | include 'desktop', 'html', 'core'
--------------------------------------------------------------------------------
/html/webapp/soundmanager2-setup.js:
--------------------------------------------------------------------------------
1 | window.SM2_DEFER = true;
--------------------------------------------------------------------------------
/html/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/core/assets/ss-v1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piotr-j/dungen/HEAD/core/assets/ss-v1.png
--------------------------------------------------------------------------------
/core/assets/ss-v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piotr-j/dungen/HEAD/core/assets/ss-v2.png
--------------------------------------------------------------------------------
/core/assets/badlogic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piotr-j/dungen/HEAD/core/assets/badlogic.jpg
--------------------------------------------------------------------------------
/html/webapp/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piotr-j/dungen/HEAD/html/webapp/refresh.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.daemon=true
2 | org.gradle.jvmargs=-Xms128m -Xmx512m
3 | org.gradle.configureondemand=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piotr-j/dungen/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | # This is the official list of people who can contribute
2 | # (and who have contributed) code to the Dungen project
3 | # repository.
4 | # The AUTHORS file lists the copyright holders; this file
5 | # lists people.
6 | #
7 | Piotr Jastrzębski
8 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | # This is the official list of the AUTHORS of Dungen
2 | # for copyright purposes.
3 | # This file is distinct from the CONTRIBUTORS files.
4 | # See the latter for an explanation.
5 |
6 | # Names should be added to this file as
7 | # Name or Organization
8 | # The email address is not required for organizations.
9 |
10 | Piotr Jastrzębski
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dungeon generator
2 |
3 | ## Features
4 | - A lot of settings.
5 | - Toggles for visualization
6 | - Json export
7 |
8 | ## Inspiration
9 |
10 | [this reddit post](https://www.reddit.com/r/gamedev/comments/1dlwc4/procedural_dungeon_generation_algorithm_explained/) and [that blog post](https://github.com/adonaac/blog/issues/7)
11 |
12 | ##[Web version](https://piotr-j.github.io/dungen/dungen/)
13 |
14 | 
15 |
16 | ## TODO:
17 | - ???
18 |
19 | ## Build with:
20 | - [libgdx](https://github.com/libgdx/libgdx)
21 | - [VisUI](https://github.com/kotcrab/VisEditor/wiki/VisUI)
22 |
23 | ## License
24 | Dungen is licensed under the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0.html), meaning you
25 | can use it free of charge, without strings attached in commercial and non-commercial projects.
26 |
--------------------------------------------------------------------------------
/core/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | */
17 |
18 | apply plugin: "java"
19 |
20 | sourceCompatibility = 1.7
21 | [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
22 |
23 | sourceSets.main.java.srcDirs = ["src/"]
24 |
25 |
26 | eclipse.project {
27 | name = appName + "-core"
28 | }
29 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2015 See AUTHORS file.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | #
17 |
18 | #Sat Sep 21 13:08:26 CEST 2013
19 | distributionBase=GRADLE_USER_HOME
20 | distributionPath=wrapper/dists
21 | zipStoreBase=GRADLE_USER_HOME
22 | zipStorePath=wrapper/dists
23 | distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip
24 |
--------------------------------------------------------------------------------
/core/src/Dungen.gwt.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Java
2 |
3 | *.class
4 | *.war
5 | *.ear
6 | hs_err_pid*
7 |
8 | ## GWT
9 | war/
10 | html/war/gwt_bree/
11 | html/gwt-unitCache/
12 | .apt_generated/
13 | html/war/WEB-INF/deploy/
14 | html/war/WEB-INF/classes/
15 | .gwt/
16 | gwt-unitCache/
17 | www-test/
18 | .gwt-tmp/
19 |
20 | ## Android Studio and Intellij and Android in general
21 | android/libs/armeabi/
22 | android/libs/armeabi-v7a/
23 | android/libs/x86/
24 | android/gen/
25 | .idea/
26 | *.ipr
27 | *.iws
28 | *.iml
29 | out/
30 | com_crashlytics_export_strings.xml
31 |
32 | ## Eclipse
33 | .classpath
34 | .project
35 | .metadata
36 | **/bin/
37 | tmp/
38 | *.tmp
39 | *.bak
40 | *.swp
41 | *~.nib
42 | local.properties
43 | .settings/
44 | .loadpath
45 | .externalToolBuilders/
46 | *.launch
47 |
48 | ## NetBeans
49 | **/nbproject/private/
50 | build/
51 | nbbuild/
52 | dist/
53 | nbdist/
54 | nbactions.xml
55 | nb-configuration.xml
56 |
57 | ## Gradle
58 |
59 | .gradle
60 | gradle-app.setting
61 |
62 | ## OS Specific
63 | .DS_Store
64 | .log
65 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/gui/Saver.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.gui;
19 |
20 |
21 | /**
22 | * Created by PiotrJ on 10/09/15.
23 | */
24 | public interface Saver {
25 | void save (String name);
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/PlatformBridge.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | /**
21 | * Created by PiotrJ on 28/07/15.
22 | */
23 | public interface PlatformBridge {
24 | float getPixelScaleFactor ();
25 | void save (String name, String data);
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/gui/Restarter.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.gui;
19 |
20 | import io.piotrjastrzebski.dungen.DrawSettings;
21 | import io.piotrjastrzebski.dungen.GenSettings;
22 |
23 | /**
24 | * Created by PiotrJ on 10/09/15.
25 | */
26 | public interface Restarter {
27 | public void restart (GenSettings settings);
28 | public void update (DrawSettings settings);
29 | }
30 |
--------------------------------------------------------------------------------
/html/webapp/styles.css:
--------------------------------------------------------------------------------
1 | canvas {
2 | cursor: default;
3 | outline: none;
4 | }
5 |
6 | body {
7 | background-color: #222222;
8 | }
9 |
10 | .superdev {
11 | color: rgb(37, 37, 37);
12 | text-shadow: 0px 1px 1px rgba(250, 250, 250, 0.1);
13 | font-size: 50pt;
14 | display: block;
15 | position: relative;
16 | text-decoration: none;
17 | background-color: rgb(83, 87, 93);
18 | box-shadow: 0px 3px 0px 0px rgb(34, 34, 34),
19 | 0px 7px 10px 0px rgb(17, 17, 17),
20 | inset 0px 1px 1px 0px rgba(250, 250, 250, .2),
21 | inset 0px -12px 35px 0px rgba(0, 0, 0, .5);
22 | width: 70px;
23 | height: 70px;
24 | border: 0;
25 | border-radius: 35px;
26 | text-align: center;
27 | line-height: 68px;
28 | }
29 |
30 | .superdev:active {
31 | box-shadow: 0px 0px 0px 0px rgb(34, 34, 34),
32 | 0px 3px 7px 0px rgb(17, 17, 17),
33 | inset 0px 1px 1px 0px rgba(250, 250, 250, .2),
34 | inset 0px -10px 35px 5px rgba(0, 0, 0, .5);
35 | background-color: rgb(83, 87, 93);
36 | top: 3px;
37 | color: #fff;
38 | text-shadow: 0px 0px 3px rgb(250, 250, 250);
39 | }
40 |
41 | .superdev:hover {
42 | background-color: rgb(100, 100, 100);
43 | }
44 |
--------------------------------------------------------------------------------
/html/src/io/piotrjastrzebski/dungen/GdxDefinition.gwt.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/html/src/io/piotrjastrzebski/dungen/GdxDefinitionSuperdev.gwt.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/desktop/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "java"
2 |
3 | sourceCompatibility = 1.7
4 | sourceSets.main.java.srcDirs = ["src/"]
5 |
6 | project.ext.mainClassName = "io.piotrjastrzebski.dungen.desktop.DesktopLauncher"
7 | project.ext.assetsDir = new File("../core/assets");
8 |
9 | task run(dependsOn: classes, type: JavaExec) {
10 | main = project.mainClassName
11 | classpath = sourceSets.main.runtimeClasspath
12 | standardInput = System.in
13 | workingDir = project.assetsDir
14 | ignoreExitValue = true
15 | }
16 |
17 | task dist(type: Jar) {
18 | from files(sourceSets.main.output.classesDir)
19 | from files(sourceSets.main.output.resourcesDir)
20 | from { configurations.compile.collect { zipTree(it) } }
21 | from files(project.assetsDir);
22 |
23 | manifest {
24 | attributes 'Main-Class': project.mainClassName
25 | }
26 | }
27 |
28 | dist.dependsOn classes
29 |
30 | eclipse {
31 | project {
32 | name = appName + "-desktop"
33 | linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/core/assets'
34 | }
35 | }
36 |
37 | task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
38 | doLast {
39 | def classpath = new XmlParser().parse(file(".classpath"))
40 | new Node(classpath, "classpathentry", [kind: 'src', path: 'assets']);
41 | def writer = new FileWriter(file(".classpath"))
42 | def printer = new XmlNodePrinter(new PrintWriter(writer))
43 | printer.setPreserveWhitespace(true)
44 | printer.print(classpath)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/html/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dungen - simple dungeon generator
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
34 |
38 |
44 |
45 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/DungenGame.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.Game;
21 | import com.kotcrab.vis.ui.VisUI;
22 |
23 | public class DungenGame extends Game {
24 | // 'target' resolution
25 | public final static int WIDTH = 1280;
26 | public final static int HEIGHT = 720;
27 | public final static float SCALE = 32f;
28 | public final static float INV_SCALE = 1.f / SCALE;
29 | public final static float VP_WIDTH = WIDTH * INV_SCALE;
30 | public final static float VP_HEIGHT = HEIGHT * INV_SCALE;
31 |
32 | protected PlatformBridge bridge;
33 | public DungenGame (PlatformBridge bridge) {
34 | this.bridge = bridge;
35 | }
36 |
37 | @Override public void create () {
38 | if (bridge.getPixelScaleFactor() > 1.5f) {
39 | VisUI.load(VisUI.SkinScale.X2);
40 | } else {
41 | VisUI.load(VisUI.SkinScale.X1);
42 | }
43 | setScreen(new DungenScreen(this));
44 | }
45 |
46 | @Override public void dispose () {
47 | super.dispose();
48 | VisUI.dispose();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/desktop/src/io/piotrjastrzebski/dungen/desktop/DesktopLauncher.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.desktop;
19 |
20 | import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
21 | import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
22 | import io.piotrjastrzebski.dungen.DungenGame;
23 | import io.piotrjastrzebski.dungen.PlatformBridge;
24 | import org.lwjgl.opengl.Display;
25 |
26 | public class DesktopLauncher {
27 | public static void main (String[] arg) {
28 | LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
29 | config.width = DungenGame.WIDTH;
30 | config.height = DungenGame.HEIGHT;
31 | config.useHDPI = true;
32 | config.samples = 4;
33 | new LwjglApplication(new DungenGame(new DesktopBridge()), config);
34 | }
35 |
36 | public static class DesktopBridge implements PlatformBridge {
37 | @Override public float getPixelScaleFactor () {
38 | return Display.getPixelScaleFactor();
39 | }
40 |
41 | @Override public void save (String name, String data) {
42 |
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/html/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "java"
2 | apply plugin: "jetty"
3 |
4 | gwt {
5 | gwtVersion = '2.6.0' // Should match the gwt version used for building the gwt backend
6 | maxHeapSize = "1G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY
7 | minHeapSize = "1G"
8 |
9 | src = files(file("src/")) // Needs to be in front of "modules" below.
10 | modules 'io.piotrjastrzebski.dungen.GdxDefinition'
11 | devModules 'io.piotrjastrzebski.dungen.GdxDefinitionSuperdev'
12 | project.webAppDirName = 'webapp'
13 |
14 | compiler {
15 | strict = true;
16 | enableClosureCompiler = true;
17 | disableCastChecking = true;
18 | }
19 | }
20 |
21 | task draftRun(type: JettyRunWar) {
22 | dependsOn draftWar
23 | dependsOn.remove('war')
24 | webApp = draftWar.archivePath
25 | daemon = true
26 | }
27 |
28 | task superDev(type: de.richsource.gradle.plugins.gwt.GwtSuperDev) {
29 | dependsOn draftRun
30 | doFirst {
31 | gwt.modules = gwt.devModules
32 | }
33 | }
34 |
35 | task dist(dependsOn: [clean, compileGwt]) {
36 | doLast {
37 | file("build/dist").mkdirs()
38 | copy {
39 | from "build/gwt/out"
40 | into "build/dist"
41 | }
42 | copy {
43 | from "webapp"
44 | into "build/dist"
45 | }
46 | copy {
47 | from "war"
48 | into "build/dist"
49 | }
50 | }
51 | }
52 |
53 | draftWar {
54 | from "war"
55 | }
56 |
57 | task addSource << {
58 | sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs)
59 | }
60 |
61 | tasks.compileGwt.dependsOn(addSource)
62 | tasks.draftCompileGwt.dependsOn(addSource)
63 |
64 | sourceCompatibility = 1.7
65 | sourceSets.main.java.srcDirs = ["src/"]
66 |
67 |
68 | eclipse.project {
69 | name = appName + "-html"
70 | }
71 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/Grid.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.graphics.Color;
21 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
22 |
23 | /**
24 | * Created by PiotrJ on 04/09/15.
25 | */
26 | public class Grid {
27 | float size;
28 | float w, h;
29 | Color color = new Color(0.25f, 0.25f, 0.25f, 1f);
30 |
31 | public void render (ShapeRenderer renderer) {
32 | renderer.setColor(color);
33 | int hSegments = (int)(w / size);
34 | for (int i = 0; i < hSegments / 2; i++) {
35 | float x = i * size;
36 | renderer.line(x, -h / 2, x, h / 2);
37 | renderer.line(-x, -h / 2, -x, h / 2);
38 | }
39 | int vSegments = (int)(h / size);
40 | for (int i = 0; i < vSegments / 2; i++) {
41 | float y = i * size;
42 | renderer.line(-w / 2, y, w / 2, y);
43 | renderer.line(-w / 2, -y, w / 2, -y);
44 | }
45 | }
46 |
47 | public Grid setSize (float size) {
48 | this.size = size;
49 | return this;
50 | }
51 |
52 | public Grid setColor (float r, float g, float b, float a) {
53 | this.color.set(r, g, b, a);
54 | return this;
55 | }
56 |
57 | public void resize (int width, int height) {
58 | w = width;
59 | h = height;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/gui/HelpGUI.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.gui;
19 |
20 | import com.badlogic.gdx.Gdx;
21 | import com.badlogic.gdx.scenes.scene2d.InputEvent;
22 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
23 | import com.kotcrab.vis.ui.widget.*;
24 |
25 | public class HelpGUI extends VisDialog {
26 |
27 | public HelpGUI () {
28 | super("HALP!");
29 | addCloseButton();
30 | closeOnEscape();
31 | setModal(true);
32 | VisTable c = new VisTable(true);
33 | c.add(new VisLabel("Welcome to Dungen!")).row();
34 | VisLabel link = new VisLabel("View this project on github!");
35 | link.setColor(0.2f, 0.4f, 1, 1);
36 | link.addListener(new ClickListener(){
37 | @Override public void clicked (InputEvent event, float x, float y) {
38 | Gdx.net.openURI("https://github.com/piotr-j/dungen");
39 | }
40 | });
41 | c.add(link).row();
42 | c.add(new VisLabel("Setting panels are movable")).row();
43 | c.add().row();
44 | c.add(new VisLabel("WSAD/arrows to pan view")).row();
45 | c.add(new VisLabel("Left click and drag to pan view")).row();
46 | c.add(new VisLabel("Q/E to zoom in/out")).row();
47 | c.add(new VisLabel("Scroll to zoom in/out")).row();
48 | c.add(new VisLabel("Space to restart")).row();
49 | c.add(new VisLabel("ESC to dismiss this dialog")).row();
50 | add(c);
51 | pack();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/RoomNode.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.utils.Array;
21 |
22 | /**
23 | * Created by PiotrJ on 03/09/15.
24 | */
25 | public class RoomNode {
26 | public Room room;
27 | public Array edges = new Array<>();
28 |
29 | public void add (Room add) {
30 | RoomEdge edge = new RoomEdge();
31 | edge.roomA = room;
32 | edge.roomB = add;
33 | edges.add(edge);
34 | }
35 |
36 | public void add (RoomEdge add) {
37 | RoomEdge edge = new RoomEdge();
38 | if (add.roomA == room) {
39 | edge.roomA = add.roomA;
40 | edge.roomB = add.roomB;
41 | } else {
42 | edge.roomA = add.roomB;
43 | edge.roomB = add.roomA;
44 | }
45 | edges.add(edge);
46 | }
47 |
48 | @Override public boolean equals (Object o) {
49 | if (this == o)
50 | return true;
51 | if (o == null || getClass() != o.getClass())
52 | return false;
53 |
54 | RoomNode roomNode = (RoomNode)o;
55 |
56 | if (room != null ? !room.equals(roomNode.room) : roomNode.room != null)
57 | return false;
58 | return !(edges != null ? !edges.equals(roomNode.edges) : roomNode.edges != null);
59 |
60 | }
61 |
62 | @Override public int hashCode () {
63 | int result = room != null ? room.hashCode() : 0;
64 | result = 31 * result + (edges != null ? edges.hashCode() : 0);
65 | return result;
66 | }
67 |
68 | @Override public String toString () {
69 | return "RoomNode{" +
70 | "room=" + room +
71 | '}';
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/RoomEdge.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.math.Vector2;
21 |
22 | /**
23 | * Created by PiotrJ on 03/09/15.
24 | */
25 | public class RoomEdge {
26 | private static Vector2 tmp = new Vector2();
27 | public Room roomA;
28 | public Room roomB;
29 | public float len;
30 | public boolean mst;
31 | public boolean recon;
32 |
33 | public void set (Room roomA, Room roomB) {
34 | this.roomA = roomA;
35 | this.roomB = roomB;
36 | len = tmp.set(roomA.cx(), roomA.cy()).sub(roomB.cx(), roomB.cy()).len();
37 | }
38 |
39 | public float ax () {
40 | return roomA.cx();
41 | }
42 |
43 | public float ay () {
44 | return roomA.cy();
45 | }
46 |
47 | public float by () {
48 | return roomB.cy();
49 | }
50 |
51 | public float bx () {
52 | return roomB.cx();
53 | }
54 |
55 | @Override public boolean equals (Object o) {
56 | if (this == o)
57 | return true;
58 | if (o == null || getClass() != o.getClass())
59 | return false;
60 |
61 | RoomEdge edge = (RoomEdge)o;
62 | if (edge.roomA == roomA && edge.roomB == roomB)
63 | return true;
64 | if (edge.roomA == roomB && edge.roomB == roomA)
65 | return true;
66 | return false;
67 | }
68 |
69 | @Override public int hashCode () {
70 | int result = roomA != null ? roomA.hashCode() : 0;
71 | result = 31 * result + (roomB != null ? roomB.hashCode() : 0);
72 | result = 31 * result + (len != +0.0f ? Float.floatToIntBits(len) : 0);
73 | return result;
74 | }
75 |
76 | @Override public String toString () {
77 | return "RoomEdge{" +
78 | "roomA=" + roomA +
79 | ", roomB=" + roomB +
80 | ", mst=" + mst +
81 | '}';
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/Utils.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.math.MathUtils;
21 | import com.badlogic.gdx.math.Vector2;
22 | import com.badlogic.gdx.utils.TimeUtils;
23 |
24 | import java.util.Random;
25 |
26 | /**
27 | * Created by PiotrJ on 04/09/15.
28 | */
29 | public class Utils {
30 |
31 | public static Vector2 pointInCircle (float radius, Vector2 out) {
32 | return pointInEllipse(radius * 2, radius * 2, out);
33 | }
34 |
35 | public static Vector2 pointInEllipse (float width, float height, Vector2 out) {
36 | float t = (float)(MathUtils.random() * Math.PI * 2);
37 | float u = MathUtils.random() + MathUtils.random();
38 | float r = (u > 1) ? (2 - u) : u;
39 | out.set(width * r * MathUtils.cos(t) / 2, height * r * MathUtils.sin(t) / 2);
40 | return out;
41 | }
42 |
43 | public static Vector2 roundedPointInEllipse (float width, float height, float size, Vector2 out) {
44 | Utils.pointInEllipse(width, height, out);
45 | out.x = roundToSize(out.x, size);
46 | out.y = roundToSize(out.y, size);
47 | return out;
48 | }
49 |
50 | public static float roundToSize (float value, float size) {
51 | return ((Math.round(value / size)) * size);
52 | }
53 |
54 | public static Vector2 roundToSize (Vector2 value, float size) {
55 | value.x = roundToSize(value.x, size);
56 | value.y = roundToSize(value.y, size);
57 | return value;
58 | }
59 |
60 | private static Random rng = new Random(TimeUtils.millis());
61 |
62 | public static float rngFloat () {
63 | return (float)(rng.nextGaussian());
64 | }
65 |
66 | public static float rngFloat (float mean) {
67 | return mean + rngFloat();
68 | }
69 | public static float rngFloat (float mean, float scale) {
70 | return mean + rngFloat() * scale;
71 | }
72 |
73 | public static float roundedRngFloat (float mean, float scale, float size) {
74 | return Utils.roundToSize(Utils.rngFloat(mean, scale), size);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/DrawSettings.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | /**
21 | * Created by PiotrJ on 04/09/15.
22 | */
23 | public class DrawSettings {
24 | public boolean drawMinSpanTree;
25 | public boolean drawHallWayPaths;
26 | public boolean drawHallWays;
27 | public boolean drawBodies;
28 | public boolean drawUnused;
29 | public boolean drawMain;
30 | public boolean drawExtra;
31 | public boolean drawEdges;
32 | public boolean drawSpawnArea;
33 |
34 | public DrawSettings () {
35 |
36 | }
37 |
38 | public void copy (DrawSettings o) {
39 | this.drawMinSpanTree = o.drawMinSpanTree;
40 | this.drawHallWayPaths = o.drawHallWayPaths;
41 | this.drawHallWays = o.drawHallWays;
42 | this.drawBodies = o.drawBodies;
43 | this.drawUnused = o.drawUnused;
44 | this.drawMain = o.drawMain;
45 | this.drawExtra = o.drawExtra;
46 | this.drawEdges = o.drawEdges;
47 | this.drawSpawnArea = o.drawSpawnArea;
48 | }
49 |
50 | public DrawSettings setDrawMinSpanTree (boolean drawMinSpanTree) {
51 | this.drawMinSpanTree = drawMinSpanTree;
52 | return this;
53 | }
54 |
55 | public DrawSettings setDrawHallWayPaths (boolean drawHallWayPaths) {
56 | this.drawHallWayPaths = drawHallWayPaths;
57 | return this;
58 | }
59 |
60 | public DrawSettings setDrawHallWays (boolean drawHallWays) {
61 | this.drawHallWays = drawHallWays;
62 | return this;
63 | }
64 |
65 | public DrawSettings setDrawBodies (boolean drawBodies) {
66 | this.drawBodies = drawBodies;
67 | return this;
68 | }
69 |
70 | public DrawSettings setDrawUnused (boolean drawUnused) {
71 | this.drawUnused = drawUnused;
72 | return this;
73 | }
74 |
75 | public DrawSettings setDrawMain (boolean drawMain) {
76 | this.drawMain = drawMain;
77 | return this;
78 | }
79 |
80 | public DrawSettings setDrawExtra (boolean drawExtra) {
81 | this.drawExtra = drawExtra;
82 | return this;
83 | }
84 |
85 | public DrawSettings setDrawEdges (boolean drawEdges) {
86 | this.drawEdges = drawEdges;
87 | return this;
88 | }
89 |
90 | public DrawSettings setDrawSpawnArea (boolean drawSpawnArea) {
91 | this.drawSpawnArea = drawSpawnArea;
92 | return this;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/html/src/io/piotrjastrzebski/dungen/client/HtmlLauncher.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.client;
19 |
20 | import com.badlogic.gdx.ApplicationListener;
21 | import com.badlogic.gdx.Gdx;
22 | import com.badlogic.gdx.backends.gwt.GwtApplication;
23 | import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
24 | import com.badlogic.gdx.utils.Base64Coder;
25 | import com.google.gwt.core.client.GWT;
26 | import com.google.gwt.dom.client.AnchorElement;
27 | import com.google.gwt.dom.client.Document;
28 | import com.google.gwt.dom.client.NativeEvent;
29 | import com.google.gwt.user.client.Window;
30 | import io.piotrjastrzebski.dungen.BaseScreen;
31 | import io.piotrjastrzebski.dungen.DungenGame;
32 | import io.piotrjastrzebski.dungen.PlatformBridge;
33 |
34 | public class HtmlLauncher extends GwtApplication {
35 |
36 | @Override public GwtApplicationConfiguration getConfig () {
37 | GwtApplicationConfiguration config = new GwtApplicationConfiguration(DungenGame.WIDTH,
38 | DungenGame.HEIGHT);
39 | config.antialiasing = true;
40 | return config;
41 | }
42 |
43 | @Override public ApplicationListener getApplicationListener () {
44 | return new DungenGame(new HtmlBridge());
45 | }
46 |
47 | public static class HtmlBridge implements PlatformBridge {
48 | @Override public float getPixelScaleFactor () {
49 | return 1;
50 | }
51 |
52 | @Override public void save (String name, String data) {
53 | String toSave = "data:application/octet-stream;charset=utf-8;base64,";
54 | toSave += Base64Coder.encodeString(data);
55 | toSave+="\n";
56 | dl(name, toSave);
57 | }
58 |
59 | private static native void dl(String filename, String uri)
60 | /*-{
61 | var link = document.createElement('a');
62 | if (typeof link.download === 'string') {
63 | link.href = uri;
64 | link.download = filename;
65 |
66 | //Firefox requires the link to be in the body
67 | document.body.appendChild(link);
68 |
69 | //simulate click
70 | link.click();
71 |
72 | //remove the link when done
73 | document.body.removeChild(link);
74 | } else {
75 | window.open(uri);
76 | }
77 | }-*/;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/Room.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
21 | import com.badlogic.gdx.math.Rectangle;
22 | import com.badlogic.gdx.math.Vector2;
23 | import com.badlogic.gdx.physics.box2d.Body;
24 |
25 | /**
26 | * Created by PiotrJ on 03/09/15.
27 | */
28 | public class Room {
29 | public int id;
30 | public Rectangle bounds = new Rectangle();
31 | public Body body;
32 | public float gridSize;
33 | public boolean isMain;
34 | public boolean isHallway;
35 | public boolean isExtra;
36 |
37 | public Room (int id, float gridSize) {
38 | this.id = id;
39 | this.gridSize = gridSize;
40 | }
41 |
42 | public boolean isUnused() {
43 | return !isMain && !isHallway && !isExtra;
44 | }
45 |
46 | public void update () {
47 | if (body == null)
48 | return;
49 | Vector2 pos = body.getPosition();
50 | bounds.setPosition(Utils.roundToSize(pos.x - bounds.width / 2, gridSize),
51 | Utils.roundToSize(pos.y - bounds.height / 2, gridSize));
52 | }
53 |
54 | public boolean isSleeping () {
55 | if (body == null)
56 | return false;
57 | return !body.isAwake();
58 | }
59 |
60 | public void draw (ShapeRenderer renderer) {
61 | float s = gridSize * 0.16f;
62 | renderer.rect(bounds.x + s, bounds.y + s, bounds.width - 2 * s, bounds.height - 2 * s);
63 | }
64 |
65 | public void set (float x, float y, float w, float h) {
66 | if (w < 0)
67 | w = -w;
68 | if (h < 0)
69 | h = -h;
70 | bounds.set(x, y, w, h);
71 | }
72 |
73 | public float cx () {
74 | return bounds.x + bounds.width / 2;
75 | }
76 |
77 | public float cy () {
78 | return bounds.y + bounds.height / 2;
79 | }
80 |
81 | @Override public String toString () {
82 | return "Room{" +
83 | "id=" + id +
84 | '}';
85 | }
86 |
87 | @Override public boolean equals (Object o) {
88 | if (this == o)
89 | return true;
90 | if (o == null || getClass() != o.getClass())
91 | return false;
92 |
93 | Room room = (Room)o;
94 |
95 | if (id != room.id)
96 | return false;
97 | if (Float.compare(room.gridSize, gridSize) != 0)
98 | return false;
99 | if (isMain != room.isMain)
100 | return false;
101 | if (bounds != null ? !bounds.equals(room.bounds) : room.bounds != null)
102 | return false;
103 | return !(body != null ? !body.equals(room.body) : room.body != null);
104 |
105 | }
106 |
107 | @Override public int hashCode () {
108 | int result = id;
109 | result = 31 * result + (bounds != null ? bounds.hashCode() : 0);
110 | result = 31 * result + (body != null ? body.hashCode() : 0);
111 | result = 31 * result + (gridSize != +0.0f ? Float.floatToIntBits(gridSize) : 0);
112 | result = 31 * result + (isMain ? 1 : 0);
113 | return result;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/RoomGraph.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.graphics.Color;
21 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
22 | import com.badlogic.gdx.utils.Array;
23 | import com.badlogic.gdx.utils.ObjectMap;
24 |
25 | /**
26 | * Created by PiotrJ on 03/09/15.
27 | */
28 | public class RoomGraph {
29 | Array edges = new Array<>();
30 | ObjectMap roomToNode = new ObjectMap<>();
31 | Array nodes = new Array<>();
32 |
33 | public RoomGraph () {
34 | }
35 |
36 | public void add (RoomEdge edge) {
37 | add(edge.roomA, edge.roomB);
38 | }
39 |
40 | public void add (Room roomA, Room roomB) {
41 | RoomEdge edge = new RoomEdge();
42 | edge.set(roomA, roomB);
43 | if (!edges.contains(edge, false)) {
44 | edges.add(edge);
45 | }
46 | addNode(roomA, roomB);
47 | addNode(roomB, roomA);
48 | }
49 |
50 | private void addNode (Room roomA, Room roomB) {
51 | RoomNode nodeA = roomToNode.get(roomA);
52 | if (nodeA == null) {
53 | nodeA = new RoomNode();
54 | nodeA.room = roomA;
55 | roomToNode.put(roomA, nodeA);
56 | nodes.add(nodeA);
57 | }
58 | nodeA.add(roomB);
59 | }
60 |
61 | public void render (ShapeRenderer renderer, boolean drawEdges, boolean mst, float grid) {
62 | if (edges.size == 0)
63 | return;
64 | if (drawEdges) {
65 | for (RoomEdge e : edges) {
66 | renderer.setColor(0, 1, 0, 0.5f);
67 | renderer.rectLine(e.ax(), e.ay(), e.bx(), e.by(), grid * 0.2f);
68 | }
69 | }
70 | if (mst) {
71 | for (RoomEdge e : edges) {
72 | if (e.recon) {
73 | renderer.setColor(Color.ORANGE);
74 | renderer.rectLine(e.ax(), e.ay(), e.bx(), e.by(), grid * 0.4f);
75 | } else if (e.mst) {
76 | renderer.setColor(Color.LIME);
77 | renderer.rectLine(e.ax(), e.ay(), e.bx(), e.by(), grid * 0.4f);
78 | }
79 | }
80 | }
81 | }
82 |
83 | public void clear () {
84 | edges.clear();
85 | roomToNode.clear();
86 | nodes.clear();
87 | }
88 |
89 | public Array getEdges () {
90 | return edges;
91 | }
92 |
93 | Array open = new Array<>();
94 | Array closed = new Array<>();
95 |
96 | public boolean isConnected (RoomEdge edge) {
97 | if (edges.size == 0)
98 | return false;
99 | // find if there is an existing path between edge.roomA and edge.roomB
100 | Room start = edge.roomA;
101 | Room target = edge.roomB;
102 | RoomNode sNode = roomToNode.get(start);
103 | // start not yet in graph
104 | if (sNode == null)
105 | return false;
106 |
107 | closed.clear();
108 | open.clear();
109 | open.add(sNode);
110 | while (open.size > 0) {
111 | RoomNode first = open.get(0);
112 | closed.add(first);
113 | open.removeIndex(0);
114 | for (RoomEdge e : first.edges) {
115 | RoomNode node = roomToNode.get(e.roomB);
116 | if (node.room == target) {
117 | return true;
118 | }
119 | if (!closed.contains(node, true)) {
120 | open.add(node);
121 | }
122 | }
123 | }
124 | return false;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/HallwayPath.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.graphics.Color;
21 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
22 | import com.badlogic.gdx.math.*;
23 | import com.badlogic.gdx.utils.Array;
24 |
25 | /**
26 | * Created by PiotrJ on 03/09/15.
27 | */
28 | public class HallwayPath {
29 | private static int ID = 0;
30 | public int id;
31 | public Vector2 start = new Vector2();
32 | public Vector2 bend = new Vector2();
33 | public Vector2 end = new Vector2();
34 | public Rectangle hallA = new Rectangle();
35 | public Rectangle hallB = new Rectangle();
36 | public boolean hasBend;
37 | public boolean recon;
38 | public int width = 1;
39 | public Room roomA;
40 | public Room roomB;
41 | public Array overlap = new Array<>();
42 | private float gridSize;
43 |
44 | public HallwayPath (float gridSize, int width) {
45 | this.gridSize = gridSize;
46 | this.width = width;
47 | this.id = ID++;
48 | }
49 |
50 | Vector2 tmp = new Vector2();
51 | public void draw (ShapeRenderer renderer) {
52 | if (recon) {
53 | renderer.setColor(Color.ORANGE);
54 | } else {
55 | renderer.setColor(Color.LIME);
56 | }
57 | if (hasBend) {
58 | renderer.rectLine(start.x, start.y, bend.x, bend.y, gridSize * 0.33f);
59 | renderer.rectLine(bend.x, bend.y, end.x, end.y, gridSize * 0.33f);
60 | } else {
61 | renderer.rectLine(start.x, start.y, end.x, end.y, gridSize * 0.33f);
62 | }
63 | }
64 |
65 | private Rectangle setPathRect(Vector2 start, Vector2 end, Rectangle rect) {
66 | tmp.set(end).sub(start);
67 | float grid = gridSize * width;
68 | float sx = start.x > end.x? end.x:start.x;
69 | float sy = start.y > end.y? end.y:start.y;
70 | float width = grid - gridSize / 2;
71 | float height = grid - gridSize / 2;
72 | if (MathUtils.isZero(tmp.x)) {
73 | // horizontal path
74 | sx = sx - grid / 2 + gridSize / 4;
75 | sy = sy - grid / 2 + gridSize / 4;
76 | height = Math.abs(end.y - start.y) + grid - gridSize / 2;
77 | rect.set(sx, sy, width, height);
78 | } else {
79 | // vertical path
80 | sx = sx - grid / 2 + gridSize / 4;
81 | sy = sy - grid / 2 + gridSize / 4;
82 | width = Math.abs(end.x - start.x) + grid - gridSize / 2;
83 | rect.set(sx, sy, width, height);
84 | }
85 | return rect;
86 | }
87 |
88 | public void set (float sx, float sy, float ex, float ey) {
89 | start.set(sx, sy);
90 | end.set(ex, ey);
91 | hasBend = false;
92 | setPathRect(start, end, hallA);
93 | }
94 |
95 | public void set (float sx, float sy, float bx, float by, float ex, float ey) {
96 | start.set(sx, sy);
97 | bend.set(bx, by);
98 | end.set(ex, ey);
99 | hasBend = true;
100 | setPathRect(start, bend, hallA);
101 | setPathRect(bend, end, hallB);
102 | }
103 |
104 | public boolean intersects (Room room) {
105 | Rectangle b = room.bounds;
106 | if (hasBend) {
107 | return b.overlaps(hallA) || b.overlaps(hallB);
108 | } else {
109 | return b.overlaps(hallA);
110 | }
111 | }
112 |
113 | @Override public String toString () {
114 | return "Hallway{" +
115 | "id=" + id +
116 | '}';
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/GenSettings.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | /**
21 | * Created by PiotrJ on 04/09/15.
22 | */
23 | public class GenSettings {
24 | private float gridSize;
25 | private float spawnWidth, spawnHeight;
26 | private float roomWidth, roomHeight;
27 | private float mainRoomScale;
28 | private float reconnectChance;
29 | private int hallwaysWidth;
30 | private int count;
31 | private int b2bIters;
32 |
33 | public GenSettings () {
34 | }
35 |
36 | public int getHallwaysWidth () {
37 | return hallwaysWidth;
38 | }
39 |
40 | public GenSettings setHallwaysWidth (int hallwaysWidth) {
41 | this.hallwaysWidth = hallwaysWidth;
42 | return this;
43 | }
44 |
45 | public float getGridSize () {
46 | return gridSize;
47 | }
48 |
49 | public GenSettings setGridSize (float gridSize) {
50 | this.gridSize = gridSize;
51 | return this;
52 | }
53 |
54 | public float getSpawnWidth () {
55 | return spawnWidth * gridSize;
56 | }
57 |
58 | public float getRawSpawnWidth () {
59 | return spawnWidth;
60 | }
61 |
62 | public GenSettings setSpawnWidth (float ellipseWidth) {
63 | this.spawnWidth = ellipseWidth;
64 | return this;
65 | }
66 |
67 | public float getSpawnHeight () {
68 | return spawnHeight * gridSize;
69 | }
70 |
71 |
72 | public float getRawSpawnHeight () {
73 | return spawnHeight;
74 | }
75 |
76 | public GenSettings setSpawnHeight (float ellipseHeight) {
77 | this.spawnHeight = ellipseHeight;
78 | return this;
79 | }
80 |
81 | public float getRoomWidth () {
82 | return roomWidth * gridSize;
83 | }
84 | public float getRawRoomWidth () {
85 | return roomWidth;
86 | }
87 |
88 | public GenSettings setRoomWidth (float roomWidth) {
89 | this.roomWidth = roomWidth;
90 | return this;
91 | }
92 |
93 | public float getRoomHeight () {
94 | return roomHeight * gridSize;
95 | }
96 | public float getRawRoomHeight () {
97 | return roomHeight;
98 | }
99 |
100 | public GenSettings setRoomHeight (float roomHeight) {
101 | this.roomHeight = roomHeight;
102 | return this;
103 | }
104 |
105 | public float getMainRoomScale () {
106 | return mainRoomScale;
107 | }
108 |
109 | public GenSettings setMainRoomScale (float mainRoomScale) {
110 | this.mainRoomScale = mainRoomScale;
111 | return this;
112 | }
113 |
114 | public float getReconnectChance () {
115 | return reconnectChance;
116 | }
117 |
118 | public GenSettings setReconnectChance (float reconnectChance) {
119 | this.reconnectChance = reconnectChance;
120 | return this;
121 | }
122 |
123 | public GenSettings setCount (int count) {
124 | this.count = count;
125 | return this;
126 | }
127 |
128 | public int getCount () {
129 | return count;
130 | }
131 |
132 | public GenSettings setB2bIters (int b2bIters) {
133 | this.b2bIters = b2bIters;
134 | return this;
135 | }
136 |
137 | public int getB2bIters () {
138 | return b2bIters;
139 | }
140 |
141 | public void copy (GenSettings s) {
142 | this.gridSize = s.gridSize;
143 | this.spawnWidth = s.spawnWidth;
144 | this.spawnHeight = s.spawnHeight;
145 | this.roomWidth = s.roomWidth;
146 | this.roomHeight = s.roomHeight;
147 | this.mainRoomScale = s.mainRoomScale;
148 | this.reconnectChance = s.reconnectChance;
149 | this.hallwaysWidth = s.hallwaysWidth;
150 | this.count = s.count;
151 | this.b2bIters = s.b2bIters;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/BaseScreen.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.*;
21 | import com.badlogic.gdx.graphics.GL20;
22 | import com.badlogic.gdx.graphics.OrthographicCamera;
23 | import com.badlogic.gdx.graphics.g2d.SpriteBatch;
24 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
25 | import com.badlogic.gdx.scenes.scene2d.Stage;
26 | import com.badlogic.gdx.scenes.scene2d.ui.Table;
27 | import com.badlogic.gdx.utils.viewport.ExtendViewport;
28 | import com.badlogic.gdx.utils.viewport.ScreenViewport;
29 |
30 | /**
31 | * Created by EvilEntity on 07/06/2015.
32 | */
33 | public abstract class BaseScreen implements Screen, InputProcessor {
34 | private final static String TAG = "BaseScreen";
35 |
36 | protected OrthographicCamera gameCamera;
37 | protected OrthographicCamera guiCamera;
38 | protected ExtendViewport gameViewport;
39 | protected ScreenViewport guiViewport;
40 |
41 | protected SpriteBatch batch;
42 | protected ShapeRenderer renderer;
43 |
44 | protected Stage stage;
45 | protected Table root;
46 |
47 | protected final InputMultiplexer multiplexer;
48 |
49 | boolean debugStage;
50 |
51 | public BaseScreen () {
52 | gameCamera = new OrthographicCamera();
53 | gameViewport = new ExtendViewport(DungenGame.VP_WIDTH, DungenGame.VP_HEIGHT, gameCamera);
54 | guiCamera = new OrthographicCamera();
55 | guiViewport = new ScreenViewport(guiCamera);
56 |
57 | batch = new SpriteBatch();
58 | renderer = new ShapeRenderer();
59 |
60 | stage = new Stage(guiViewport, batch);
61 | stage.setDebugAll(debugStage);
62 | root = new Table();
63 | root.setFillParent(true);
64 | stage.addActor(root);
65 | Gdx.input.setInputProcessor(multiplexer = new InputMultiplexer(stage, this));
66 |
67 | Gdx.app.log(TAG, "F1 - toggle stage debug");
68 | }
69 |
70 | @Override public void show () {
71 |
72 | }
73 |
74 | @Override public void render (float delta) {
75 | Gdx.gl.glClearColor(0, 0, 0, 1);
76 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
77 | }
78 |
79 | @Override public void resize (int width, int height) {
80 | gameViewport.update(width, height, false);
81 | guiViewport.update(width, height, true);
82 | }
83 |
84 | @Override public void pause () {
85 |
86 | }
87 |
88 | @Override public void resume () {
89 |
90 | }
91 |
92 | @Override public void hide () {
93 | dispose();
94 | }
95 |
96 | @Override public void dispose () {
97 | batch.dispose();
98 | renderer.dispose();
99 | stage.dispose();
100 | }
101 |
102 | @Override public boolean keyDown (int keycode) {
103 | if (keycode == Input.Keys.F1) {
104 | debugStage = !debugStage;
105 | stage.setDebugAll(debugStage);
106 | Gdx.app.log(TAG, "F1 - Stage debug is " + (debugStage ? "enabled" : "disabled"));
107 | }
108 | return false;
109 | }
110 |
111 | @Override public boolean keyUp (int keycode) {
112 | return false;
113 | }
114 |
115 | @Override public boolean keyTyped (char character) {
116 | return false;
117 | }
118 |
119 | @Override public boolean touchDown (int screenX, int screenY, int pointer, int button) {
120 | return false;
121 | }
122 |
123 | @Override public boolean touchUp (int screenX, int screenY, int pointer, int button) {
124 | return false;
125 | }
126 |
127 | @Override public boolean touchDragged (int screenX, int screenY, int pointer) {
128 | return false;
129 | }
130 |
131 | @Override public boolean mouseMoved (int screenX, int screenY) {
132 | return false;
133 | }
134 |
135 | @Override public boolean scrolled (int amount) {
136 | return false;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/gui/DrawSettingsGUI.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.gui;
19 |
20 | import com.badlogic.gdx.scenes.scene2d.Actor;
21 | import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
22 | import com.kotcrab.vis.ui.VisUI;
23 | import com.kotcrab.vis.ui.widget.*;
24 | import io.piotrjastrzebski.dungen.DrawSettings;
25 |
26 | public class DrawSettingsGUI extends VisWindow {
27 | DrawSettings settings;
28 | Restarter restarter;
29 |
30 | VisCheckBox drawMinSpanTree;
31 | VisCheckBox drawHallWayPaths;
32 | VisCheckBox drawHallWays;
33 | VisCheckBox drawBodies;
34 | VisCheckBox drawUnused;
35 | VisCheckBox drawMain;
36 | VisCheckBox drawExtra;
37 | VisCheckBox drawEdges;
38 | VisCheckBox drawSpawnArea;
39 |
40 | public DrawSettingsGUI (Restarter restarter) {
41 | super("Display settings");
42 | this.restarter = restarter;
43 | VisUI.getSkin().getFont("default-font").getData().markupEnabled = true;
44 | settings = new DrawSettings();
45 | VisTable c = new VisTable(true);
46 | c.add(new VisLabel("Hover for tooltips")).row();
47 |
48 | drawBodies = toggle(c, "Bodies", "Draw box2d bodies used for separation", settings.drawBodies, new Toggle() {
49 | @Override public void toggle (boolean value) {
50 | settings.drawBodies = value;
51 | }
52 | });
53 | c.row();
54 | drawUnused = toggle(c, "[#9c9c9c]Unused[]", "Draw rooms that are [#9c9c9c]unused[]", settings.drawUnused, new Toggle() {
55 | @Override public void toggle (boolean value) {
56 | settings.drawUnused = value;
57 | }
58 | });
59 | drawExtra = toggle(c, "[#cccccc]Extra[]", "Draw [#cccccc]extra[] rooms, added to form paths", settings.drawExtra, new Toggle() {
60 | @Override public void toggle (boolean value) {
61 | settings.drawExtra = value;
62 | }
63 | });
64 | c.row();
65 | drawHallWays = toggle(c, "[#3366ff]Hallways[]", "Draw rooms that are part of [#3366ff]hallways[]", settings.drawHallWays, new Toggle() {
66 | @Override public void toggle (boolean value) {
67 | settings.drawHallWays = value;
68 | }
69 | });
70 | drawMain = toggle(c, "[#ff3319]Main[]", "Draw [#ff3319]main[] rooms", settings.drawMain, new Toggle() {
71 | @Override public void toggle (boolean value) {
72 | settings.drawMain = value;
73 | }
74 | });
75 | c.row();
76 | String ptt = "Draw hallway paths connecting main rooms\n" +
77 | "[#32cd32]from min span tree[]\n" +
78 | "[ORANGE]reconnected[]";
79 | drawHallWayPaths = toggle(c, "Hallway Paths", ptt, settings.drawHallWayPaths, new Toggle() {
80 | @Override public void toggle (boolean value) {
81 | settings.drawHallWayPaths = value;
82 | }
83 | });
84 | drawSpawnArea = toggle(c, "Spawn Area", "Draw initial spawn area of rooms", settings.drawSpawnArea, new Toggle() {
85 | @Override public void toggle (boolean value) {
86 | settings.drawSpawnArea = value;
87 | }
88 | });
89 | c.row();
90 | String msttt = "Draw minimum spanning tree for main rooms\n" +
91 | "[#32cd32]min span tree[]\n" +
92 | "[ORANGE]reconnected[]";
93 | drawMinSpanTree = toggle(c, "Min Span Tree", msttt, settings.drawMinSpanTree, new Toggle() {
94 | @Override public void toggle (boolean value) {
95 | settings.drawMinSpanTree = value;
96 | }
97 | });
98 | drawEdges = toggle(c, "Triangulation", "Draw triangulation for main rooms", settings.drawEdges, new Toggle() {
99 | @Override public void toggle (boolean value) {
100 | settings.drawEdges = value;
101 | }
102 | });
103 |
104 | add(c);
105 | pack();
106 | }
107 |
108 | private VisCheckBox toggle (VisTable c, String text, String tt, boolean def, final Toggle toggle) {
109 | final VisCheckBox cb = new VisCheckBox(text, def);
110 | new Tooltip(cb, tt);
111 | cb.addListener(new ChangeListener() {
112 | @Override public void changed (ChangeEvent event, Actor actor) {
113 | toggle.toggle(cb.isChecked());
114 | restarter.update(settings);
115 | }
116 | });
117 | c.add(cb).left();
118 | return cb;
119 | }
120 |
121 | private abstract class Toggle {
122 | public abstract void toggle(boolean checked);
123 | }
124 |
125 | public void setDefaults(DrawSettings settings) {
126 | this.settings.copy(settings);
127 | drawBodies.setChecked(settings.drawBodies);
128 | drawUnused.setChecked(settings.drawUnused);
129 | drawExtra.setChecked(settings.drawExtra);
130 | drawHallWays.setChecked(settings.drawHallWays);
131 | drawHallWayPaths.setChecked(settings.drawHallWayPaths);
132 | drawMain.setChecked(settings.drawMain);
133 | drawEdges.setChecked(settings.drawEdges);
134 | drawMinSpanTree.setChecked(settings.drawMinSpanTree);
135 | drawSpawnArea.setChecked(settings.drawSpawnArea);
136 | pack();
137 | }
138 |
139 | public DrawSettings getSettings () {
140 | return settings;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/gui/GenSettingsGUI.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen.gui;
19 |
20 | import com.badlogic.gdx.Gdx;
21 | import com.badlogic.gdx.scenes.scene2d.Actor;
22 | import com.badlogic.gdx.scenes.scene2d.InputEvent;
23 | import com.badlogic.gdx.scenes.scene2d.ui.Table;
24 | import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
25 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
26 | import com.badlogic.gdx.utils.Align;
27 | import com.badlogic.gdx.utils.Base64Coder;
28 | import com.badlogic.gdx.utils.StringBuilder;
29 | import com.kotcrab.vis.ui.VisUI;
30 | import com.kotcrab.vis.ui.widget.*;
31 | import io.piotrjastrzebski.dungen.DungenScreen;
32 | import io.piotrjastrzebski.dungen.GenSettings;
33 |
34 | public class GenSettingsGUI extends VisWindow {
35 | GenSettings settings;
36 | VisSlider grid;
37 | VisSlider count;
38 | VisSlider sWidth;
39 | VisSlider sHeight;
40 | VisSlider rWidth;
41 | VisSlider rHeight;
42 | VisSlider mainScale;
43 | VisSlider reconChance;
44 | VisSlider hallWidth;
45 | VisSlider b2dIters;
46 |
47 | public GenSettingsGUI (final Restarter restarter, final Saver saver) {
48 | super("Generator settings");
49 | settings = new GenSettings();
50 | VisTable c = new VisTable(true);
51 |
52 | VisTextButton restart = new VisTextButton("Restart");
53 | restart.addListener(new ClickListener() {
54 | @Override public void clicked (InputEvent event, float x, float y) {
55 | restarter.restart(settings);
56 | }
57 | });
58 | VisTextButton export = new VisTextButton("Export");
59 | export.addListener(new ClickListener() {
60 | @Override public void clicked (InputEvent event, float x, float y) {
61 | // TODO add a dialog to pick a name?
62 | saver.save("dungen");
63 | }
64 | });
65 | VisTable top = new VisTable(true);
66 | top.add(restart);
67 | top.add(export).expandX();
68 | top.add(new VisLabel("Hover for tooltips"));
69 | c.add(top).expandX().fillX().colspan(3);
70 | c.row();
71 |
72 | grid = slider(c, "Grid Size", "Size of the grid in units\n1u=32px at 720p", 0.1f, 1.f, 0.05f, new SliderAction() {
73 | @Override public void setValue (float value) {
74 | settings.setGridSize(value);
75 | }
76 | });
77 | c.row();
78 | count = slider(c, "Room Count", "Number of rooms to be spawned", 50f, 1000f, 10f, new SliderAction() {
79 | @Override public void setValue (float value) {
80 | settings.setCount((int)value);
81 | }
82 | });
83 | c.row();
84 | sWidth = slider(c, "Spawn Width", "Width of the ellipse the rooms will be spawned in\nin grid units", 5f, 100f, 5f, new SliderAction() {
85 | @Override public void setValue (float value) {
86 | settings.setSpawnWidth(value);
87 | }
88 | });
89 | c.row();
90 | sHeight = slider(c, "Spawn Height", "Height of the ellipse the rooms will be spawned in\nin grid units", 5f, 100f, 5f, new SliderAction() {
91 | @Override public void setValue (float value) {
92 | settings.setSpawnHeight(value);
93 | }
94 | });
95 | c.row();
96 | rWidth = slider(c, "Room Width", "Mean room width in grid units", 1f, 10f, 1f, new SliderAction() {
97 | @Override public void setValue (float value) {
98 | settings.setRoomWidth(value);
99 | }
100 | });
101 | c.row();
102 | rHeight = slider(c, "Room Height", "Mean room height in grid units", 1f, 10f, 1f, new SliderAction() {
103 | @Override public void setValue (float value) {
104 | settings.setRoomHeight(value);
105 | }
106 | });
107 | c.row();
108 | mainScale = slider(c, "Main Scale", "Percent of the mean size for a room to be marked as main", 0.5f, 2.f, 0.05f, new SliderAction() {
109 | @Override public void setValue (float value) {
110 | settings.setMainRoomScale(value);
111 | }
112 | });
113 | c.row();
114 | reconChance = slider(c, "Reconnect %", "Chance to reconnect the path after\nminimum spanning tree is created",
115 | 0.0f, 1.f, 0.05f, new SliderAction() {
116 | @Override public void setValue (float value) {
117 | settings.setReconnectChance(value);
118 | }
119 | });
120 | add(c);
121 | c.row();
122 | hallWidth = slider(c, "Hallway Width", "Width of hallways in grid units",
123 | 1, 10, 1, new SliderAction() {
124 | @Override public void setValue (float value) {
125 | settings.setHallwaysWidth((int)value);
126 | }
127 | });
128 | add(c);
129 | c.row();
130 | b2dIters = slider(c, "B2D Iterations", "Iterations per frame for settling bodies, more -> faster settling",
131 | 5, 1000, 5, new SliderAction() {
132 | @Override public void setValue (float value) {
133 | settings.setB2bIters((int)value);
134 | }
135 | });
136 | add(c);
137 | pack();
138 | }
139 |
140 | private abstract class SliderAction {
141 | public abstract void setValue (float value);
142 | }
143 |
144 | private VisSlider slider(Table container, String text, String tooltip, float min, float max, float step, final SliderAction action) {
145 | VisLabel label = new VisLabel(text);
146 | final VisSlider slider = new VisSlider(min, max, step, false);
147 | container.add(label).left();
148 | new Tooltip(label, tooltip);
149 | float scale = VisUI.getSizes().scaleFactor;
150 | container.add(slider).prefWidth(120 * scale);
151 | final VisLabel val = new VisLabel("000.00");
152 | slider.addListener(new ChangeListener() {
153 | @Override public void changed (ChangeEvent event, Actor actor) {
154 | val.setText(toStr(slider.getValue()));
155 | action.setValue(slider.getValue());
156 | }
157 | });
158 | val.setAlignment(Align.right);
159 | container.add(val).right().width(45 * scale);
160 | return slider;
161 | }
162 |
163 | /*
164 | Simple String.format() replacements as it doesnt work on GWT
165 | */
166 | StringBuilder sb = new StringBuilder();
167 | private String toStr(float value) {
168 | sb.setLength(0);
169 | sb.append(value);
170 | int dot = sb.indexOf(".");
171 | if (dot > 0 && sb.length() > dot + 3) {
172 | sb.setLength(dot + 3);
173 | }
174 | return sb.toString();
175 | }
176 |
177 | public void setDefaults(GenSettings settings) {
178 | this.settings.copy(settings);
179 | grid.setValue(settings.getGridSize());
180 | count.setValue(settings.getCount());
181 | sWidth.setValue(settings.getRawSpawnWidth());
182 | sHeight.setValue(settings.getRawSpawnHeight());
183 | rWidth.setValue(settings.getRawRoomWidth());
184 | rHeight.setValue(settings.getRawRoomHeight());
185 | mainScale.setValue(settings.getMainRoomScale());
186 | reconChance.setValue(settings.getReconnectChance());
187 | hallWidth.setValue(settings.getHallwaysWidth());
188 | b2dIters.setValue(settings.getB2bIters());
189 | pack();
190 | }
191 |
192 | public GenSettings getSettings () {
193 | return settings;
194 | }
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/DungenScreen.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.Gdx;
21 | import com.badlogic.gdx.Input;
22 | import com.badlogic.gdx.Preferences;
23 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
24 | import com.badlogic.gdx.input.GestureDetector;
25 | import com.badlogic.gdx.math.MathUtils;
26 | import com.badlogic.gdx.math.Vector2;
27 | import com.badlogic.gdx.scenes.scene2d.InputEvent;
28 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
29 | import com.badlogic.gdx.utils.JsonWriter;
30 | import com.kotcrab.vis.ui.widget.VisTable;
31 | import com.kotcrab.vis.ui.widget.VisTextButton;
32 | import io.piotrjastrzebski.dungen.gui.*;
33 |
34 | /**
35 | * Created by PiotrJ on 02/09/15.
36 | */
37 | public class DungenScreen extends BaseScreen implements Restarter, Saver, GestureDetector.GestureListener {
38 | DungeonGenerator generator;
39 | Grid grid;
40 | GenSettingsGUI genGui;
41 | GenSettings genSettings;
42 | DrawSettingsGUI drawGui;
43 | DrawSettings drawSettings;
44 | DungenGame game;
45 |
46 | HelpGUI helpGUI;
47 |
48 | public DungenScreen (DungenGame game) {
49 | super();
50 | this.game = game;
51 |
52 | genSettings = new GenSettings()
53 | .setGridSize(.25f)
54 | .setCount(150)
55 | .setSpawnWidth(20).setSpawnHeight(10)
56 | .setRoomWidth(4).setRoomHeight(4)
57 | .setMainRoomScale(1.15f)
58 | .setReconnectChance(.2f)
59 | .setHallwaysWidth(2)
60 | .setB2bIters(100);
61 |
62 | drawSettings = new DrawSettings()
63 | .setDrawExtra(true)
64 | .setDrawMain(true)
65 | .setDrawHallWays(true)
66 | .setDrawUnused(true);
67 |
68 | generator = new DungeonGenerator();
69 | generator.init(genSettings);
70 |
71 | grid = new Grid();
72 | grid.setSize(genSettings.getGridSize());
73 |
74 | genGui = new GenSettingsGUI(this, this);
75 | genGui.setDefaults(genSettings);
76 | stage.addActor(genGui);
77 | genGui.setPosition(10, 10);
78 |
79 | drawGui = new DrawSettingsGUI(this);
80 | drawGui.setDefaults(drawSettings);
81 | stage.addActor(drawGui);
82 | drawGui.setPosition(10, stage.getHeight() - drawGui.getHeight() - 10);
83 |
84 | multiplexer.addProcessor(this);
85 | multiplexer.addProcessor(new GestureDetector(this));
86 |
87 | helpGUI = new HelpGUI();
88 | VisTable helpCont = new VisTable();
89 | helpCont.setFillParent(true);
90 | VisTextButton showHelp = new VisTextButton("Help!");
91 | showHelp.addListener(new ClickListener() {
92 | @Override public void clicked (InputEvent event, float x, float y) {
93 | helpGUI.show(stage);
94 | }
95 | });
96 | helpCont.add(showHelp).right().top().expand().pad(10);
97 | stage.addActor(helpCont);
98 |
99 | Preferences dungen = Gdx.app.getPreferences("Dungen");
100 | if (!dungen.getBoolean("help-shown", false)) {
101 | helpGUI.show(stage);
102 | dungen.putBoolean("help-shown", true);
103 | dungen.flush();
104 | }
105 | }
106 |
107 | @Override public void save (String name) {
108 | // TODO settings for type and pretty print
109 | String json = generator.toJson(JsonWriter.OutputType.javascript, true);
110 | if (!name.endsWith(".json"))
111 | name += ".json";
112 | game.bridge.save(name, json);
113 | }
114 |
115 | private int moveVert;
116 | private int moveHor;
117 | private int zoom;
118 | @Override public void render (float delta) {
119 | super.render(delta);
120 | generator.update(delta);
121 | if (zoom > 0) {
122 | gameCamera.zoom = MathUtils.clamp(gameCamera.zoom + gameCamera.zoom * 0.05f, 0.01f, 10);
123 | } else if (zoom < 0) {
124 | gameCamera.zoom = MathUtils.clamp(gameCamera.zoom - gameCamera.zoom * 0.05f, 0.01f, 10);
125 |
126 | }
127 | if (moveVert > 0) {
128 | gameCamera.position.y += 10 * delta;
129 | } else if (moveVert < 0) {
130 | gameCamera.position.y -= 10 * delta;
131 | }
132 | if (moveHor > 0) {
133 | gameCamera.position.x += 10 * delta;
134 | } else if (moveHor < 0) {
135 | gameCamera.position.x -= 10 * delta;
136 | }
137 | gameCamera.update();
138 |
139 | renderer.setProjectionMatrix(gameCamera.combined);
140 | renderer.begin(ShapeRenderer.ShapeType.Line);
141 | grid.render(renderer);
142 | renderer.end();
143 |
144 | renderer.begin(ShapeRenderer.ShapeType.Filled);
145 | generator.render(renderer, gameCamera);
146 | renderer.end();
147 |
148 | stage.act(delta);
149 | stage.draw();
150 | }
151 |
152 | @Override public void resize (int width, int height) {
153 | super.resize(width, height);
154 | grid.resize(width, height);
155 | }
156 |
157 | @Override public boolean keyDown (int keycode) {
158 | switch (keycode) {
159 | case Input.Keys.SPACE:
160 | restart(genGui.getSettings());
161 | break;
162 | case Input.Keys.C:
163 | resetCamera();
164 | break;
165 | case Input.Keys.Q:
166 | zoom++;
167 | break;
168 | case Input.Keys.E:
169 | zoom--;
170 | break;
171 | case Input.Keys.UP:
172 | case Input.Keys.W:
173 | moveVert++;
174 | break;
175 | case Input.Keys.DOWN:
176 | case Input.Keys.S:
177 | moveVert--;
178 | break;
179 | case Input.Keys.LEFT:
180 | case Input.Keys.A:
181 | moveHor--;
182 | break;
183 | case Input.Keys.RIGHT:
184 | case Input.Keys.D:
185 | moveHor++;
186 | break;
187 | }
188 | return super.keyDown(keycode);
189 | }
190 |
191 |
192 | @Override public boolean keyUp (int keycode) {
193 | switch (keycode) {
194 | case Input.Keys.Q:
195 | zoom--;
196 | break;
197 | case Input.Keys.E:
198 | zoom++;
199 | break;
200 | case Input.Keys.UP:
201 | case Input.Keys.W:
202 | moveVert--;
203 | break;
204 | case Input.Keys.DOWN:
205 | case Input.Keys.S:
206 | moveVert++;
207 | break;
208 | case Input.Keys.LEFT:
209 | case Input.Keys.A:
210 | moveHor++;
211 | break;
212 | case Input.Keys.RIGHT:
213 | case Input.Keys.D:
214 | moveHor--;
215 | break;
216 | }
217 | return super.keyDown(keycode);
218 | }
219 |
220 | private void resetCamera () {
221 | gameCamera.position.setZero();
222 | gameCamera.zoom = 1;
223 | gameCamera.update();
224 | }
225 |
226 | @Override public boolean scrolled (int amount) {
227 | gameCamera.zoom = MathUtils.clamp(gameCamera.zoom + gameCamera.zoom * amount * 0.05f, 0.01f, 10);
228 | gameCamera.update();
229 | return super.scrolled(amount);
230 | }
231 |
232 | @Override public void dispose () {
233 | super.dispose();
234 | generator.dispose();
235 | }
236 |
237 | @Override public void restart (GenSettings settings) {
238 | this.genSettings.copy(settings);
239 | generator.init(settings);
240 | grid.setSize(settings.getGridSize());
241 | }
242 |
243 | @Override public void update (DrawSettings settings) {
244 | generator.setDrawSettings(settings);
245 | }
246 |
247 | @Override public boolean pan (float x, float y, float deltaX, float deltaY) {
248 | // this feels wrong...
249 | float ppw = gameViewport.getWorldWidth() / gameViewport.getScreenWidth();
250 | float pph = gameViewport.getWorldHeight() / gameViewport.getScreenHeight();
251 | gameCamera.position.add(-deltaX * ppw * gameCamera.zoom, deltaY * pph * gameCamera.zoom, 0);
252 | gameCamera.update();
253 | return false;
254 | }
255 |
256 | @Override public boolean panStop (float x, float y, int pointer, int button) {
257 | return false;
258 | }
259 |
260 | @Override public boolean zoom (float initialDistance, float distance) {
261 | // TODO touch screen zoom
262 | return false;
263 | }
264 |
265 | @Override public boolean touchDown (float x, float y, int pointer, int button) {
266 | return false;
267 | }
268 |
269 | @Override public boolean tap (float x, float y, int count, int button) {
270 | return false;
271 | }
272 |
273 | @Override public boolean longPress (float x, float y) {
274 | return false;
275 | }
276 |
277 | @Override public boolean fling (float velocityX, float velocityY, int button) {
278 | return false;
279 | }
280 |
281 | @Override public boolean pinch (Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
282 | return false;
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/core/src/io/piotrjastrzebski/dungen/DungeonGenerator.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2015 See AUTHORS file.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | ******************************************************************************/
17 |
18 | package io.piotrjastrzebski.dungen;
19 |
20 | import com.badlogic.gdx.Gdx;
21 | import com.badlogic.gdx.graphics.Color;
22 | import com.badlogic.gdx.graphics.GL20;
23 | import com.badlogic.gdx.graphics.OrthographicCamera;
24 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
25 | import com.badlogic.gdx.math.DelaunayTriangulator;
26 | import com.badlogic.gdx.math.MathUtils;
27 | import com.badlogic.gdx.math.Rectangle;
28 | import com.badlogic.gdx.math.Vector2;
29 | import com.badlogic.gdx.physics.box2d.*;
30 | import com.badlogic.gdx.utils.Array;
31 | import com.badlogic.gdx.utils.Json;
32 | import com.badlogic.gdx.utils.JsonWriter;
33 | import com.badlogic.gdx.utils.ShortArray;
34 |
35 | import java.io.StringWriter;
36 | import java.util.Comparator;
37 |
38 | /**
39 | * Created by PiotrJ on 02/09/15.
40 | */
41 | public class DungeonGenerator {
42 | private int roomID;
43 | Array rooms = new Array<>();
44 |
45 | World b2d;
46 | Box2DDebugRenderer b2dd;
47 | Vector2 tmp = new Vector2();
48 | GenSettings settings;
49 | DrawSettings drawSettings;
50 | Rectangle map = new Rectangle();
51 |
52 | public DungeonGenerator () {
53 | super();
54 | b2d = new World(new Vector2(), true);
55 | b2dd = new Box2DDebugRenderer();
56 | settings = new GenSettings();
57 | drawSettings = new DrawSettings();
58 | }
59 |
60 | public void init (GenSettings settings) {
61 | this.settings.copy(settings);
62 |
63 | graph.clear();
64 | mainRooms.clear();
65 | if (rooms.size > 0) {
66 | for (Room room : rooms) {
67 | if (room.body != null)
68 | b2d.destroyBody(room.body);
69 | }
70 | }
71 | rooms.clear();
72 | paths.clear();
73 |
74 | float gridSize = settings.getGridSize();
75 | float roomWidth = settings.getRoomWidth();
76 | float roomHeight = settings.getRoomHeight();
77 | float spawnWidth = settings.getSpawnWidth();
78 | float spawnHeight = settings.getSpawnHeight();
79 | for (int i = 0; i < settings.getCount(); i++) {
80 | Room room = new Room(roomID++, gridSize);
81 | float w = Utils.roundedRngFloat(roomWidth, gridSize, gridSize);
82 | float h = Utils.roundedRngFloat(roomHeight, gridSize, gridSize);
83 | if (w < gridSize || h < gridSize) {
84 | continue;
85 | }
86 | Utils.roundedPointInEllipse(spawnWidth, spawnHeight, gridSize, tmp);
87 | room.set(tmp.x, tmp.y, w, h);
88 | createBody(room);
89 | rooms.add(room);
90 | }
91 | }
92 |
93 | public void setDrawSettings (DrawSettings drawSettings) {
94 | this.drawSettings.copy(drawSettings);
95 | }
96 |
97 | private void createBody (Room room) {
98 | Rectangle b = room.bounds;
99 | if (b.width < 0.1f || b.height < 0.1f) {
100 | return;
101 | }
102 | BodyDef bodyDef = new BodyDef();
103 | bodyDef.fixedRotation = true;
104 | bodyDef.type = BodyDef.BodyType.DynamicBody;
105 | bodyDef.position.set(b.x, b.y);
106 | Body body = b2d.createBody(bodyDef);
107 |
108 | PolygonShape shape = new PolygonShape();
109 | shape.setAsBox(b.width / 2, b.height / 2);
110 |
111 | FixtureDef fd = new FixtureDef();
112 | fd.restitution = 0;
113 | fd.friction = 0.5f;
114 | fd.density = 1;
115 | fd.shape = shape;
116 |
117 | body.createFixture(fd);
118 |
119 | shape.dispose();
120 |
121 | room.body = body;
122 | }
123 |
124 | boolean settled;
125 | public void update (float delta) {
126 | // no need to run this if we have rooms
127 | if (mainRooms.size > 0) return;
128 | settled = true;
129 | for (int i = 0; i < settings.getB2bIters(); i++) {
130 | b2d.step(0.16f, 6, 4);
131 | for (Room room : rooms) {
132 | if (!room.isSleeping()) {
133 | settled = false;
134 | break;
135 | }
136 | }
137 | if (settled)
138 | break;
139 | }
140 | for (Room room : rooms) {
141 | room.update();
142 | }
143 | }
144 |
145 | public void render (ShapeRenderer renderer, OrthographicCamera camera) {
146 | if (drawSettings.drawBodies) {
147 | b2dd.render(b2d, camera.combined);
148 | }
149 |
150 | if (mainRooms.size == 0) {
151 | renderer.setColor(0.4f, 0.2f, 0.1f, 1);
152 | for (Room room : rooms) {
153 | room.draw(renderer);
154 | }
155 | }
156 |
157 | float size = settings.getGridSize();
158 | if (drawSettings.drawUnused) {
159 | renderer.setColor(0.3f, 0.3f, 0.3f, 1);
160 | for (Room room : rooms) {
161 | if (room.isUnused()) {
162 | room.draw(renderer);
163 | }
164 | }
165 | }
166 |
167 | if (drawSettings.drawExtra) {
168 | renderer.setColor(0.8f, 0.8f, 0.8f, 1);
169 | for (Room room : rooms) {
170 | if (room.isExtra) {
171 | room.draw(renderer);
172 | }
173 | }
174 | }
175 | if (drawSettings.drawHallWays) {
176 | renderer.setColor(0.2f, 0.4f, 1, 1);
177 | for (Room room : rooms) {
178 | if (room.isHallway) {
179 | room.draw(renderer);
180 | }
181 | }
182 | }
183 | if (drawSettings.drawMain) {
184 | for (Room room : rooms) {
185 | if (room.isMain) {
186 | renderer.setColor(1, 0.2f, 0.1f, 1);
187 | room.draw(renderer);
188 | }
189 | }
190 | }
191 | if (settled && mainRooms.size == 0) {
192 | float mw = settings.getRoomWidth() * settings.getMainRoomScale();
193 | float mh = settings.getRoomHeight() * settings.getMainRoomScale();
194 | for (Room room : rooms) {
195 | map.merge(room.bounds);
196 | if (room.bounds.width >= mw && room.bounds.height >= mh) {
197 | room.isMain = true;
198 | mainRooms.add(room);
199 | }
200 | }
201 | // extend map bounds by 1 tile in all directions
202 | map.x -= size;
203 | map.y -= size;
204 | map.width += size * 2;
205 | map.height += size * 2;
206 | // sort so main rooms are drawn lsat
207 | rooms.sort(new Comparator() {
208 | @Override public int compare (Room o1, Room o2) {
209 | int main = Boolean.compare(o1.isMain, o2.isMain);
210 | if (main != 0) {
211 | return main;
212 | }
213 | return Boolean.compare(o1.isHallway, o2.isHallway);
214 | }
215 | });
216 | triangulate();
217 | }
218 | graph.render(renderer, drawSettings.drawEdges, drawSettings.drawMinSpanTree, size);
219 | if (drawSettings.drawHallWayPaths) {
220 | renderer.setColor(Color.YELLOW);
221 | for (HallwayPath path : paths) {
222 | path.draw(renderer);
223 | }
224 | }
225 | if (drawSettings.drawSpawnArea) {
226 | Gdx.gl.glEnable(GL20.GL_BLEND);
227 | renderer.setColor(1, 1, 1, 0.5f);
228 | renderer.ellipse(
229 | -settings.getSpawnWidth()/2, -settings.getSpawnHeight()/2,
230 | settings.getSpawnWidth(), settings.getSpawnHeight());
231 | }
232 | }
233 |
234 | Array mainRooms = new Array<>();
235 | RoomGraph graph = new RoomGraph();
236 |
237 | private void triangulate () {
238 | DelaunayTriangulator triangulator = new DelaunayTriangulator();
239 |
240 | float[] points = new float[mainRooms.size * 2];
241 | for (int i = 0; i < points.length; i += 2) {
242 | Room room = mainRooms.get(i / 2);
243 | points[i] = room.cx();
244 | points[i + 1] = room.cy();
245 | }
246 |
247 | ShortArray indicies = triangulator.computeTriangles(points, 0, points.length, false);
248 |
249 | graph.clear();
250 |
251 | for (int i = 0; i < indicies.size; i += 3) {
252 | int p1 = indicies.get(i) * 2;
253 | int p2 = indicies.get(i + 1) * 2;
254 | int p3 = indicies.get(i + 2) * 2;
255 | // this is pretty dumb...
256 | Room roomA = getRoom(points[p1], points[p1 + 1]);
257 | Room roomB = getRoom(points[p2], points[p2 + 1]);
258 | Room roomC = getRoom(points[p3], points[p3 + 1]);
259 | graph.add(roomA, roomB);
260 | graph.add(roomA, roomC);
261 | graph.add(roomB, roomC);
262 | }
263 |
264 | createMST();
265 | }
266 |
267 | private void createMST () {
268 | /*
269 | kruskal's algorithm, we dont need anything fancy
270 | */
271 | Array edges = graph.getEdges();
272 | edges.sort(new Comparator() {
273 | @Override public int compare (RoomEdge o1, RoomEdge o2) {
274 | return Float.compare(o1.len, o2.len);
275 | }
276 | });
277 | RoomGraph mstGraph = new RoomGraph();
278 | for (RoomEdge edge : edges) {
279 | if (!mstGraph.isConnected(edge)) {
280 | mstGraph.add(edge);
281 | edge.mst = true;
282 | }
283 | }
284 |
285 | for (RoomEdge edge : edges) {
286 | if (!edge.mst && MathUtils.random() < settings.getReconnectChance()) {
287 | edge.mst = true;
288 | edge.recon = true;
289 | }
290 | }
291 |
292 | createHallways();
293 | }
294 |
295 | Array paths = new Array<>();
296 |
297 | private void createHallways () {
298 | Array edges = graph.getEdges();
299 | float grid = settings.getGridSize();
300 | // offset mid position by half grid if the width is odd so we can easily find rooms we need for hallways
301 | int hallwaysWidth = settings.getHallwaysWidth();
302 | float offset = (hallwaysWidth%2==1)?grid / 2:0;
303 |
304 | for (RoomEdge e : edges) {
305 | if (!e.mst)
306 | continue;
307 | HallwayPath path = new HallwayPath(grid, hallwaysWidth);
308 | path.recon = e.recon;
309 | Rectangle bA = e.roomA.bounds;
310 | Rectangle bB = e.roomB.bounds;
311 | float min, max, mid;
312 | // rooms cant overlap on both axis
313 | if (bA.x < bB.x + bB.width && bA.x + bA.width > bB.x) {
314 | // no need for 0 len hallway
315 | if (MathUtils.isEqual(bA.y, bB.y + bB.height) || MathUtils.isEqual(bA.y + bA.height, bB.y)) {
316 | continue;
317 | }
318 | min = (bA.x < bB.x) ? bB.x : bA.x;
319 | max = (bA.x + bA.width < bB.x + bB.width) ? bA.x + bA.width : bB.x + bB.width;
320 | mid = (min + max) / 2;
321 | mid = Utils.roundToSize(mid, grid) - offset;
322 | if (bA.y > bB.y) {
323 | path.set(mid, bA.y, mid, bB.y + bB.height);
324 | } else {
325 | path.set(mid, bA.y + bA.height, mid, bB.y);
326 | }
327 | } else if (bA.y < bB.y + bB.height && bA.y + bA.height > bB.y) {
328 | // no need for 0 len hallway
329 | if (MathUtils.isEqual(bA.x, bB.x + bB.width) || MathUtils.isEqual(bA.x + bA.width, bB.x)) {
330 | continue;
331 | }
332 |
333 | min = (bA.y < bB.y) ? bB.y : bA.y;
334 | max = (bA.y + bA.height < bB.y + bB.height) ? bA.y + bA.height : bB.y + bB.height;
335 | mid = (min + max) / 2;
336 | mid = Utils.roundToSize(mid, grid) - offset;
337 | if (bA.x > bB.x) {
338 | path.set(bA.x, mid, bB.x + bB.width, mid);
339 | } else {
340 | path.set(bA.x + bA.width, mid, bB.x, mid);
341 | }
342 | } else {
343 | // need to make a L shaped hallway
344 | float ax = bA.x;
345 | float ay = bA.y;
346 | float aw = bA.width;
347 | float ah = bA.height;
348 | float bx = bB.x;
349 | float by = bB.y;
350 | float bw = bB.width;
351 | float bh = bB.height;
352 | float mx, my;
353 | // pick a side of the bend
354 | // can we make this simpler? im dumb
355 | if (MathUtils.randomBoolean()) {
356 | mx = ax + aw / 2;
357 | my = by + bh / 2;
358 | mx = Utils.roundToSize(mx, grid) - offset;
359 | my = Utils.roundToSize(my, grid) - offset;
360 | if (ax < bx) {
361 | if (ay < by) {
362 | path.set(mx, ay + ah, mx, my, bx, my);
363 | } else {
364 | path.set(mx, ay, mx, my, bx, my);
365 | }
366 | } else {
367 | if (ay > by) {
368 | path.set(mx, ay, mx, my, bx + bw, my);
369 | } else {
370 | path.set(mx, ay + ah, mx, my, bx + bw, my);
371 | }
372 | }
373 | } else {
374 | mx = bx + bw / 2;
375 | my = ay + ah / 2;
376 | mx = Utils.roundToSize(mx, grid) - offset;
377 | my = Utils.roundToSize(my, grid) - offset;
378 | if (ax < bx) {
379 | if (ay < by) {
380 | path.set(ax + aw, my, mx, my, mx, by);
381 | } else {
382 | path.set(ax + aw, my, mx, my, mx, by + bh);
383 | }
384 | } else {
385 | if (ay > by) {
386 | path.set(ax, my, mx, my, mx, by + bh);
387 | } else {
388 | path.set(ax, my, mx, my, mx, by);
389 | }
390 | }
391 | }
392 | }
393 | path.roomA = e.roomA;
394 | path.roomB = e.roomB;
395 | paths.add(path);
396 | }
397 |
398 | addHallwayRooms();
399 | }
400 |
401 | private void addHallwayRooms () {
402 | for (HallwayPath path : paths) {
403 | for (Room room : rooms) {
404 | if (room.isMain)
405 | continue;
406 | if (path.intersects(room)) {
407 | room.isHallway = true;
408 | }
409 | }
410 | }
411 |
412 | for (HallwayPath path : paths) {
413 | if (path.hasBend) {
414 | createRooms(path.hallA);
415 | createRooms(path.hallB);
416 | } else {
417 | createRooms(path.hallA);
418 | }
419 | }
420 | }
421 |
422 | private void createRooms (Rectangle r) {
423 | float grid = settings.getGridSize();
424 | float x = Utils.roundToSize(r.x, grid);
425 | float w = Utils.roundToSize(r.width, grid);
426 | float y = Utils.roundToSize(r.y, grid);
427 | float h = Utils.roundToSize(r.height, grid);
428 |
429 | int gw = (int)(w / grid);
430 | int gh = (int)(h / grid);
431 |
432 | for (int rx = 0; rx < gw; rx++) {
433 | for (int ry = 0; ry < gh; ry++) {
434 | createRoom(x + rx * grid, y + ry * grid, grid);
435 | }
436 | }
437 | }
438 |
439 | private void createRoom (float x, float y, float size) {
440 | if (findRoom(x + size / 2, y + size / 2) != null)
441 | return;
442 | Room room = new Room(roomID++, size);
443 | room.bounds.set(x, y, size, size);
444 | room.isExtra = true;
445 | rooms.add(room);
446 | }
447 |
448 | private Room getRoom (float cx, float cy) {
449 | for (Room room : mainRooms) {
450 | if (MathUtils.isEqual(cx, room.cx()) && MathUtils.isEqual(cy, room.cy())) {
451 | return room;
452 | }
453 | }
454 | return null;
455 | }
456 |
457 | private Room findRoom (float tx, float ty) {
458 | for (Room room : rooms) {
459 | if (room.bounds.contains(tx, ty))
460 | return room;
461 | }
462 | return null;
463 | }
464 |
465 | public void dispose () {
466 | b2d.dispose();
467 | }
468 |
469 | public String toJson (JsonWriter.OutputType outputType, boolean pretty) {
470 | Json json = new Json(outputType);
471 | StringWriter writer = new StringWriter();
472 | json.setWriter(writer);
473 | json.writeObjectStart();
474 | json.writeValue("grid-size", settings.getGridSize());
475 | json.writeArrayStart("rooms");
476 | for (Room room : rooms) {
477 | if (room.isUnused())
478 | continue;
479 | json.writeObjectStart();
480 | json.writeValue("id", room.id);
481 | if (room.isMain) {
482 | json.writeValue("type", "main");
483 | } else if (room.isHallway) {
484 | json.writeValue("type", "hallway");
485 | } else if (room.isExtra) {
486 | json.writeValue("type", "extra");
487 | }
488 | json.writeValue("bounds", room.bounds);
489 | json.writeObjectEnd();
490 | }
491 | json.writeArrayEnd();
492 | json.writeArrayStart("paths");
493 | for (HallwayPath path : paths) {
494 | json.writeObjectStart();
495 | json.writeValue("id", path.id);
496 | json.writeValue("start-room", path.roomA.id);
497 | json.writeValue("end-room", path.roomB.id);
498 | json.writeValue("start", path.start);
499 | if (path.hasBend) {
500 | json.writeValue("mid", path.bend);
501 | }
502 | json.writeValue("end", path.end);
503 | json.writeArrayStart("overlaps");
504 | for (Room room : path.overlap) {
505 | json.writeValue(room.id);
506 | }
507 | json.writeArrayEnd();
508 | json.writeObjectEnd();
509 | }
510 | json.writeArrayEnd();
511 | json.writeObjectEnd();
512 |
513 | if (pretty) {
514 | return json.prettyPrint(writer.toString());
515 | } else {
516 | return writer.toString();
517 | }
518 | }
519 | }
520 |
--------------------------------------------------------------------------------
/html/webapp/soundmanager2-jsmin.js:
--------------------------------------------------------------------------------
1 | /** @license
2 |
3 |
4 | SoundManager 2: JavaScript Sound for the Web
5 | ----------------------------------------------
6 | http://schillmania.com/projects/soundmanager2/
7 |
8 | Copyright (c) 2007, Scott Schiller. All rights reserved.
9 | Code provided under the BSD License:
10 | http://schillmania.com/projects/soundmanager2/license.txt
11 |
12 | V2.97a.20130512
13 | */
14 | (function (h, g) {
15 | function fa(fa, wa) {
16 | function ga(b) {
17 | return c.preferFlash && H && !c.ignoreFlash && c.flash[b] !== g && c.flash[b]
18 | }
19 |
20 | function s(b) {
21 | return function (d) {
22 | var e = this._s;
23 | !e || !e._a ? (e && e.id ? c._wD(e.id + ": Ignoring " + d.type) : c._wD(rb + "Ignoring " + d.type), d = null) : d = b.call(this, d);
24 | return d
25 | }
26 | }
27 |
28 | this.setupOptions = {
29 | url: fa || null,
30 | flashVersion: 8,
31 | debugMode: !0,
32 | debugFlash: !1,
33 | useConsole: !0,
34 | consoleOnly: !0,
35 | waitForWindowLoad: !1,
36 | bgColor: "#ffffff",
37 | useHighPerformance: !1,
38 | flashPollingInterval: null,
39 | html5PollingInterval: null,
40 | flashLoadTimeout: 1E3,
41 | wmode: null,
42 | allowScriptAccess: "always",
43 | useFlashBlock: !1,
44 | useHTML5Audio: !0,
45 | html5Test: /^(probably|maybe)$/i,
46 | preferFlash: !0,
47 | noSWFCache: !1,
48 | idPrefix: "sound"
49 | };
50 | this.defaultOptions = {
51 | autoLoad: !1,
52 | autoPlay: !1,
53 | from: null,
54 | loops: 1,
55 | onid3: null,
56 | onload: null,
57 | whileloading: null,
58 | onplay: null,
59 | onpause: null,
60 | onresume: null,
61 | whileplaying: null,
62 | onposition: null,
63 | onstop: null,
64 | onfailure: null,
65 | onfinish: null,
66 | multiShot: !0,
67 | multiShotEvents: !1,
68 | position: null,
69 | pan: 0,
70 | stream: !0,
71 | to: null,
72 | type: null,
73 | usePolicyFile: !1,
74 | volume: 100
75 | };
76 | this.flash9Options = {
77 | isMovieStar: null,
78 | usePeakData: !1, useWaveformData: !1, useEQData: !1, onbufferchange: null, ondataerror: null
79 | };
80 | this.movieStarOptions = {bufferTime: 3, serverURL: null, onconnect: null, duration: null};
81 | this.audioFormats = {
82 | mp3: {
83 | type: ['audio/mpeg; codecs\x3d"mp3"', "audio/mpeg", "audio/mp3", "audio/MPA", "audio/mpa-robust"],
84 | required: !0
85 | },
86 | mp4: {
87 | related: ["aac", "m4a", "m4b"],
88 | type: ['audio/mp4; codecs\x3d"mp4a.40.2"', "audio/aac", "audio/x-m4a", "audio/MP4A-LATM", "audio/mpeg4-generic"],
89 | required: !1
90 | },
91 | ogg: {type: ["audio/ogg; codecs\x3dvorbis"], required: !1},
92 | opus: {type: ["audio/ogg; codecs\x3dopus", "audio/opus"], required: !1},
93 | wav: {type: ['audio/wav; codecs\x3d"1"', "audio/wav", "audio/wave", "audio/x-wav"], required: !1}
94 | };
95 | this.movieID = "sm2-container";
96 | this.id = wa || "sm2movie";
97 | this.debugID = "soundmanager-debug";
98 | this.debugURLParam = /([#?&])debug=1/i;
99 | this.versionNumber = "V2.97a.20130512";
100 | this.altURL = this.movieURL = this.version = null;
101 | this.enabled = this.swfLoaded = !1;
102 | this.oMC = null;
103 | this.sounds = {};
104 | this.soundIDs = [];
105 | this.didFlashBlock = this.muted = !1;
106 | this.filePattern = null;
107 | this.filePatterns =
108 | {flash8: /\.mp3(\?.*)?$/i, flash9: /\.mp3(\?.*)?$/i};
109 | this.features = {buffering: !1, peakData: !1, waveformData: !1, eqData: !1, movieStar: !1};
110 | this.sandbox = {
111 | type: null,
112 | types: {
113 | remote: "remote (domain-based) rules",
114 | localWithFile: "local with file access (no internet access)",
115 | localWithNetwork: "local with network (internet access only, no local access)",
116 | localTrusted: "local, trusted (local+internet access)"
117 | },
118 | description: null,
119 | noRemote: null,
120 | noLocal: null
121 | };
122 | this.html5 = {usingFlash: null};
123 | this.flash = {};
124 | this.ignoreFlash = this.html5Only = !1;
125 | var Ua, c = this, Va = null, k = null, rb = "HTML5::", A, t = navigator.userAgent, U = h.location.href.toString(), m = document, xa, Wa, ya, n, F = [], za = !0, C, V = !1, W = !1, q = !1, y = !1, ha = !1, p, sb = 0, X, B, Aa, O, Ba, M, P, Q, Xa, Ca, ia, I, ja, Da, R, Ea, Y, ka, la, S, Ya, Fa, Za = ["log", "info", "warn", "error"], $a, Ga, ab, Z = null, Ha = null, r, Ia, T, bb, ma, na, J, v, $ = !1, Ja = !1, cb, db, eb, oa = 0, aa = null, pa, N = [], qa, u = null, fb, ra, ba, K, sa, Ka, gb, w, hb = Array.prototype.slice, E = !1, La, H, Ma, ib, G, jb, Na, ta, kb = 0, ca = t.match(/(ipad|iphone|ipod)/i), lb = t.match(/android/i), L = t.match(/msie/i),
126 | tb = t.match(/webkit/i), ua = t.match(/safari/i) && !t.match(/chrome/i), Oa = t.match(/opera/i), ub = t.match(/firefox/i), Pa = t.match(/(mobile|pre\/|xoom)/i) || ca || lb, Qa = !U.match(/usehtml5audio/i) && !U.match(/sm2\-ignorebadua/i) && ua && !t.match(/silk/i) && t.match(/OS X 10_6_([3-7])/i), da = h.console !== g && console.log !== g, Ra = m.hasFocus !== g ? m.hasFocus() : null, va = ua && (m.hasFocus === g || !m.hasFocus()), mb = !va, nb = /(mp3|mp4|mpa|m4a|m4b)/i, ea = m.location ? m.location.protocol.match(/http/i) : null, ob = !ea ? "http://" : "", pb = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,
127 | qb = "mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "), vb = RegExp("\\.(" + qb.join("|") + ")(\\?.*)?$", "i");
128 | this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;
129 | this.useAltURL = !ea;
130 | var Sa;
131 | try {
132 | Sa = Audio !== g && (Oa && opera !== g && 10 > opera.version() ? new Audio(null) : new Audio).canPlayType !== g
133 | } catch (wb) {
134 | Sa = !1
135 | }
136 | this.hasHTML5 = Sa;
137 | this.setup = function (b) {
138 | var d = !c.url;
139 | b !== g && (q && u && c.ok() && (b.flashVersion !== g || b.url !== g || b.html5Test !== g)) && J(r("setupLate"));
140 | Aa(b);
141 | b && (d && (Y && b.url !== g) && c.beginDelayedInit(),
142 | !Y && (b.url !== g && "complete" === m.readyState) && setTimeout(R, 1));
143 | return c
144 | };
145 | this.supported = this.ok = function () {
146 | return u ? q && !y : c.useHTML5Audio && c.hasHTML5
147 | };
148 | this.getMovie = function (c) {
149 | return A(c) || m[c] || h[c]
150 | };
151 | this.createSound = function (b, d) {
152 | function e() {
153 | f = ma(f);
154 | c.sounds[f.id] = new Ua(f);
155 | c.soundIDs.push(f.id);
156 | return c.sounds[f.id]
157 | }
158 |
159 | var a, f;
160 | a = null;
161 | a = "soundManager.createSound(): " + r(!q ? "notReady" : "notOK");
162 | if (!q || !c.ok())return J(a), !1;
163 | d !== g && (b = {id: b, url: d});
164 | f = B(b);
165 | f.url = pa(f.url);
166 | void 0 === f.id && (f.id = c.setupOptions.idPrefix +
167 | kb++);
168 | f.id.toString().charAt(0).match(/^[0-9]$/) && c._wD("soundManager.createSound(): " + r("badID", f.id), 2);
169 | c._wD("soundManager.createSound(): " + f.id + (f.url ? " (" + f.url + ")" : ""), 1);
170 | if (v(f.id, !0))return c._wD("soundManager.createSound(): " + f.id + " exists", 1), c.sounds[f.id];
171 | if (ra(f))a = e(), c._wD(f.id + ": Using HTML5"), a._setup_html5(f); else {
172 | if (c.html5Only)return c._wD(f.id + ": No HTML5 support for this sound, and no Flash. Exiting."), e();
173 | if (c.html5.usingFlash && f.url && f.url.match(/data\:/i))return c._wD(f.id +
174 | ": data: URIs not supported via Flash. Exiting."), e();
175 | 8 < n && (null === f.isMovieStar && (f.isMovieStar = !(!f.serverURL && !(f.type && f.type.match(pb) || f.url && f.url.match(vb)))), f.isMovieStar && (c._wD("soundManager.createSound(): using MovieStar handling"), 1 < f.loops && p("noNSLoop")));
176 | f = na(f, "soundManager.createSound(): ");
177 | a = e();
178 | 8 === n ? k._createSound(f.id, f.loops || 1, f.usePolicyFile) : (k._createSound(f.id, f.url, f.usePeakData, f.useWaveformData, f.useEQData, f.isMovieStar, f.isMovieStar ? f.bufferTime : !1, f.loops || 1, f.serverURL,
179 | f.duration || null, f.autoPlay, !0, f.autoLoad, f.usePolicyFile), f.serverURL || (a.connected = !0, f.onconnect && f.onconnect.apply(a)));
180 | !f.serverURL && (f.autoLoad || f.autoPlay) && a.load(f)
181 | }
182 | !f.serverURL && f.autoPlay && a.play();
183 | return a
184 | };
185 | this.destroySound = function (b, d) {
186 | if (!v(b))return !1;
187 | var e = c.sounds[b], a;
188 | e._iO = {};
189 | e.stop();
190 | e.unload();
191 | for (a = 0; a < c.soundIDs.length; a++)if (c.soundIDs[a] === b) {
192 | c.soundIDs.splice(a, 1);
193 | break
194 | }
195 | d || e.destruct(!0);
196 | delete c.sounds[b];
197 | return !0
198 | };
199 | this.load = function (b, d) {
200 | return !v(b) ? !1 : c.sounds[b].load(d)
201 | };
202 | this.unload = function (b) {
203 | return !v(b) ? !1 : c.sounds[b].unload()
204 | };
205 | this.onposition = this.onPosition = function (b, d, e, a) {
206 | return !v(b) ? !1 : c.sounds[b].onposition(d, e, a)
207 | };
208 | this.clearOnPosition = function (b, d, e) {
209 | return !v(b) ? !1 : c.sounds[b].clearOnPosition(d, e)
210 | };
211 | this.start = this.play = function (b, d) {
212 | var e = null, a = d && !(d instanceof Object);
213 | if (!q || !c.ok())return J("soundManager.play(): " + r(!q ? "notReady" : "notOK")), !1;
214 | if (v(b, a))a && (d = {url: d}); else {
215 | if (!a)return !1;
216 | a && (d = {url: d});
217 | d && d.url && (c._wD('soundManager.play(): Attempting to create "' +
218 | b + '"', 1), d.id = b, e = c.createSound(d).play())
219 | }
220 | null === e && (e = c.sounds[b].play(d));
221 | return e
222 | };
223 | this.setPosition = function (b, d) {
224 | return !v(b) ? !1 : c.sounds[b].setPosition(d)
225 | };
226 | this.stop = function (b) {
227 | if (!v(b))return !1;
228 | c._wD("soundManager.stop(" + b + ")", 1);
229 | return c.sounds[b].stop()
230 | };
231 | this.stopAll = function () {
232 | var b;
233 | c._wD("soundManager.stopAll()", 1);
234 | for (b in c.sounds)c.sounds.hasOwnProperty(b) && c.sounds[b].stop()
235 | };
236 | this.pause = function (b) {
237 | return !v(b) ? !1 : c.sounds[b].pause()
238 | };
239 | this.pauseAll = function () {
240 | var b;
241 | for (b = c.soundIDs.length -
242 | 1; 0 <= b; b--)c.sounds[c.soundIDs[b]].pause()
243 | };
244 | this.resume = function (b) {
245 | return !v(b) ? !1 : c.sounds[b].resume()
246 | };
247 | this.resumeAll = function () {
248 | var b;
249 | for (b = c.soundIDs.length - 1; 0 <= b; b--)c.sounds[c.soundIDs[b]].resume()
250 | };
251 | this.togglePause = function (b) {
252 | return !v(b) ? !1 : c.sounds[b].togglePause()
253 | };
254 | this.setPan = function (b, d) {
255 | return !v(b) ? !1 : c.sounds[b].setPan(d)
256 | };
257 | this.setVolume = function (b, d) {
258 | return !v(b) ? !1 : c.sounds[b].setVolume(d)
259 | };
260 | this.mute = function (b) {
261 | var d = 0;
262 | b instanceof String && (b = null);
263 | if (b) {
264 | if (!v(b))return !1;
265 | c._wD('soundManager.mute(): Muting "' +
266 | b + '"');
267 | return c.sounds[b].mute()
268 | }
269 | c._wD("soundManager.mute(): Muting all sounds");
270 | for (d = c.soundIDs.length - 1; 0 <= d; d--)c.sounds[c.soundIDs[d]].mute();
271 | return c.muted = !0
272 | };
273 | this.muteAll = function () {
274 | c.mute()
275 | };
276 | this.unmute = function (b) {
277 | b instanceof String && (b = null);
278 | if (b) {
279 | if (!v(b))return !1;
280 | c._wD('soundManager.unmute(): Unmuting "' + b + '"');
281 | return c.sounds[b].unmute()
282 | }
283 | c._wD("soundManager.unmute(): Unmuting all sounds");
284 | for (b = c.soundIDs.length - 1; 0 <= b; b--)c.sounds[c.soundIDs[b]].unmute();
285 | c.muted = !1;
286 | return !0
287 | };
288 | this.unmuteAll =
289 | function () {
290 | c.unmute()
291 | };
292 | this.toggleMute = function (b) {
293 | return !v(b) ? !1 : c.sounds[b].toggleMute()
294 | };
295 | this.getMemoryUse = function () {
296 | var c = 0;
297 | k && 8 !== n && (c = parseInt(k._getMemoryUse(), 10));
298 | return c
299 | };
300 | this.disable = function (b) {
301 | var d;
302 | b === g && (b = !1);
303 | if (y)return !1;
304 | y = !0;
305 | p("shutdown", 1);
306 | for (d = c.soundIDs.length - 1; 0 <= d; d--)$a(c.sounds[c.soundIDs[d]]);
307 | X(b);
308 | w.remove(h, "load", P);
309 | return !0
310 | };
311 | this.canPlayMIME = function (b) {
312 | var d;
313 | c.hasHTML5 && (d = ba({type: b}));
314 | !d && u && (d = b && c.ok() ? !!(8 < n && b.match(pb) || b.match(c.mimePattern)) : null);
315 | return d
316 | };
317 | this.canPlayURL = function (b) {
318 | var d;
319 | c.hasHTML5 && (d = ba({url: b}));
320 | !d && u && (d = b && c.ok() ? !!b.match(c.filePattern) : null);
321 | return d
322 | };
323 | this.canPlayLink = function (b) {
324 | return b.type !== g && b.type && c.canPlayMIME(b.type) ? !0 : c.canPlayURL(b.href)
325 | };
326 | this.getSoundById = function (b, d) {
327 | if (!b)return null;
328 | var e = c.sounds[b];
329 | !e && !d && c._wD('soundManager.getSoundById(): Sound "' + b + '" not found.', 2);
330 | return e
331 | };
332 | this.onready = function (b, d) {
333 | if ("function" === typeof b)q && c._wD(r("queue", "onready")), d || (d = h), Ba("onready", b, d), M(); else throw r("needFunction",
334 | "onready");
335 | return !0
336 | };
337 | this.ontimeout = function (b, d) {
338 | if ("function" === typeof b)q && c._wD(r("queue", "ontimeout")), d || (d = h), Ba("ontimeout", b, d), M({type: "ontimeout"}); else throw r("needFunction", "ontimeout");
339 | return !0
340 | };
341 | this._writeDebug = function (b, d) {
342 | var e, a;
343 | if (!c.debugMode)return !1;
344 | if (da && c.useConsole) {
345 | if (d && "object" === typeof d)console.log(b, d); else if (Za[d] !== g)console[Za[d]](b); else console.log(b);
346 | if (c.consoleOnly)return !0
347 | }
348 | e = A("soundmanager-debug");
349 | if (!e)return !1;
350 | a = m.createElement("div");
351 | 0 === ++sb % 2 && (a.className =
352 | "sm2-alt");
353 | d = d === g ? 0 : parseInt(d, 10);
354 | a.appendChild(m.createTextNode(b));
355 | d && (2 <= d && (a.style.fontWeight = "bold"), 3 === d && (a.style.color = "#ff3333"));
356 | e.insertBefore(a, e.firstChild);
357 | return !0
358 | };
359 | -1 !== U.indexOf("sm2-debug\x3dalert") && (this._writeDebug = function (c) {
360 | h.alert(c)
361 | });
362 | this._wD = this._writeDebug;
363 | this._debug = function () {
364 | var b, d;
365 | p("currentObj", 1);
366 | b = 0;
367 | for (d = c.soundIDs.length; b < d; b++)c.sounds[c.soundIDs[b]]._debug()
368 | };
369 | this.reboot = function (b, d) {
370 | c.soundIDs.length && c._wD("Destroying " + c.soundIDs.length + " SMSound object" +
371 | (1 !== c.soundIDs.length ? "s" : "") + "...");
372 | var e, a, f;
373 | for (e = c.soundIDs.length - 1; 0 <= e; e--)c.sounds[c.soundIDs[e]].destruct();
374 | if (k)try {
375 | L && (Ha = k.innerHTML), Z = k.parentNode.removeChild(k)
376 | } catch (g) {
377 | p("badRemove", 2)
378 | }
379 | Ha = Z = u = k = null;
380 | c.enabled = Y = q = $ = Ja = V = W = y = E = c.swfLoaded = !1;
381 | c.soundIDs = [];
382 | c.sounds = {};
383 | kb = 0;
384 | if (b)F = []; else for (e in F)if (F.hasOwnProperty(e)) {
385 | a = 0;
386 | for (f = F[e].length; a < f; a++)F[e][a].fired = !1
387 | }
388 | d || c._wD("soundManager: Rebooting...");
389 | c.html5 = {usingFlash: null};
390 | c.flash = {};
391 | c.html5Only = !1;
392 | c.ignoreFlash = !1;
393 | h.setTimeout(function () {
394 | Da();
395 | d || c.beginDelayedInit()
396 | }, 20);
397 | return c
398 | };
399 | this.reset = function () {
400 | p("reset");
401 | return c.reboot(!0, !0)
402 | };
403 | this.getMoviePercent = function () {
404 | return k && "PercentLoaded"in k ? k.PercentLoaded() : null
405 | };
406 | this.beginDelayedInit = function () {
407 | ha = !0;
408 | R();
409 | setTimeout(function () {
410 | if (Ja)return !1;
411 | la();
412 | ja();
413 | return Ja = !0
414 | }, 20);
415 | Q()
416 | };
417 | this.destruct = function () {
418 | c._wD("soundManager.destruct()");
419 | c.disable(!0)
420 | };
421 | Ua = function (b) {
422 | var d, e, a = this, f, h, z, l, m, q, s = !1, D = [], t = 0, Ta, y, u = null, A;
423 | e = d = null;
424 | this.sID = this.id = b.id;
425 | this.url = b.url;
426 | this._iO = this.instanceOptions =
427 | this.options = B(b);
428 | this.pan = this.options.pan;
429 | this.volume = this.options.volume;
430 | this.isHTML5 = !1;
431 | this._a = null;
432 | A = this.url ? !1 : !0;
433 | this.id3 = {};
434 | this._debug = function () {
435 | c._wD(a.id + ": Merged options:", a.options)
436 | };
437 | this.load = function (b) {
438 | var d = null, e;
439 | b !== g ? a._iO = B(b, a.options) : (b = a.options, a._iO = b, u && u !== a.url && (p("manURL"), a._iO.url = a.url, a.url = null));
440 | a._iO.url || (a._iO.url = a.url);
441 | a._iO.url = pa(a._iO.url);
442 | e = a.instanceOptions = a._iO;
443 | c._wD(a.id + ": load (" + e.url + ")");
444 | if (!e.url && !a.url)return c._wD(a.id + ": load(): url is unassigned. Exiting.",
445 | 2), a;
446 | !a.isHTML5 && (8 === n && !a.url && !e.autoPlay) && c._wD(a.id + ": Flash 8 load() limitation: Wait for onload() before calling play().", 1);
447 | if (e.url === a.url && 0 !== a.readyState && 2 !== a.readyState)return p("onURL", 1), 3 === a.readyState && e.onload && ta(a, function () {
448 | e.onload.apply(a, [!!a.duration])
449 | }), a;
450 | a.loaded = !1;
451 | a.readyState = 1;
452 | a.playState = 0;
453 | a.id3 = {};
454 | if (ra(e))d = a._setup_html5(e), d._called_load ? c._wD(a.id + ": Ignoring request to load again") : (a._html5_canplay = !1, a.url !== e.url && (c._wD(p("manURL") + ": " + e.url), a._a.src =
455 | e.url, a.setPosition(0)), a._a.autobuffer = "auto", a._a.preload = "auto", a._a._called_load = !0, e.autoPlay && a.play()); else {
456 | if (c.html5Only)return c._wD(a.id + ": No flash support. Exiting."), a;
457 | if (a._iO.url && a._iO.url.match(/data\:/i))return c._wD(a.id + ": data: URIs not supported via Flash. Exiting."), a;
458 | try {
459 | a.isHTML5 = !1, a._iO = na(ma(e)), e = a._iO, 8 === n ? k._load(a.id, e.url, e.stream, e.autoPlay, e.usePolicyFile) : k._load(a.id, e.url, !!e.stream, !!e.autoPlay, e.loops || 1, !!e.autoLoad, e.usePolicyFile)
460 | } catch (f) {
461 | p("smError",
462 | 2), C("onload", !1), S({type: "SMSOUND_LOAD_JS_EXCEPTION", fatal: !0})
463 | }
464 | }
465 | a.url = e.url;
466 | return a
467 | };
468 | this.unload = function () {
469 | 0 !== a.readyState && (c._wD(a.id + ": unload()"), a.isHTML5 ? (l(), a._a && (a._a.pause(), u = sa(a._a))) : 8 === n ? k._unload(a.id, "about:blank") : k._unload(a.id), f());
470 | return a
471 | };
472 | this.destruct = function (b) {
473 | c._wD(a.id + ": Destruct");
474 | a.isHTML5 ? (l(), a._a && (a._a.pause(), sa(a._a), E || z(), a._a._s = null, a._a = null)) : (a._iO.onfailure = null, k._destroySound(a.id));
475 | b || c.destroySound(a.id, !0)
476 | };
477 | this.start = this.play = function (b,
478 | d) {
479 | var e, f, l, z, h, x = !0, x = null;
480 | e = a.id + ": play(): ";
481 | d = d === g ? !0 : d;
482 | b || (b = {});
483 | a.url && (a._iO.url = a.url);
484 | a._iO = B(a._iO, a.options);
485 | a._iO = B(b, a._iO);
486 | a._iO.url = pa(a._iO.url);
487 | a.instanceOptions = a._iO;
488 | if (!a.isHTML5 && a._iO.serverURL && !a.connected)return a.getAutoPlay() || (c._wD(e + " Netstream not connected yet - setting autoPlay"), a.setAutoPlay(!0)), a;
489 | ra(a._iO) && (a._setup_html5(a._iO), m());
490 | 1 === a.playState && !a.paused && ((f = a._iO.multiShot) ? c._wD(e + "Already playing (multi-shot)", 1) : (c._wD(e + "Already playing (one-shot)",
491 | 1), a.isHTML5 && a.setPosition(a._iO.position), x = a));
492 | if (null !== x)return x;
493 | b.url && b.url !== a.url && (!a.readyState && !a.isHTML5 && 8 === n && A ? A = !1 : a.load(a._iO));
494 | a.loaded ? c._wD(e.substr(0, e.lastIndexOf(":"))) : 0 === a.readyState ? (c._wD(e + "Attempting to load"), !a.isHTML5 && !c.html5Only ? (a._iO.autoPlay = !0, a.load(a._iO)) : a.isHTML5 ? a.load(a._iO) : (c._wD(e + "Unsupported type. Exiting."), x = a), a.instanceOptions = a._iO) : 2 === a.readyState ? (c._wD(e + "Could not load - exiting", 2), x = a) : c._wD(e + "Loading - attempting to play...");
495 | if (null !== x)return x;
496 | !a.isHTML5 && (9 === n && 0 < a.position && a.position === a.duration) && (c._wD(e + "Sound at end, resetting to position:0"), b.position = 0);
497 | if (a.paused && 0 <= a.position && (!a._iO.serverURL || 0 < a.position))c._wD(e + "Resuming from paused state", 1), a.resume(); else {
498 | a._iO = B(b, a._iO);
499 | if (null !== a._iO.from && null !== a._iO.to && 0 === a.instanceCount && 0 === a.playState && !a._iO.serverURL) {
500 | f = function () {
501 | a._iO = B(b, a._iO);
502 | a.play(a._iO)
503 | };
504 | if (a.isHTML5 && !a._html5_canplay)c._wD(e + "Beginning load for from/to case"), a.load({oncanplay: f}),
505 | x = !1; else if (!a.isHTML5 && !a.loaded && (!a.readyState || 2 !== a.readyState))c._wD(e + "Preloading for from/to case"), a.load({onload: f}), x = !1;
506 | if (null !== x)return x;
507 | a._iO = y()
508 | }
509 | (!a.instanceCount || a._iO.multiShotEvents || a.isHTML5 && a._iO.multiShot && !E || !a.isHTML5 && 8 < n && !a.getAutoPlay()) && a.instanceCount++;
510 | a._iO.onposition && 0 === a.playState && q(a);
511 | a.playState = 1;
512 | a.paused = !1;
513 | a.position = a._iO.position !== g && !isNaN(a._iO.position) ? a._iO.position : 0;
514 | a.isHTML5 || (a._iO = na(ma(a._iO)));
515 | a._iO.onplay && d && (a._iO.onplay.apply(a),
516 | s = !0);
517 | a.setVolume(a._iO.volume, !0);
518 | a.setPan(a._iO.pan, !0);
519 | a.isHTML5 ? 2 > a.instanceCount ? (m(), e = a._setup_html5(), a.setPosition(a._iO.position), e.play()) : (c._wD(a.id + ": Cloning Audio() for instance #" + a.instanceCount + "..."), l = new Audio(a._iO.url), z = function () {
520 | w.remove(l, "onended", z);
521 | a._onfinish(a);
522 | sa(l);
523 | l = null
524 | }, h = function () {
525 | w.remove(l, "canplay", h);
526 | try {
527 | l.currentTime = a._iO.position / 1E3
528 | } catch (c) {
529 | J(a.id + ": multiShot play() failed to apply position of " + a._iO.position / 1E3)
530 | }
531 | l.play()
532 | }, w.add(l, "ended", z), a._iO.position ?
533 | w.add(l, "canplay", h) : l.play()) : (x = k._start(a.id, a._iO.loops || 1, 9 === n ? a.position : a.position / 1E3, a._iO.multiShot || !1), 9 === n && !x && (c._wD(e + "No sound hardware, or 32-sound ceiling hit", 2), a._iO.onplayerror && a._iO.onplayerror.apply(a)))
534 | }
535 | return a
536 | };
537 | this.stop = function (b) {
538 | var d = a._iO;
539 | 1 === a.playState && (c._wD(a.id + ": stop()"), a._onbufferchange(0), a._resetOnPosition(0), a.paused = !1, a.isHTML5 || (a.playState = 0), Ta(), d.to && a.clearOnPosition(d.to), a.isHTML5 ? a._a && (b = a.position, a.setPosition(0), a.position = b, a._a.pause(),
540 | a.playState = 0, a._onTimer(), l()) : (k._stop(a.id, b), d.serverURL && a.unload()), a.instanceCount = 0, a._iO = {}, d.onstop && d.onstop.apply(a));
541 | return a
542 | };
543 | this.setAutoPlay = function (b) {
544 | c._wD(a.id + ": Autoplay turned " + (b ? "on" : "off"));
545 | a._iO.autoPlay = b;
546 | a.isHTML5 || (k._setAutoPlay(a.id, b), b && (!a.instanceCount && 1 === a.readyState) && (a.instanceCount++, c._wD(a.id + ": Incremented instance count to " + a.instanceCount)))
547 | };
548 | this.getAutoPlay = function () {
549 | return a._iO.autoPlay
550 | };
551 | this.setPosition = function (b) {
552 | b === g && (b = 0);
553 | var d = a.isHTML5 ?
554 | Math.max(b, 0) : Math.min(a.duration || a._iO.duration, Math.max(b, 0));
555 | a.position = d;
556 | b = a.position / 1E3;
557 | a._resetOnPosition(a.position);
558 | a._iO.position = d;
559 | if (a.isHTML5) {
560 | if (a._a) {
561 | if (a._html5_canplay) {
562 | if (a._a.currentTime !== b) {
563 | c._wD(a.id + ": setPosition(" + b + ")");
564 | try {
565 | a._a.currentTime = b, (0 === a.playState || a.paused) && a._a.pause()
566 | } catch (e) {
567 | c._wD(a.id + ": setPosition(" + b + ") failed: " + e.message, 2)
568 | }
569 | }
570 | } else if (b)return c._wD(a.id + ": setPosition(" + b + "): Cannot seek yet, sound not ready", 2), a;
571 | a.paused && a._onTimer(!0)
572 | }
573 | } else b =
574 | 9 === n ? a.position : b, a.readyState && 2 !== a.readyState && k._setPosition(a.id, b, a.paused || !a.playState, a._iO.multiShot);
575 | return a
576 | };
577 | this.pause = function (b) {
578 | if (a.paused || 0 === a.playState && 1 !== a.readyState)return a;
579 | c._wD(a.id + ": pause()");
580 | a.paused = !0;
581 | a.isHTML5 ? (a._setup_html5().pause(), l()) : (b || b === g) && k._pause(a.id, a._iO.multiShot);
582 | a._iO.onpause && a._iO.onpause.apply(a);
583 | return a
584 | };
585 | this.resume = function () {
586 | var b = a._iO;
587 | if (!a.paused)return a;
588 | c._wD(a.id + ": resume()");
589 | a.paused = !1;
590 | a.playState = 1;
591 | a.isHTML5 ? (a._setup_html5().play(),
592 | m()) : (b.isMovieStar && !b.serverURL && a.setPosition(a.position), k._pause(a.id, b.multiShot));
593 | !s && b.onplay ? (b.onplay.apply(a), s = !0) : b.onresume && b.onresume.apply(a);
594 | return a
595 | };
596 | this.togglePause = function () {
597 | c._wD(a.id + ": togglePause()");
598 | if (0 === a.playState)return a.play({position: 9 === n && !a.isHTML5 ? a.position : a.position / 1E3}), a;
599 | a.paused ? a.resume() : a.pause();
600 | return a
601 | };
602 | this.setPan = function (b, c) {
603 | b === g && (b = 0);
604 | c === g && (c = !1);
605 | a.isHTML5 || k._setPan(a.id, b);
606 | a._iO.pan = b;
607 | c || (a.pan = b, a.options.pan = b);
608 | return a
609 | };
610 | this.setVolume =
611 | function (b, d) {
612 | b === g && (b = 100);
613 | d === g && (d = !1);
614 | a.isHTML5 ? a._a && (a._a.volume = Math.max(0, Math.min(1, b / 100))) : k._setVolume(a.id, c.muted && !a.muted || a.muted ? 0 : b);
615 | a._iO.volume = b;
616 | d || (a.volume = b, a.options.volume = b);
617 | return a
618 | };
619 | this.mute = function () {
620 | a.muted = !0;
621 | a.isHTML5 ? a._a && (a._a.muted = !0) : k._setVolume(a.id, 0);
622 | return a
623 | };
624 | this.unmute = function () {
625 | a.muted = !1;
626 | var b = a._iO.volume !== g;
627 | a.isHTML5 ? a._a && (a._a.muted = !1) : k._setVolume(a.id, b ? a._iO.volume : a.options.volume);
628 | return a
629 | };
630 | this.toggleMute = function () {
631 | return a.muted ? a.unmute() :
632 | a.mute()
633 | };
634 | this.onposition = this.onPosition = function (b, c, d) {
635 | D.push({position: parseInt(b, 10), method: c, scope: d !== g ? d : a, fired: !1});
636 | return a
637 | };
638 | this.clearOnPosition = function (a, b) {
639 | var c;
640 | a = parseInt(a, 10);
641 | if (isNaN(a))return !1;
642 | for (c = 0; c < D.length; c++)if (a === D[c].position && (!b || b === D[c].method))D[c].fired && t--, D.splice(c, 1)
643 | };
644 | this._processOnPosition = function () {
645 | var b, c;
646 | b = D.length;
647 | if (!b || !a.playState || t >= b)return !1;
648 | for (b -= 1; 0 <= b; b--)c = D[b], !c.fired && a.position >= c.position && (c.fired = !0, t++, c.method.apply(c.scope, [c.position]));
649 | return !0
650 | };
651 | this._resetOnPosition = function (a) {
652 | var b, c;
653 | b = D.length;
654 | if (!b)return !1;
655 | for (b -= 1; 0 <= b; b--)c = D[b], c.fired && a <= c.position && (c.fired = !1, t--);
656 | return !0
657 | };
658 | y = function () {
659 | var b = a._iO, d = b.from, e = b.to, f, g;
660 | g = function () {
661 | c._wD(a.id + ': "To" time of ' + e + " reached.");
662 | a.clearOnPosition(e, g);
663 | a.stop()
664 | };
665 | f = function () {
666 | c._wD(a.id + ': Playing "from" ' + d);
667 | if (null !== e && !isNaN(e))a.onPosition(e, g)
668 | };
669 | null !== d && !isNaN(d) && (b.position = d, b.multiShot = !1, f());
670 | return b
671 | };
672 | q = function () {
673 | var b, c = a._iO.onposition;
674 | if (c)for (b in c)if (c.hasOwnProperty(b))a.onPosition(parseInt(b,
675 | 10), c[b])
676 | };
677 | Ta = function () {
678 | var b, c = a._iO.onposition;
679 | if (c)for (b in c)c.hasOwnProperty(b) && a.clearOnPosition(parseInt(b, 10))
680 | };
681 | m = function () {
682 | a.isHTML5 && cb(a)
683 | };
684 | l = function () {
685 | a.isHTML5 && db(a)
686 | };
687 | f = function (b) {
688 | b || (D = [], t = 0);
689 | s = !1;
690 | a._hasTimer = null;
691 | a._a = null;
692 | a._html5_canplay = !1;
693 | a.bytesLoaded = null;
694 | a.bytesTotal = null;
695 | a.duration = a._iO && a._iO.duration ? a._iO.duration : null;
696 | a.durationEstimate = null;
697 | a.buffered = [];
698 | a.eqData = [];
699 | a.eqData.left = [];
700 | a.eqData.right = [];
701 | a.failures = 0;
702 | a.isBuffering = !1;
703 | a.instanceOptions = {};
704 | a.instanceCount =
705 | 0;
706 | a.loaded = !1;
707 | a.metadata = {};
708 | a.readyState = 0;
709 | a.muted = !1;
710 | a.paused = !1;
711 | a.peakData = {left: 0, right: 0};
712 | a.waveformData = {left: [], right: []};
713 | a.playState = 0;
714 | a.position = null;
715 | a.id3 = {}
716 | };
717 | f();
718 | this._onTimer = function (b) {
719 | var c, f = !1, g = {};
720 | if (a._hasTimer || b) {
721 | if (a._a && (b || (0 < a.playState || 1 === a.readyState) && !a.paused))c = a._get_html5_duration(), c !== d && (d = c, a.duration = c, f = !0), a.durationEstimate = a.duration, c = 1E3 * a._a.currentTime || 0, c !== e && (e = c, f = !0), (f || b) && a._whileplaying(c, g, g, g, g);
722 | return f
723 | }
724 | };
725 | this._get_html5_duration = function () {
726 | var b =
727 | a._iO;
728 | return (b = a._a && a._a.duration ? 1E3 * a._a.duration : b && b.duration ? b.duration : null) && !isNaN(b) && Infinity !== b ? b : null
729 | };
730 | this._apply_loop = function (a, b) {
731 | !a.loop && 1 < b && c._wD("Note: Native HTML5 looping is infinite.", 1);
732 | a.loop = 1 < b ? "loop" : ""
733 | };
734 | this._setup_html5 = function (b) {
735 | b = B(a._iO, b);
736 | var c = E ? Va : a._a, d = decodeURI(b.url), e;
737 | E ? d === decodeURI(La) && (e = !0) : d === decodeURI(u) && (e = !0);
738 | if (c) {
739 | if (c._s)if (E)c._s && (c._s.playState && !e) && c._s.stop(); else if (!E && d === decodeURI(u))return a._apply_loop(c, b.loops), c;
740 | e || (f(!1), c.src =
741 | b.url, La = u = a.url = b.url, c._called_load = !1)
742 | } else a._a = b.autoLoad || b.autoPlay ? new Audio(b.url) : Oa && 10 > opera.version() ? new Audio(null) : new Audio, c = a._a, c._called_load = !1, E && (Va = c);
743 | a.isHTML5 = !0;
744 | a._a = c;
745 | c._s = a;
746 | h();
747 | a._apply_loop(c, b.loops);
748 | b.autoLoad || b.autoPlay ? a.load() : (c.autobuffer = !1, c.preload = "auto");
749 | return c
750 | };
751 | h = function () {
752 | if (a._a._added_events)return !1;
753 | var b;
754 | a._a._added_events = !0;
755 | for (b in G)G.hasOwnProperty(b) && a._a && a._a.addEventListener(b, G[b], !1);
756 | return !0
757 | };
758 | z = function () {
759 | var b;
760 | c._wD(a.id + ": Removing event listeners");
761 | a._a._added_events = !1;
762 | for (b in G)G.hasOwnProperty(b) && a._a && a._a.removeEventListener(b, G[b], !1)
763 | };
764 | this._onload = function (b) {
765 | var d = !!b || !a.isHTML5 && 8 === n && a.duration;
766 | b = a.id + ": ";
767 | c._wD(b + (d ? "onload()" : "Failed to load / invalid sound?" + (!a.duration ? " Zero-length duration reported." : " -") + " (" + a.url + ")"), d ? 1 : 2);
768 | !d && !a.isHTML5 && (!0 === c.sandbox.noRemote && c._wD(b + r("noNet"), 1), !0 === c.sandbox.noLocal && c._wD(b + r("noLocal"), 1));
769 | a.loaded = d;
770 | a.readyState = d ? 3 : 2;
771 | a._onbufferchange(0);
772 | a._iO.onload && ta(a, function () {
773 | a._iO.onload.apply(a,
774 | [d])
775 | });
776 | return !0
777 | };
778 | this._onbufferchange = function (b) {
779 | if (0 === a.playState || b && a.isBuffering || !b && !a.isBuffering)return !1;
780 | a.isBuffering = 1 === b;
781 | a._iO.onbufferchange && (c._wD(a.id + ": Buffer state change: " + b), a._iO.onbufferchange.apply(a));
782 | return !0
783 | };
784 | this._onsuspend = function () {
785 | a._iO.onsuspend && (c._wD(a.id + ": Playback suspended"), a._iO.onsuspend.apply(a));
786 | return !0
787 | };
788 | this._onfailure = function (b, d, e) {
789 | a.failures++;
790 | c._wD(a.id + ": Failures \x3d " + a.failures);
791 | if (a._iO.onfailure && 1 === a.failures)a._iO.onfailure(a, b, d, e);
792 | else c._wD(a.id + ": Ignoring failure")
793 | };
794 | this._onfinish = function () {
795 | var b = a._iO.onfinish;
796 | a._onbufferchange(0);
797 | a._resetOnPosition(0);
798 | if (a.instanceCount && (a.instanceCount--, a.instanceCount || (Ta(), a.playState = 0, a.paused = !1, a.instanceCount = 0, a.instanceOptions = {}, a._iO = {}, l(), a.isHTML5 && (a.position = 0)), (!a.instanceCount || a._iO.multiShotEvents) && b))c._wD(a.id + ": onfinish()"), ta(a, function () {
799 | b.apply(a)
800 | })
801 | };
802 | this._whileloading = function (b, c, d, e) {
803 | var f = a._iO;
804 | a.bytesLoaded = b;
805 | a.bytesTotal = c;
806 | a.duration = Math.floor(d);
807 | a.bufferLength = e;
808 | a.durationEstimate = !a.isHTML5 && !f.isMovieStar ? f.duration ? a.duration > f.duration ? a.duration : f.duration : parseInt(a.bytesTotal / a.bytesLoaded * a.duration, 10) : a.duration;
809 | a.isHTML5 || (a.buffered = [{start: 0, end: a.duration}]);
810 | (3 !== a.readyState || a.isHTML5) && f.whileloading && f.whileloading.apply(a)
811 | };
812 | this._whileplaying = function (b, c, d, e, f) {
813 | var l = a._iO;
814 | if (isNaN(b) || null === b)return !1;
815 | a.position = Math.max(0, b);
816 | a._processOnPosition();
817 | !a.isHTML5 && 8 < n && (l.usePeakData && (c !== g && c) && (a.peakData = {
818 | left: c.leftPeak,
819 | right: c.rightPeak
820 | }), l.useWaveformData && (d !== g && d) && (a.waveformData = {
821 | left: d.split(","),
822 | right: e.split(",")
823 | }), l.useEQData && (f !== g && f && f.leftEQ) && (b = f.leftEQ.split(","), a.eqData = b, a.eqData.left = b, f.rightEQ !== g && f.rightEQ && (a.eqData.right = f.rightEQ.split(","))));
824 | 1 === a.playState && (!a.isHTML5 && (8 === n && !a.position && a.isBuffering) && a._onbufferchange(0), l.whileplaying && l.whileplaying.apply(a));
825 | return !0
826 | };
827 | this._oncaptiondata = function (b) {
828 | c._wD(a.id + ": Caption data received.");
829 | a.captiondata = b;
830 | a._iO.oncaptiondata &&
831 | a._iO.oncaptiondata.apply(a, [b])
832 | };
833 | this._onmetadata = function (b, d) {
834 | c._wD(a.id + ": Metadata received.");
835 | var e = {}, f, g;
836 | f = 0;
837 | for (g = b.length; f < g; f++)e[b[f]] = d[f];
838 | a.metadata = e;
839 | a._iO.onmetadata && a._iO.onmetadata.apply(a)
840 | };
841 | this._onid3 = function (b, d) {
842 | c._wD(a.id + ": ID3 data received.");
843 | var e = [], f, g;
844 | f = 0;
845 | for (g = b.length; f < g; f++)e[b[f]] = d[f];
846 | a.id3 = B(a.id3, e);
847 | a._iO.onid3 && a._iO.onid3.apply(a)
848 | };
849 | this._onconnect = function (b) {
850 | b = 1 === b;
851 | c._wD(a.id + ": " + (b ? "Connected." : "Failed to connect? - " + a.url), b ? 1 : 2);
852 | if (a.connected = b)a.failures =
853 | 0, v(a.id) && (a.getAutoPlay() ? a.play(g, a.getAutoPlay()) : a._iO.autoLoad && a.load()), a._iO.onconnect && a._iO.onconnect.apply(a, [b])
854 | };
855 | this._ondataerror = function (b) {
856 | 0 < a.playState && (c._wD(a.id + ": Data error: " + b), a._iO.ondataerror && a._iO.ondataerror.apply(a))
857 | };
858 | this._debug()
859 | };
860 | ka = function () {
861 | return m.body || m._docElement || m.getElementsByTagName("div")[0]
862 | };
863 | A = function (b) {
864 | return m.getElementById(b)
865 | };
866 | B = function (b, d) {
867 | var e = b || {}, a, f;
868 | a = d === g ? c.defaultOptions : d;
869 | for (f in a)a.hasOwnProperty(f) && e[f] === g && (e[f] = "object" !== typeof a[f] || null === a[f] ? a[f] : B(e[f], a[f]));
870 | return e
871 | };
872 | ta = function (b, c) {
873 | !b.isHTML5 && 8 === n ? h.setTimeout(c, 0) : c()
874 | };
875 | O = {onready: 1, ontimeout: 1, defaultOptions: 1, flash9Options: 1, movieStarOptions: 1};
876 | Aa = function (b, d) {
877 | var e, a = !0, f = d !== g, x = c.setupOptions;
878 | if (b === g) {
879 | a = [];
880 | for (e in x)x.hasOwnProperty(e) && a.push(e);
881 | for (e in O)O.hasOwnProperty(e) && ("object" === typeof c[e] ? a.push(e + ": {...}") : c[e]instanceof Function ? a.push(e + ": function() {...}") : a.push(e));
882 | c._wD(r("setup", a.join(", ")));
883 | return !1
884 | }
885 | for (e in b)if (b.hasOwnProperty(e))if ("object" !== typeof b[e] || null === b[e] || b[e]instanceof Array || b[e]instanceof RegExp)f && O[d] !== g ? c[d][e] = b[e] : x[e] !== g ? (c.setupOptions[e] = b[e], c[e] = b[e]) : O[e] === g ? (J(r(c[e] === g ? "setupUndef" : "setupError", e), 2), a = !1) : c[e]instanceof Function ? c[e].apply(c, b[e]instanceof Array ? b[e] : [b[e]]) : c[e] = b[e]; else if (O[e] === g)J(r(c[e] === g ? "setupUndef" : "setupError", e), 2), a = !1; else return Aa(b[e], e);
886 | return a
887 | };
888 | w = function () {
889 | function b(a) {
890 | a = hb.call(a);
891 | var b = a.length;
892 | e ? (a[1] = "on" + a[1], 3 < b && a.pop()) : 3 === b && a.push(!1);
893 | return a
894 | }
895 |
896 | function c(b,
897 | d) {
898 | var g = b.shift(), l = [a[d]];
899 | if (e)g[l](b[0], b[1]); else g[l].apply(g, b)
900 | }
901 |
902 | var e = h.attachEvent, a = {
903 | add: e ? "attachEvent" : "addEventListener",
904 | remove: e ? "detachEvent" : "removeEventListener"
905 | };
906 | return {
907 | add: function () {
908 | c(b(arguments), "add")
909 | }, remove: function () {
910 | c(b(arguments), "remove")
911 | }
912 | }
913 | }();
914 | G = {
915 | abort: s(function () {
916 | c._wD(this._s.id + ": abort")
917 | }), canplay: s(function () {
918 | var b = this._s, d;
919 | if (b._html5_canplay)return !0;
920 | b._html5_canplay = !0;
921 | c._wD(b.id + ": canplay");
922 | b._onbufferchange(0);
923 | d = b._iO.position !== g && !isNaN(b._iO.position) ? b._iO.position /
924 | 1E3 : null;
925 | if (b.position && this.currentTime !== d) {
926 | c._wD(b.id + ": canplay: Setting position to " + d);
927 | try {
928 | this.currentTime = d
929 | } catch (e) {
930 | c._wD(b.id + ": canplay: Setting position of " + d + " failed: " + e.message, 2)
931 | }
932 | }
933 | b._iO._oncanplay && b._iO._oncanplay()
934 | }), canplaythrough: s(function () {
935 | var b = this._s;
936 | b.loaded || (b._onbufferchange(0), b._whileloading(b.bytesLoaded, b.bytesTotal, b._get_html5_duration()), b._onload(!0))
937 | }), ended: s(function () {
938 | var b = this._s;
939 | c._wD(b.id + ": ended");
940 | b._onfinish()
941 | }), error: s(function () {
942 | c._wD(this._s.id +
943 | ": HTML5 error, code " + this.error.code);
944 | this._s._onload(!1)
945 | }), loadeddata: s(function () {
946 | var b = this._s;
947 | c._wD(b.id + ": loadeddata");
948 | !b._loaded && !ua && (b.duration = b._get_html5_duration())
949 | }), loadedmetadata: s(function () {
950 | c._wD(this._s.id + ": loadedmetadata")
951 | }), loadstart: s(function () {
952 | c._wD(this._s.id + ": loadstart");
953 | this._s._onbufferchange(1)
954 | }), play: s(function () {
955 | this._s._onbufferchange(0)
956 | }), playing: s(function () {
957 | c._wD(this._s.id + ": playing");
958 | this._s._onbufferchange(0)
959 | }), progress: s(function (b) {
960 | var d = this._s, e, a,
961 | f;
962 | e = 0;
963 | var g = "progress" === b.type, z = b.target.buffered, l = b.loaded || 0, h = b.total || 1;
964 | d.buffered = [];
965 | if (z && z.length) {
966 | e = 0;
967 | for (a = z.length; e < a; e++)d.buffered.push({start: 1E3 * z.start(e), end: 1E3 * z.end(e)});
968 | e = 1E3 * (z.end(0) - z.start(0));
969 | l = Math.min(1, e / (1E3 * b.target.duration));
970 | if (g && 1 < z.length) {
971 | f = [];
972 | a = z.length;
973 | for (e = 0; e < a; e++)f.push(1E3 * b.target.buffered.start(e) + "-" + 1E3 * b.target.buffered.end(e));
974 | c._wD(this._s.id + ": progress, timeRanges: " + f.join(", "))
975 | }
976 | g && !isNaN(l) && c._wD(this._s.id + ": progress, " + Math.floor(100 *
977 | l) + "% loaded")
978 | }
979 | isNaN(l) || (d._onbufferchange(0), d._whileloading(l, h, d._get_html5_duration()), l && (h && l === h) && G.canplaythrough.call(this, b))
980 | }), ratechange: s(function () {
981 | c._wD(this._s.id + ": ratechange")
982 | }), suspend: s(function (b) {
983 | var d = this._s;
984 | c._wD(this._s.id + ": suspend");
985 | G.progress.call(this, b);
986 | d._onsuspend()
987 | }), stalled: s(function () {
988 | c._wD(this._s.id + ": stalled")
989 | }), timeupdate: s(function () {
990 | this._s._onTimer()
991 | }), waiting: s(function () {
992 | var b = this._s;
993 | c._wD(this._s.id + ": waiting");
994 | b._onbufferchange(1)
995 | })
996 | };
997 | ra = function (b) {
998 | return !b ||
999 | !b.type && !b.url && !b.serverURL ? !1 : b.serverURL || b.type && ga(b.type) ? !1 : b.type ? ba({type: b.type}) : ba({url: b.url}) || c.html5Only || b.url.match(/data\:/i)
1000 | };
1001 | sa = function (b) {
1002 | var c;
1003 | b && (c = ua && !ca ? null : ub ? "about:blank" : null, b.src = c, void 0 !== b._called_unload && (b._called_load = !1));
1004 | E && (La = null);
1005 | return c
1006 | };
1007 | ba = function (b) {
1008 | if (!c.useHTML5Audio || !c.hasHTML5)return !1;
1009 | var d = b.url || null;
1010 | b = b.type || null;
1011 | var e = c.audioFormats, a;
1012 | if (b && c.html5[b] !== g)return c.html5[b] && !ga(b);
1013 | if (!K) {
1014 | K = [];
1015 | for (a in e)e.hasOwnProperty(a) && (K.push(a),
1016 | e[a].related && (K = K.concat(e[a].related)));
1017 | K = RegExp("\\.(" + K.join("|") + ")(\\?.*)?$", "i")
1018 | }
1019 | a = d ? d.toLowerCase().match(K) : null;
1020 | !a || !a.length ? b && (d = b.indexOf(";"), a = (-1 !== d ? b.substr(0, d) : b).substr(6)) : a = a[1];
1021 | a && c.html5[a] !== g ? d = c.html5[a] && !ga(a) : (b = "audio/" + a, d = c.html5.canPlayType({type: b}), d = (c.html5[a] = d) && c.html5[b] && !ga(b));
1022 | return d
1023 | };
1024 | gb = function () {
1025 | function b(a) {
1026 | var b, e, f = b = !1;
1027 | if (!d || "function" !== typeof d.canPlayType)return b;
1028 | if (a instanceof Array) {
1029 | b = 0;
1030 | for (e = a.length; b < e; b++)if (c.html5[a[b]] || d.canPlayType(a[b]).match(c.html5Test))f = !0, c.html5[a[b]] = !0, c.flash[a[b]] = !!a[b].match(nb);
1031 | b = f
1032 | } else a = d && "function" === typeof d.canPlayType ? d.canPlayType(a) : !1, b = !(!a || !a.match(c.html5Test));
1033 | return b
1034 | }
1035 |
1036 | if (!c.useHTML5Audio || !c.hasHTML5)return u = c.html5.usingFlash = !0, !1;
1037 | var d = Audio !== g ? Oa && 10 > opera.version() ? new Audio(null) : new Audio : null, e, a, f = {}, h;
1038 | h = c.audioFormats;
1039 | for (e in h)if (h.hasOwnProperty(e) && (a = "audio/" + e, f[e] = b(h[e].type), f[a] = f[e], e.match(nb) ? (c.flash[e] = !0, c.flash[a] = !0) : (c.flash[e] = !1, c.flash[a] = !1), h[e] && h[e].related))for (a = h[e].related.length -
1040 | 1; 0 <= a; a--)f["audio/" + h[e].related[a]] = f[e], c.html5[h[e].related[a]] = f[e], c.flash[h[e].related[a]] = f[e];
1041 | f.canPlayType = d ? b : null;
1042 | c.html5 = B(c.html5, f);
1043 | c.html5.usingFlash = fb();
1044 | u = c.html5.usingFlash;
1045 | return !0
1046 | };
1047 | I = {
1048 | notReady: "Unavailable - wait until onready() has fired.",
1049 | notOK: "Audio support is not available.",
1050 | domError: "soundManagerexception caught while appending SWF to DOM.",
1051 | spcWmode: "Removing wmode, preventing known SWF loading issue(s)",
1052 | swf404: "soundManager: Verify that %s is a valid path.",
1053 | tryDebug: "Try soundManager.debugFlash \x3d true for more security details (output goes to SWF.)",
1054 | checkSWF: "See SWF output for more debug info.",
1055 | localFail: "soundManager: Non-HTTP page (" + m.location.protocol + " URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/",
1056 | waitFocus: "soundManager: Special case: Waiting for SWF to load with window focus...",
1057 | waitForever: "soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",
1058 | waitSWF: "soundManager: Waiting for 100% SWF load...",
1059 | needFunction: "soundManager: Function object expected for %s",
1060 | badID: 'Sound ID "%s" should be a string, starting with a non-numeric character',
1061 | currentObj: "soundManager: _debug(): Current sound objects",
1062 | waitOnload: "soundManager: Waiting for window.onload()",
1063 | docLoaded: "soundManager: Document already loaded",
1064 | onload: "soundManager: initComplete(): calling soundManager.onload()",
1065 | onloadOK: "soundManager.onload() complete",
1066 | didInit: "soundManager: init(): Already called?",
1067 | secNote: "Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",
1068 | badRemove: "soundManager: Failed to remove Flash node.",
1069 | shutdown: "soundManager.disable(): Shutting down",
1070 | queue: "soundManager: Queueing %s handler",
1071 | smError: "SMSound.load(): Exception: JS-Flash communication failed, or JS error.",
1072 | fbTimeout: "No flash response, applying .swf_timedout CSS...",
1073 | fbLoaded: "Flash loaded",
1074 | fbHandler: "soundManager: flashBlockHandler()",
1075 | manURL: "SMSound.load(): Using manually-assigned URL",
1076 | onURL: "soundManager.load(): current URL already assigned.",
1077 | badFV: 'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',
1078 | as2loop: "Note: Setting stream:false so looping can work (flash 8 limitation)",
1079 | noNSLoop: "Note: Looping not implemented for MovieStar formats",
1080 | needfl9: "Note: Switching to flash 9, required for MP4 formats.",
1081 | mfTimeout: "Setting flashLoadTimeout \x3d 0 (infinite) for off-screen, mobile flash case",
1082 | needFlash: "soundManager: Fatal error: Flash is needed to play some required formats, but is not available.",
1083 | gotFocus: "soundManager: Got window focus.",
1084 | policy: "Enabling usePolicyFile for data access",
1085 | setup: "soundManager.setup(): allowed parameters: %s",
1086 | setupError: 'soundManager.setup(): "%s" cannot be assigned with this method.',
1087 | setupUndef: 'soundManager.setup(): Could not find option "%s"',
1088 | setupLate: "soundManager.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().",
1089 | noURL: "soundManager: Flash URL required. Call soundManager.setup({url:...}) to get started.",
1090 | sm2Loaded: "SoundManager 2: Ready.",
1091 | reset: "soundManager.reset(): Removing event callbacks",
1092 | mobileUA: "Mobile UA detected, preferring HTML5 by default.",
1093 | globalHTML5: "Using singleton HTML5 Audio() pattern for this device."
1094 | };
1095 | r = function () {
1096 | var b = hb.call(arguments), c = b.shift(), c = I && I[c] ? I[c] : "", e, a;
1097 | if (c && b && b.length) {
1098 | e = 0;
1099 | for (a = b.length; e < a; e++)c = c.replace("%s", b[e])
1100 | }
1101 | return c
1102 | };
1103 | ma = function (b) {
1104 | 8 === n && (1 < b.loops && b.stream) &&
1105 | (p("as2loop"), b.stream = !1);
1106 | return b
1107 | };
1108 | na = function (b, d) {
1109 | if (b && !b.usePolicyFile && (b.onid3 || b.usePeakData || b.useWaveformData || b.useEQData))c._wD((d || "") + r("policy")), b.usePolicyFile = !0;
1110 | return b
1111 | };
1112 | J = function (b) {
1113 | da && console.warn !== g ? console.warn(b) : c._wD(b)
1114 | };
1115 | xa = function () {
1116 | return !1
1117 | };
1118 | $a = function (b) {
1119 | for (var c in b)b.hasOwnProperty(c) && "function" === typeof b[c] && (b[c] = xa)
1120 | };
1121 | Ga = function (b) {
1122 | b === g && (b = !1);
1123 | (y || b) && c.disable(b)
1124 | };
1125 | ab = function (b) {
1126 | var d = null;
1127 | if (b)if (b.match(/\.swf(\?.*)?$/i)) {
1128 | if (d = b.substr(b.toLowerCase().lastIndexOf(".swf?") +
1129 | 4))return b
1130 | } else b.lastIndexOf("/") !== b.length - 1 && (b += "/");
1131 | b = (b && -1 !== b.lastIndexOf("/") ? b.substr(0, b.lastIndexOf("/") + 1) : "./") + c.movieURL;
1132 | c.noSWFCache && (b += "?ts\x3d" + (new Date).getTime());
1133 | return b
1134 | };
1135 | Ca = function () {
1136 | n = parseInt(c.flashVersion, 10);
1137 | 8 !== n && 9 !== n && (c._wD(r("badFV", n, 8)), c.flashVersion = n = 8);
1138 | var b = c.debugMode || c.debugFlash ? "_debug.swf" : ".swf";
1139 | c.useHTML5Audio && (!c.html5Only && c.audioFormats.mp4.required && 9 > n) && (c._wD(r("needfl9")), c.flashVersion = n = 9);
1140 | c.version = c.versionNumber + (c.html5Only ? " (HTML5-only mode)" :
1141 | 9 === n ? " (AS3/Flash 9)" : " (AS2/Flash 8)");
1142 | 8 < n ? (c.defaultOptions = B(c.defaultOptions, c.flash9Options), c.features.buffering = !0, c.defaultOptions = B(c.defaultOptions, c.movieStarOptions), c.filePatterns.flash9 = RegExp("\\.(mp3|" + qb.join("|") + ")(\\?.*)?$", "i"), c.features.movieStar = !0) : c.features.movieStar = !1;
1143 | c.filePattern = c.filePatterns[8 !== n ? "flash9" : "flash8"];
1144 | c.movieURL = (8 === n ? "soundmanager2.swf" : "soundmanager2_flash9.swf").replace(".swf", b);
1145 | c.features.peakData = c.features.waveformData = c.features.eqData = 8 <
1146 | n
1147 | };
1148 | Ya = function (b, c) {
1149 | if (!k)return !1;
1150 | k._setPolling(b, c)
1151 | };
1152 | Fa = function () {
1153 | c.debugURLParam.test(U) && (c.debugMode = !0);
1154 | if (A(c.debugID))return !1;
1155 | var b, d, e, a;
1156 | if (c.debugMode && !A(c.debugID) && (!da || !c.useConsole || !c.consoleOnly)) {
1157 | b = m.createElement("div");
1158 | b.id = c.debugID + "-toggle";
1159 | d = {
1160 | position: "fixed",
1161 | bottom: "0px",
1162 | right: "0px",
1163 | width: "1.2em",
1164 | height: "1.2em",
1165 | lineHeight: "1.2em",
1166 | margin: "2px",
1167 | textAlign: "center",
1168 | border: "1px solid #999",
1169 | cursor: "pointer",
1170 | background: "#fff",
1171 | color: "#333",
1172 | zIndex: 10001
1173 | };
1174 | b.appendChild(m.createTextNode("-"));
1175 | b.onclick = bb;
1176 | b.title = "Toggle SM2 debug console";
1177 | t.match(/msie 6/i) && (b.style.position = "absolute", b.style.cursor = "hand");
1178 | for (a in d)d.hasOwnProperty(a) && (b.style[a] = d[a]);
1179 | d = m.createElement("div");
1180 | d.id = c.debugID;
1181 | d.style.display = c.debugMode ? "block" : "none";
1182 | if (c.debugMode && !A(b.id)) {
1183 | try {
1184 | e = ka(), e.appendChild(b)
1185 | } catch (f) {
1186 | throw Error(r("domError") + " \n" + f.toString());
1187 | }
1188 | e.appendChild(d)
1189 | }
1190 | }
1191 | };
1192 | v = this.getSoundById;
1193 | p = function (b, d) {
1194 | return !b ? "" : c._wD(r(b), d)
1195 | };
1196 | bb = function () {
1197 | var b = A(c.debugID), d = A(c.debugID + "-toggle");
1198 | if (!b)return !1;
1199 | za ? (d.innerHTML = "+", b.style.display = "none") : (d.innerHTML = "-", b.style.display = "block");
1200 | za = !za
1201 | };
1202 | C = function (b, c, e) {
1203 | if (h.sm2Debugger !== g)try {
1204 | sm2Debugger.handleEvent(b, c, e)
1205 | } catch (a) {
1206 | return !1
1207 | }
1208 | return !0
1209 | };
1210 | T = function () {
1211 | var b = [];
1212 | c.debugMode && b.push("sm2_debug");
1213 | c.debugFlash && b.push("flash_debug");
1214 | c.useHighPerformance && b.push("high_performance");
1215 | return b.join(" ")
1216 | };
1217 | Ia = function () {
1218 | var b = r("fbHandler"), d = c.getMoviePercent(), e = {type: "FLASHBLOCK"};
1219 | if (c.html5Only)return !1;
1220 | c.ok() ? (c.didFlashBlock && c._wD(b +
1221 | ": Unblocked"), c.oMC && (c.oMC.className = [T(), "movieContainer", "swf_loaded" + (c.didFlashBlock ? " swf_unblocked" : "")].join(" "))) : (u && (c.oMC.className = T() + " movieContainer " + (null === d ? "swf_timedout" : "swf_error"), c._wD(b + ": " + r("fbTimeout") + (d ? " (" + r("fbLoaded") + ")" : ""))), c.didFlashBlock = !0, M({
1222 | type: "ontimeout",
1223 | ignoreInit: !0,
1224 | error: e
1225 | }), S(e))
1226 | };
1227 | Ba = function (b, c, e) {
1228 | F[b] === g && (F[b] = []);
1229 | F[b].push({method: c, scope: e || null, fired: !1})
1230 | };
1231 | M = function (b) {
1232 | b || (b = {type: c.ok() ? "onready" : "ontimeout"});
1233 | if (!q && b && !b.ignoreInit ||
1234 | "ontimeout" === b.type && (c.ok() || y && !b.ignoreInit))return !1;
1235 | var d = {success: b && b.ignoreInit ? c.ok() : !y}, e = b && b.type ? F[b.type] || [] : [], a = [], f, d = [d], g = u && !c.ok();
1236 | b.error && (d[0].error = b.error);
1237 | b = 0;
1238 | for (f = e.length; b < f; b++)!0 !== e[b].fired && a.push(e[b]);
1239 | if (a.length) {
1240 | b = 0;
1241 | for (f = a.length; b < f; b++)a[b].scope ? a[b].method.apply(a[b].scope, d) : a[b].method.apply(this, d), g || (a[b].fired = !0)
1242 | }
1243 | return !0
1244 | };
1245 | P = function () {
1246 | h.setTimeout(function () {
1247 | c.useFlashBlock && Ia();
1248 | M();
1249 | "function" === typeof c.onload && (p("onload", 1), c.onload.apply(h),
1250 | p("onloadOK", 1));
1251 | c.waitForWindowLoad && w.add(h, "load", P)
1252 | }, 1)
1253 | };
1254 | Ma = function () {
1255 | if (H !== g)return H;
1256 | var b = !1, c = navigator, e = c.plugins, a, f = h.ActiveXObject;
1257 | if (e && e.length)(c = c.mimeTypes) && (c["application/x-shockwave-flash"] && c["application/x-shockwave-flash"].enabledPlugin && c["application/x-shockwave-flash"].enabledPlugin.description) && (b = !0); else if (f !== g && !t.match(/MSAppHost/i)) {
1258 | try {
1259 | a = new f("ShockwaveFlash.ShockwaveFlash")
1260 | } catch (m) {
1261 | a = null
1262 | }
1263 | b = !!a
1264 | }
1265 | return H = b
1266 | };
1267 | fb = function () {
1268 | var b, d, e = c.audioFormats;
1269 | if (ca && t.match(/os (1|2|3_0|3_1)/i))c.hasHTML5 = !1, c.html5Only = !0, c.oMC && (c.oMC.style.display = "none"); else if (c.useHTML5Audio) {
1270 | if (!c.html5 || !c.html5.canPlayType)c._wD("SoundManager: No HTML5 Audio() support detected."), c.hasHTML5 = !1;
1271 | Qa && c._wD("soundManager: Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id\x3d32159 - " + (!H ? " would use flash fallback for MP3/MP4, but none detected." : "will use flash fallback for MP3/MP4, if available"), 1)
1272 | }
1273 | if (c.useHTML5Audio && c.hasHTML5)for (d in qa = !0, e)if (e.hasOwnProperty(d) &&
1274 | e[d].required)if (c.html5.canPlayType(e[d].type)) {
1275 | if (c.preferFlash && (c.flash[d] || c.flash[e[d].type]))b = !0
1276 | } else qa = !1, b = !0;
1277 | c.ignoreFlash && (b = !1, qa = !0);
1278 | c.html5Only = c.hasHTML5 && c.useHTML5Audio && !b;
1279 | return !c.html5Only
1280 | };
1281 | pa = function (b) {
1282 | var d, e, a = 0;
1283 | if (b instanceof Array) {
1284 | d = 0;
1285 | for (e = b.length; d < e; d++)if (b[d]instanceof Object) {
1286 | if (c.canPlayMIME(b[d].type)) {
1287 | a = d;
1288 | break
1289 | }
1290 | } else if (c.canPlayURL(b[d])) {
1291 | a = d;
1292 | break
1293 | }
1294 | b[a].url && (b[a] = b[a].url);
1295 | b = b[a]
1296 | }
1297 | return b
1298 | };
1299 | cb = function (b) {
1300 | b._hasTimer || (b._hasTimer = !0, !Pa && c.html5PollingInterval &&
1301 | (null === aa && 0 === oa && (aa = setInterval(eb, c.html5PollingInterval)), oa++))
1302 | };
1303 | db = function (b) {
1304 | b._hasTimer && (b._hasTimer = !1, !Pa && c.html5PollingInterval && oa--)
1305 | };
1306 | eb = function () {
1307 | var b;
1308 | if (null !== aa && !oa)return clearInterval(aa), aa = null, !1;
1309 | for (b = c.soundIDs.length - 1; 0 <= b; b--)c.sounds[c.soundIDs[b]].isHTML5 && c.sounds[c.soundIDs[b]]._hasTimer && c.sounds[c.soundIDs[b]]._onTimer()
1310 | };
1311 | S = function (b) {
1312 | b = b !== g ? b : {};
1313 | "function" === typeof c.onerror && c.onerror.apply(h, [{type: b.type !== g ? b.type : null}]);
1314 | b.fatal !== g && b.fatal && c.disable()
1315 | };
1316 | ib = function () {
1317 | if (!Qa || !Ma())return !1;
1318 | var b = c.audioFormats, d, e;
1319 | for (e in b)if (b.hasOwnProperty(e) && ("mp3" === e || "mp4" === e))if (c._wD("soundManager: Using flash fallback for " + e + " format"), c.html5[e] = !1, b[e] && b[e].related)for (d = b[e].related.length - 1; 0 <= d; d--)c.html5[b[e].related[d]] = !1
1320 | };
1321 | this._setSandboxType = function (b) {
1322 | var d = c.sandbox;
1323 | d.type = b;
1324 | d.description = d.types[d.types[b] !== g ? b : "unknown"];
1325 | "localWithFile" === d.type ? (d.noRemote = !0, d.noLocal = !1, p("secNote", 2)) : "localWithNetwork" === d.type ? (d.noRemote = !1,
1326 | d.noLocal = !0) : "localTrusted" === d.type && (d.noRemote = !1, d.noLocal = !1)
1327 | };
1328 | this._externalInterfaceOK = function (b) {
1329 | if (c.swfLoaded)return !1;
1330 | var d;
1331 | C("swf", !0);
1332 | C("flashtojs", !0);
1333 | c.swfLoaded = !0;
1334 | va = !1;
1335 | Qa && ib();
1336 | if (!b || b.replace(/\+dev/i, "") !== c.versionNumber.replace(/\+dev/i, ""))return d = 'soundManager: Fatal: JavaScript file build "' + c.versionNumber + '" does not match Flash SWF build "' + b + '" at ' + c.url + ". Ensure both are up-to-date.", setTimeout(function () {
1337 | throw Error(d);
1338 | }, 0), !1;
1339 | setTimeout(ya, L ? 100 : 1)
1340 | };
1341 | la = function (b,
1342 | d) {
1343 | function e() {
1344 | var a = [], b, d = [];
1345 | b = "SoundManager " + c.version + (!c.html5Only && c.useHTML5Audio ? c.hasHTML5 ? " + HTML5 audio" : ", no HTML5 audio support" : "");
1346 | c.html5Only ? c.html5PollingInterval && a.push("html5PollingInterval (" + c.html5PollingInterval + "ms)") : (c.preferFlash && a.push("preferFlash"), c.useHighPerformance && a.push("useHighPerformance"), c.flashPollingInterval && a.push("flashPollingInterval (" + c.flashPollingInterval + "ms)"), c.html5PollingInterval && a.push("html5PollingInterval (" + c.html5PollingInterval +
1347 | "ms)"), c.wmode && a.push("wmode (" + c.wmode + ")"), c.debugFlash && a.push("debugFlash"), c.useFlashBlock && a.push("flashBlock"));
1348 | a.length && (d = d.concat([a.join(" + ")]));
1349 | c._wD(b + (d.length ? " + " + d.join(", ") : ""), 1);
1350 | jb()
1351 | }
1352 |
1353 | function a(a, b) {
1354 | return '\x3cparam name\x3d"' + a + '" value\x3d"' + b + '" /\x3e'
1355 | }
1356 |
1357 | if (V && W)return !1;
1358 | if (c.html5Only)return Ca(), e(), c.oMC = A(c.movieID), ya(), W = V = !0, !1;
1359 | var f = d || c.url, h = c.altURL || f, k = ka(), l = T(), n = null, n = m.getElementsByTagName("html")[0], p, s, q, n = n && n.dir && n.dir.match(/rtl/i);
1360 | b = b === g ? c.id : b;
1361 | Ca();
1362 | c.url = ab(ea ? f : h);
1363 | d = c.url;
1364 | c.wmode = !c.wmode && c.useHighPerformance ? "transparent" : c.wmode;
1365 | if (null !== c.wmode && (t.match(/msie 8/i) || !L && !c.useHighPerformance) && navigator.platform.match(/win32|win64/i))N.push(I.spcWmode), c.wmode = null;
1366 | k = {
1367 | name: b,
1368 | id: b,
1369 | src: d,
1370 | quality: "high",
1371 | allowScriptAccess: c.allowScriptAccess,
1372 | bgcolor: c.bgColor,
1373 | pluginspage: ob + "www.macromedia.com/go/getflashplayer",
1374 | title: "JS/Flash audio component (SoundManager 2)",
1375 | type: "application/x-shockwave-flash",
1376 | wmode: c.wmode,
1377 | hasPriority: "true"
1378 | };
1379 | c.debugFlash &&
1380 | (k.FlashVars = "debug\x3d1");
1381 | c.wmode || delete k.wmode;
1382 | if (L)f = m.createElement("div"), s = ['\x3cobject id\x3d"' + b + '" data\x3d"' + d + '" type\x3d"' + k.type + '" title\x3d"' + k.title + '" classid\x3d"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase\x3d"' + ob + 'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version\x3d6,0,40,0"\x3e', a("movie", d), a("AllowScriptAccess", c.allowScriptAccess), a("quality", k.quality), c.wmode ? a("wmode", c.wmode) : "", a("bgcolor", c.bgColor), a("hasPriority", "true"), c.debugFlash ?
1383 | a("FlashVars", k.FlashVars) : "", "\x3c/object\x3e"].join(""); else for (p in f = m.createElement("embed"), k)k.hasOwnProperty(p) && f.setAttribute(p, k[p]);
1384 | Fa();
1385 | l = T();
1386 | if (k = ka())if (c.oMC = A(c.movieID) || m.createElement("div"), c.oMC.id)q = c.oMC.className, c.oMC.className = (q ? q + " " : "movieContainer") + (l ? " " + l : ""), c.oMC.appendChild(f), L && (p = c.oMC.appendChild(m.createElement("div")), p.className = "sm2-object-box", p.innerHTML = s), W = !0; else {
1387 | c.oMC.id = c.movieID;
1388 | c.oMC.className = "movieContainer " + l;
1389 | p = l = null;
1390 | c.useFlashBlock || (c.useHighPerformance ?
1391 | l = {
1392 | position: "fixed",
1393 | width: "8px",
1394 | height: "8px",
1395 | bottom: "0px",
1396 | left: "0px",
1397 | overflow: "hidden"
1398 | } : (l = {
1399 | position: "absolute",
1400 | width: "6px",
1401 | height: "6px",
1402 | top: "-9999px",
1403 | left: "-9999px"
1404 | }, n && (l.left = Math.abs(parseInt(l.left, 10)) + "px")));
1405 | tb && (c.oMC.style.zIndex = 1E4);
1406 | if (!c.debugFlash)for (q in l)l.hasOwnProperty(q) && (c.oMC.style[q] = l[q]);
1407 | try {
1408 | L || c.oMC.appendChild(f), k.appendChild(c.oMC), L && (p = c.oMC.appendChild(m.createElement("div")), p.className = "sm2-object-box", p.innerHTML = s), W = !0
1409 | } catch (u) {
1410 | throw Error(r("domError") + " \n" +
1411 | u.toString());
1412 | }
1413 | }
1414 | V = !0;
1415 | e();
1416 | return !0
1417 | };
1418 | ja = function () {
1419 | if (c.html5Only)return la(), !1;
1420 | if (k)return !1;
1421 | if (!c.url)return p("noURL"), !1;
1422 | k = c.getMovie(c.id);
1423 | k || (Z ? (L ? c.oMC.innerHTML = Ha : c.oMC.appendChild(Z), Z = null, V = !0) : la(c.id, c.url), k = c.getMovie(c.id));
1424 | "function" === typeof c.oninitmovie && setTimeout(c.oninitmovie, 1);
1425 | Na();
1426 | return !0
1427 | };
1428 | Q = function () {
1429 | setTimeout(Xa, 1E3)
1430 | };
1431 | Xa = function () {
1432 | var b, d = !1;
1433 | if (!c.url || $)return !1;
1434 | $ = !0;
1435 | w.remove(h, "load", Q);
1436 | if (va && !Ra)return p("waitFocus"), !1;
1437 | q || (b = c.getMoviePercent(), 0 < b && 100 > b && (d = !0));
1438 | setTimeout(function () {
1439 | b = c.getMoviePercent();
1440 | if (d)return $ = !1, c._wD(r("waitSWF")), h.setTimeout(Q, 1), !1;
1441 | q || (c._wD("soundManager: No Flash response within expected time. Likely causes: " + (0 === b ? "SWF load failed, " : "") + "Flash blocked or JS-Flash security error." + (c.debugFlash ? " " + r("checkSWF") : ""), 2), !ea && b && (p("localFail", 2), c.debugFlash || p("tryDebug", 2)), 0 === b && c._wD(r("swf404", c.url), 1), C("flashtojs", !1, ": Timed out" + ea ? " (Check flash security or flash blockers)" : " (No plugin/missing SWF?)"));
1442 | !q && mb && (null === b ? c.useFlashBlock || 0 === c.flashLoadTimeout ? (c.useFlashBlock && Ia(), p("waitForever")) : !c.useFlashBlock && qa ? h.setTimeout(function () {
1443 | J("soundManager: useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false...");
1444 | c.setup({preferFlash: !1}).reboot();
1445 | c.didFlashBlock = !0;
1446 | c.beginDelayedInit()
1447 | }, 1) : (p("waitForever"), M({
1448 | type: "ontimeout",
1449 | ignoreInit: !0
1450 | })) : 0 === c.flashLoadTimeout ? p("waitForever") : Ga(!0))
1451 | }, c.flashLoadTimeout)
1452 | };
1453 | ia = function () {
1454 | if (Ra || !va)return w.remove(h, "focus",
1455 | ia), !0;
1456 | Ra = mb = !0;
1457 | p("gotFocus");
1458 | $ = !1;
1459 | Q();
1460 | w.remove(h, "focus", ia);
1461 | return !0
1462 | };
1463 | Na = function () {
1464 | N.length && (c._wD("SoundManager 2: " + N.join(" "), 1), N = [])
1465 | };
1466 | jb = function () {
1467 | Na();
1468 | var b, d = [];
1469 | if (c.useHTML5Audio && c.hasHTML5) {
1470 | for (b in c.audioFormats)c.audioFormats.hasOwnProperty(b) && d.push(b + " \x3d " + c.html5[b] + (!c.html5[b] && u && c.flash[b] ? " (using flash)" : c.preferFlash && c.flash[b] && u ? " (preferring flash)" : !c.html5[b] ? " (" + (c.audioFormats[b].required ? "required, " : "") + "and no flash support)" : ""));
1471 | c._wD("SoundManager 2 HTML5 support: " +
1472 | d.join(", "), 1)
1473 | }
1474 | };
1475 | X = function (b) {
1476 | if (q)return !1;
1477 | if (c.html5Only)return p("sm2Loaded"), q = !0, P(), C("onload", !0), !0;
1478 | var d = !0, e;
1479 | if (!c.useFlashBlock || !c.flashLoadTimeout || c.getMoviePercent())q = !0, y && (e = {type: !H && u ? "NO_FLASH" : "INIT_TIMEOUT"});
1480 | c._wD("SoundManager 2 " + (y ? "failed to load" : "loaded") + " (" + (y ? "Flash security/load error" : "OK") + ")", y ? 2 : 1);
1481 | y || b ? (c.useFlashBlock && c.oMC && (c.oMC.className = T() + " " + (null === c.getMoviePercent() ? "swf_timedout" : "swf_error")), M({
1482 | type: "ontimeout",
1483 | error: e,
1484 | ignoreInit: !0
1485 | }), C("onload",
1486 | !1), S(e), d = !1) : C("onload", !0);
1487 | y || (c.waitForWindowLoad && !ha ? (p("waitOnload"), w.add(h, "load", P)) : (c.waitForWindowLoad && ha && p("docLoaded"), P()));
1488 | return d
1489 | };
1490 | Wa = function () {
1491 | var b, d = c.setupOptions;
1492 | for (b in d)d.hasOwnProperty(b) && (c[b] === g ? c[b] = d[b] : c[b] !== d[b] && (c.setupOptions[b] = c[b]))
1493 | };
1494 | ya = function () {
1495 | if (q)return p("didInit"), !1;
1496 | if (c.html5Only)return q || (w.remove(h, "load", c.beginDelayedInit), c.enabled = !0, X()), !0;
1497 | ja();
1498 | try {
1499 | k._externalInterfaceTest(!1), Ya(!0, c.flashPollingInterval || (c.useHighPerformance ? 10 :
1500 | 50)), c.debugMode || k._disableDebug(), c.enabled = !0, C("jstoflash", !0), c.html5Only || w.add(h, "unload", xa)
1501 | } catch (b) {
1502 | return c._wD("js/flash exception: " + b.toString()), C("jstoflash", !1), S({
1503 | type: "JS_TO_FLASH_EXCEPTION",
1504 | fatal: !0
1505 | }), Ga(!0), X(), !1
1506 | }
1507 | X();
1508 | w.remove(h, "load", c.beginDelayedInit);
1509 | return !0
1510 | };
1511 | R = function () {
1512 | if (Y)return !1;
1513 | Y = !0;
1514 | Wa();
1515 | Fa();
1516 | var b = null, b = null, d = U.toLowerCase();
1517 | -1 !== d.indexOf("sm2-usehtml5audio\x3d") && (b = "1" === d.charAt(d.indexOf("sm2-usehtml5audio\x3d") + 18), da && console.log((b ? "Enabling " : "Disabling ") +
1518 | "useHTML5Audio via URL parameter"), c.setup({useHTML5Audio: b}));
1519 | -1 !== d.indexOf("sm2-preferflash\x3d") && (b = "1" === d.charAt(d.indexOf("sm2-preferflash\x3d") + 16), da && console.log((b ? "Enabling " : "Disabling ") + "preferFlash via URL parameter"), c.setup({preferFlash: b}));
1520 | !H && c.hasHTML5 && (c._wD("SoundManager: No Flash detected" + (!c.useHTML5Audio ? ", enabling HTML5." : ". Trying HTML5-only mode."), 1), c.setup({
1521 | useHTML5Audio: !0,
1522 | preferFlash: !1
1523 | }));
1524 | gb();
1525 | !H && u && (N.push(I.needFlash), c.setup({flashLoadTimeout: 1}));
1526 | m.removeEventListener &&
1527 | m.removeEventListener("DOMContentLoaded", R, !1);
1528 | ja();
1529 | return !0
1530 | };
1531 | Ka = function () {
1532 | "complete" === m.readyState && (R(), m.detachEvent("onreadystatechange", Ka));
1533 | return !0
1534 | };
1535 | Ea = function () {
1536 | ha = !0;
1537 | w.remove(h, "load", Ea)
1538 | };
1539 | Da = function () {
1540 | if (Pa && ((!c.setupOptions.useHTML5Audio || c.setupOptions.preferFlash) && N.push(I.mobileUA), c.setupOptions.useHTML5Audio = !0, c.setupOptions.preferFlash = !1, ca || lb && !t.match(/android\s2\.3/i)))N.push(I.globalHTML5), ca && (c.ignoreFlash = !0), E = !0
1541 | };
1542 | Da();
1543 | Ma();
1544 | w.add(h, "focus", ia);
1545 | w.add(h, "load", Q);
1546 | w.add(h,
1547 | "load", Ea);
1548 | m.addEventListener ? m.addEventListener("DOMContentLoaded", R, !1) : m.attachEvent ? m.attachEvent("onreadystatechange", Ka) : (C("onload", !1), S({
1549 | type: "NO_DOM2_EVENTS",
1550 | fatal: !0
1551 | }))
1552 | }
1553 |
1554 | var wa = null;
1555 | if (void 0 === h.SM2_DEFER || !SM2_DEFER)wa = new fa;
1556 | h.SoundManager = fa;
1557 | h.soundManager = wa
1558 | })(window);
1559 |
--------------------------------------------------------------------------------