diff --git a/LICENSE b/LICENSE index bd8b823..f35c0cb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -PerformanC's PerforVNMaker Custom License +PerformanC's Custom License Copyright (c) 2023 PerformanC @@ -8,12 +8,10 @@ and it can even be used for commercial purposes. However, the software code neither can be used to train a neural network, nor any part of the code can be copied in any way without the permission of the PerformanC Organization team members. An exception is made for the -generated code, which can be used with one exception: the generated -code cannot be used for or any type of software that creates softwares -of any kind. +generated code, which can be used without only one exception: the generated +code cannot be used for other code generations or any software that creates apps. -The license must included at the source code of the PerformanC software -outside the official PerformanC repository. +The license can be included at the source code of the PerformanC software, although it is not required. The Software is given "as is" and without any warranties, and its developers disclaim all liability for any harm it (The Software) may cause. \ No newline at end of file diff --git a/OS_SUPPORT.md b/OS_SUPPORT.md index 30e210d..a891f48 100644 --- a/OS_SUPPORT.md +++ b/OS_SUPPORT.md @@ -134,14 +134,6 @@ Achievements are a way to reward the player for doing something in the game, lik \>= `1.23.0 & v1.21.0`: Supported -##### Items - -Items are a way to reward the player for doing something in the game, like finishing the game, or finding a secret. Allows also to unlock custom paths. - -###### Version support - -\>= `1.23.0 & v1.21.0`: Supported - ### Menu The menu is the place where the player can access the settings, the About menu, and start the VN. @@ -256,9 +248,9 @@ This is the list of features that we're planning to add (or modify) to PerforVNM - [x] Custom paths (Completed) - [x] Custom Views (Completed) - [x] Achievements (Completed) -- [x] Items (Completed) - [x] Menu (Missing vertical footer) - [x] Settings (Misses some additional configurations) +- [ ] Inventory ## Code generation support diff --git a/SECURITY.md b/SECURITY.md index 2b79570..68076bb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,8 +6,9 @@ This is the Security Policy of the PerforVNMaker project. Made to ensure the qua | Version | Supported | | --------------------------- | ------------------ | -| >= v1.22.0 - v1.20.0 | :white_check_mark: | -| < v1.22.0 - v1.20.0 | :x: | +| > 1.16.2-b.0 (1.14.8-b.0) | :white_check_mark: | +| 1.16.2-b.0 (1.14.7-b.0) | :white_check_mark: | +| < 1.16.2-b.0 (1.14.6-b.0) | :x: | Observation: This can be dismissed if it's proved that the newest versions don't fix the vulnerability. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..60f9043 --- /dev/null +++ b/TODO.md @@ -0,0 +1,5 @@ +# TODO + +- (Customizability) Allow to remove footer and add buttons manually. +- (Code quality) Only add necessary `import`s. +- (Optimization) Create functions for stopping the music and sound effects. diff --git a/android/app/src/main/java/com/perforvnm/MainActivity.kt b/android/app/src/main/java/com/perforvnm/MainActivity.kt index 4d32896..5611242 100644 --- a/android/app/src/main/java/com/perforvnm/MainActivity.kt +++ b/android/app/src/main/java/com/perforvnm/MainActivity.kt @@ -11,7 +11,6 @@ import android.os.Looper import android.app.Activity import android.util.TypedValue import android.media.MediaPlayer -import android.widget.Toast import android.widget.TextView import android.widget.ImageView import android.widget.ScrollView @@ -38,10 +37,8 @@ import android.content.Context import android.content.SharedPreferences class MainActivity : Activity() { - private var scenes = MutableList(6) { 0 } + private var scenes = MutableList(5) { 0 } private var scenesLength = 1 - private var items = MutableList(1) { 0 } - private var itemsLength = 0 private val handler = Handler(Looper.getMainLooper()) private var textSpeed = 50L private var sEffectVolume = 1f @@ -1207,12 +1204,6 @@ class MainActivity : Activity() { scenes.set(j, historyScenes.getInt(j)) } scenesLength = historyScenes.length() - - val sceneItems = buttonData.getJSONArray("items") - for (j in 0 until sceneItems.length()) { - items.set(j, sceneItems.getInt(j)) - } - itemsLength = sceneItems.length() switchScene(buttonData.getInt("scene")) } @@ -1265,17 +1256,6 @@ class MainActivity : Activity() { } } } - 969329308 -> { - when (characterData.getString("name")) { - "Pedro" -> { - imageViewCharacter.setImageResource(R.raw.pedro_staring) - - val leftDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._5sdp) - - layoutParamsImageViewCharacter.setMargins(leftDpLoad + leftDpCharacter, topDpLoad, 0, 0) - } - } - } 1722916383 -> { when (characterData.getString("name")) { "Pedro" -> { @@ -1675,7 +1655,7 @@ class MainActivity : Activity() { var saves = inputStream.bufferedReader().use { it.readText() } inputStream.close() - val newSave = "{\"scene\":1722916382,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" + val newSave = "{\"scene\":1722916382,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -1704,16 +1684,6 @@ class MainActivity : Activity() { buttonMenu.layoutParams = layoutParamsMenu buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - if (mediaPlayer != null) { mediaPlayer!!.stop() mediaPlayer!!.release() @@ -1761,13 +1731,6 @@ class MainActivity : Activity() { buttonSubScenes.layoutParams = layoutParamsSubScenes buttonSubScenes.setOnClickListener { - if (!items.contains(1789536792)) { - Toast.makeText(this, "You don't have the required item.", Toast.LENGTH_SHORT).show() - items.remove(1789536792) - - return@setOnClickListener - } - if (mediaPlayer != null) { mediaPlayer!!.stop() mediaPlayer!!.release() @@ -1817,9 +1780,6 @@ class MainActivity : Activity() { giveAchievement(1183596997) - items.set(itemsLength, 1789536792) - itemsLength++ - setContentView(frameLayout) } @@ -1949,7 +1909,7 @@ class MainActivity : Activity() { var saves = inputStream.bufferedReader().use { it.readText() } inputStream.close() - val newSave = "{\"scene\":1722916385,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" + val newSave = "{\"scene\":1722916385,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -1978,16 +1938,6 @@ class MainActivity : Activity() { buttonMenu.layoutParams = layoutParamsMenu buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - handler.removeCallbacksAndMessages(null) findViewById(android.R.id.content).setOnClickListener(null) @@ -2041,22 +1991,18 @@ class MainActivity : Activity() { frameLayout.addView(buttonBack) + setContentView(frameLayout) + findViewById(android.R.id.content).setOnClickListener { handler.removeCallbacksAndMessages(null) - findViewById(android.R.id.content).setOnClickListener(null) + it.setOnClickListener(null) scenes.set(scenesLength, 1722916385) scenesLength++ - if (!items.contains(1789536792)) { - no_items() - } else { - scene5() - } + scene5() } - - setContentView(frameLayout) } private fun scene5() { @@ -2181,7 +2127,7 @@ class MainActivity : Activity() { var saves = inputStream.bufferedReader().use { it.readText() } inputStream.close() - val newSave = "{\"scene\":1722916386,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" + val newSave = "{\"scene\":1722916386,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -2210,16 +2156,6 @@ class MainActivity : Activity() { buttonMenu.layoutParams = layoutParamsMenu buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - handler.removeCallbacksAndMessages(null) findViewById(android.R.id.content).setOnClickListener(null) @@ -2274,223 +2210,6 @@ class MainActivity : Activity() { setContentView(frameLayout) } - private fun no_items() { - val frameLayout = FrameLayout(this) - frameLayout.setBackgroundColor(0xFF000000.toInt()) - - val imageView_scenario = ImageView(this) - imageView_scenario.setImageResource(R.raw.background_thanking) - imageView_scenario.scaleType = ImageView.ScaleType.FIT_CENTER - - frameLayout.addView(imageView_scenario) - - val imageView_Pedro = ImageView(this) - imageView_Pedro.setImageResource(R.raw.pedro_staring) - imageView_Pedro.scaleType = ImageView.ScaleType.FIT_CENTER - - val layoutParams_Pedro = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - layoutParams_Pedro.gravity = Gravity.CENTER - layoutParams_Pedro.setMargins(resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._20sdp), 0, 0, 0) - - imageView_Pedro.layoutParams = layoutParams_Pedro - - frameLayout.addView(imageView_Pedro) - - val rectangleViewSpeech = RectangleView(this) - - val sdp53 = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._53sdp) - - val layoutParamsRectangleSpeech = LayoutParams(LayoutParams.WRAP_CONTENT, sdp53) - layoutParamsRectangleSpeech.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL - - rectangleViewSpeech.layoutParams = layoutParamsRectangleSpeech - rectangleViewSpeech.setAlpha(0.8f) - rectangleViewSpeech.setColor(0xFF000000.toInt()) - - frameLayout.addView(rectangleViewSpeech) - - val textViewSpeech = TextView(this) - textViewSpeech.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(com.intuit.ssp.R.dimen._9ssp)) - textViewSpeech.setTextColor(0xFFFFFFFF.toInt()) - - val layoutParamsSpeech = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - layoutParamsSpeech.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL - layoutParamsSpeech.setMargins(0, resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._270sdp), 0, 0) - - textViewSpeech.layoutParams = layoutParamsSpeech - - var speechText = "\"You don't have the item, sorry.\"" - var i = 0 - - handler.postDelayed(object : Runnable { - override fun run() { - if (i < speechText.length) { - textViewSpeech.text = speechText.substring(0, i + 1) - i++ - handler.postDelayed(this, textSpeed) - } - } - }, textSpeed) - - frameLayout.addView(textViewSpeech) - - val rectangleViewAuthor = RectangleView(this) - - val layoutParamsRectangleAuthor = LayoutParams(LayoutParams.WRAP_CONTENT, 70) - layoutParamsRectangleAuthor.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL - layoutParamsRectangleAuthor.setMargins(0, 0, 0, sdp53) - - rectangleViewAuthor.layoutParams = layoutParamsRectangleAuthor - rectangleViewAuthor.setAlpha(0.6f) - rectangleViewAuthor.setColor(0xFF000000.toInt()) - - frameLayout.addView(rectangleViewAuthor) - - val textViewAuthor = TextView(this) - textViewAuthor.text = "Pedro" - textViewAuthor.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(com.intuit.ssp.R.dimen._13ssp)) - textViewAuthor.setTextColor(0xFFFFFFFF.toInt()) - - val layoutParamsAuthor = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - layoutParamsAuthor.gravity = Gravity.BOTTOM or Gravity.START - layoutParamsAuthor.setMargins(resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._155sdp), 0, 0, sdp53) - - textViewAuthor.layoutParams = layoutParamsAuthor - - frameLayout.addView(textViewAuthor) - - val ssp8 = resources.getDimension(com.intuit.ssp.R.dimen._8ssp) - - val buttonSave = Button(this) - buttonSave.text = "Save" - buttonSave.setTextSize(TypedValue.COMPLEX_UNIT_PX, ssp8) - buttonSave.setTextColor(0xFFFFFFFF.toInt()) - buttonSave.background = null - - val layoutParamsSave = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - val sdp15 = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._15sdp) - - layoutParamsSave.gravity = Gravity.TOP or Gravity.START - layoutParamsSave.setMargins(sdp15, 0, 0, 0) - - buttonSave.layoutParams = layoutParamsSave - - buttonSave.setOnClickListener { - val inputStream = openFileInput("saves.json") - var saves = inputStream.bufferedReader().use { it.readText() } - inputStream.close() - - val newSave = "{\"scene\":969329308,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" - - if (saves == "[]") saves = "[" + newSave + "]" - else saves = saves.dropLast(1) + "," + newSave + "]" - - val outputStream = openFileOutput("saves.json", Context.MODE_PRIVATE) - outputStream.write(saves.toByteArray()) - outputStream.close() - } - - frameLayout.addView(buttonSave) - - val buttonMenu = Button(this) - buttonMenu.text = "Menu" - buttonMenu.setTextSize(TypedValue.COMPLEX_UNIT_PX, ssp8) - buttonMenu.setTextColor(0xFFFFFFFF.toInt()) - buttonMenu.background = null - - val layoutParamsMenu = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - layoutParamsMenu.gravity = Gravity.TOP or Gravity.START - layoutParamsMenu.setMargins(sdp15, resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._23sdp), 0, 0) - - buttonMenu.layoutParams = layoutParamsMenu - - buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - - handler.removeCallbacksAndMessages(null) - - findViewById(android.R.id.content).setOnClickListener(null) - - mediaPlayer = MediaPlayer.create(this, R.raw.menu_music) - - if (mediaPlayer != null) { - mediaPlayer!!.start() - - val volume = getSharedPreferences("VNConfig", Context.MODE_PRIVATE).getFloat("musicVolume", 1f) - mediaPlayer!!.setVolume(volume, volume) - - mediaPlayer!!.setOnCompletionListener { - mediaPlayer!!.start() - } - } - - menu() - } - - frameLayout.addView(buttonMenu) - - val buttonBack = Button(this) - buttonBack.text = "Back" - buttonBack.setTextSize(TypedValue.COMPLEX_UNIT_PX, ssp8) - buttonBack.setTextColor(0xFFFFFFFF.toInt()) - buttonBack.background = null - - val layoutParamsBack = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) - - layoutParamsBack.gravity = Gravity.TOP or Gravity.START - layoutParamsBack.setMargins(sdp15, resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._46sdp), 0, 0) - - buttonBack.layoutParams = layoutParamsBack - - buttonBack.setOnClickListener { - handler.removeCallbacksAndMessages(null) - - findViewById(android.R.id.content).setOnClickListener(null) - - val scene = scenes.get(scenesLength - 1) - - scenesLength-- - scenes.set(scenesLength, 0) - - switchScene(scene) - } - - frameLayout.addView(buttonBack) - - setContentView(frameLayout) - } - private fun scene2(animate: Boolean) { val frameLayout = FrameLayout(this) frameLayout.setBackgroundColor(0xFF000000.toInt()) @@ -2646,7 +2365,7 @@ class MainActivity : Activity() { var saves = inputStream.bufferedReader().use { it.readText() } inputStream.close() - val newSave = "{\"scene\":1722916383,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" + val newSave = "{\"scene\":1722916383,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -2675,16 +2394,6 @@ class MainActivity : Activity() { buttonMenu.layoutParams = layoutParamsMenu buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - handler.removeCallbacksAndMessages(null) findViewById(android.R.id.content).setOnClickListener(null) @@ -2734,10 +2443,6 @@ class MainActivity : Activity() { frameLayout.addView(buttonBack) findViewById(android.R.id.content).setOnClickListener { - handler.removeCallbacksAndMessages(null) - - findViewById(android.R.id.content).setOnClickListener(null) - scenes.set(scenesLength, 1722916383) scenesLength++ @@ -2902,7 +2607,7 @@ class MainActivity : Activity() { var saves = inputStream.bufferedReader().use { it.readText() } inputStream.close() - val newSave = "{\"scene\":1722916384,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + ",\"items\":" + itemsToJson() + "}" + val newSave = "{\"scene\":1722916384,\"scenario\":\"background_thanking\",\"characters\":[{\"name\":\"Pedro\"}],\"history\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -2931,16 +2636,6 @@ class MainActivity : Activity() { buttonMenu.layoutParams = layoutParamsMenu buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, 0) - } - scenesLength = 0 - - for (j in 0 until itemsLength) { - items.set(j, 0) - } - itemsLength = 0 - handler.removeCallbacksAndMessages(null) findViewById(android.R.id.content).setOnClickListener(null) @@ -2990,10 +2685,6 @@ class MainActivity : Activity() { frameLayout.addView(buttonBack) findViewById(android.R.id.content).setOnClickListener { - handler.removeCallbacksAndMessages(null) - - findViewById(android.R.id.content).setOnClickListener(null) - scenes.set(scenesLength, 1722916384) scenesLength++ @@ -3008,7 +2699,6 @@ class MainActivity : Activity() { 1722916382 -> scene1() 1722916385 -> scene4(false) 1722916386 -> scene5() - 969329308 -> no_items() 1722916383 -> scene2(false) 1722916384 -> scene3(false) } @@ -3035,16 +2725,6 @@ class MainActivity : Activity() { outputStream.close() } - private fun itemsToJson(): String { - var json = "[" - - for (i in 0 until itemsLength) { - json += items.get(i).toString() + "," - } - - return json.dropLast(1) + "]" - } - private fun scenesToJson(): String { var json = "[" diff --git a/docs/coder/init.md b/docs/coder/init.md index 997412e..581f85a 100644 --- a/docs/coder/init.md +++ b/docs/coder/init.md @@ -18,7 +18,6 @@ coder.init({ hashAchievementIds: true, hashScenesNames: true, reuseResources: true, - hashItemIds: true, minify: true } }) @@ -36,7 +35,6 @@ coder.init({ - `hashScenesNames`: If `true`, the code generator, in code generation time, will hash the names of the scenes in `saves` switch page to reduce overhead of checking strings. - `hashAchievementIds`: If `true`, the code generator, in code generation time, will hash the IDs of the achievements in `achievements` switch page to reduce overhead of checking strings. - `reuseResources`: If `true`, the code generator will reuse any `sdp` and `ssp` resources that are identical in each scene. (low - speed & code size) - - `hashItemIds`: If `true`, the code generator, in code generation time, will hash the IDs of the items in `items` switch page to reduce overhead of checking strings. - `minify`: If `true`, the code generator will minify the generated code by removing the identation spaces. (low - code size) ## Return value diff --git a/docs/items/give.md b/docs/items/give.md deleted file mode 100644 index ac9441b..0000000 --- a/docs/items/give.md +++ /dev/null @@ -1,30 +0,0 @@ -# Items - Give - -## Description - -Sets to give the player an item when the player reaches the scene. - -## Syntax - -```js -perfor.achievements.give(scene, 'first_item') - -``` - -## Parameters - -- `scene`: The scene configurations from the `init` function. -- `id`: The unique ID of the item to give. - -## Return value - -This function will return the scene configurations if successful, otherwise, it will execute `new Error` to terminate the generation process. - -## Platform support - -- [x] Android -- [ ] iOS -- [ ] Windows -- [ ] Linux distros -- [ ] MacOS -- [ ] Web diff --git a/docs/items/init.md b/docs/items/init.md deleted file mode 100644 index d77378c..0000000 --- a/docs/items/init.md +++ /dev/null @@ -1,33 +0,0 @@ -# Items - Init - -## Description - -Initializes the basic variables with information of the items for the functionality of the items core, **necessary** for the use of any items function. - -## Syntax - -```js -perfor.items.init([{ - id: 'first_item', - name: 'First item' -}]) -``` - -## Parameters - -- `options`: The options of the item. - - `id`: The unique ID of the item. - - `name`: The name of the item. - -## Return value - -This function will return `undefined` if the initialization was successful, otherwise, it will execute `new Error` to terminate the generation process. - -## Platform support - -- [x] Android -- [ ] iOS -- [ ] Windows -- [ ] Linux distros -- [ ] MacOS -- [ ] Web diff --git a/docs/scene/addSubScenes.md b/docs/scene/addSubScenes.md index 5c36bc2..2001c27 100644 --- a/docs/scene/addSubScenes.md +++ b/docs/scene/addSubScenes.md @@ -7,18 +7,7 @@ Adds a fade in transition to the scenes when entering the scene. ## Syntax ```js -scene.addSubScenes(scene, [{ - text: 'second', - scene: 'scene2', - item: { - require: 'first_item' - remove: true - } - }, { - text: 'third', - scene: 'scene3' - } -]) +scene.addSubScenes(scene, [{ text: 'second', scene: 'scene2' }, { text: 'third', scene: 'scene3' }]) ``` OBS: Maximum of 2 sub-scenes, if more are added, PerforVNM will ignore the rest. @@ -27,15 +16,13 @@ OBS: Maximum of 2 sub-scenes, if more are added, PerforVNM will ignore the rest. - `scene`: The scene configurations from the `init` function. - `options`: The options of the scenario. An object with the following property: - - `subScenes`: The array of sub-scenes configurations (2) + - `subScenes`: The sub-scenes configurations. - `subScene` is an array of objects with the following properties: - `text`: The text that will be displayed in the sub-scene button. - `scene`: The name of the scene that will be called when the sub-scene button is pressed. - - `item`: The item configurations. An object with the following properties: - - `require`: The item that is required to go to the next scene. An object with the following properties: - - `id`: The unique ID of the item. - - `fallback`: The scene that will be called if the player does not have the item. - - `remove`: If the item will be removed from the player's inventory. + - `subScene` is an array of objects with the following properties (2nd sub-scene): + - `text`: The text that will be displayed in the sub-scene button. + - `scene`: The name of the scene that will be called when the sub-scene button is pressed. ## Return value diff --git a/docs/scene/setNextScene.md b/docs/scene/setNextScene.md index cda4f6f..cd0c084 100644 --- a/docs/scene/setNextScene.md +++ b/docs/scene/setNextScene.md @@ -7,28 +7,13 @@ Adds a fade in transition to the scenes when entering the scene. ## Syntax ```js -scene.setNextScene(scene, { - scene: 'scene4', - item: { - require: { - id: 'first_item', - fallback: 'no_items' - }, - remove: true - } -}) +scene.setNextScene(scene, 'scene4') ``` ## Parameters - `scene`: The scene configurations from the `init` function. -- `options`: The options of the scenario. An object with the following property: - - `scene`: The name of the scene that will be called when the scene ends. - - `item`: The item configurations. An object with the following properties: - - `require`: The item that is required to go to the next scene. An object with the following properties: - - `id`: The unique ID of the item. - - `fallback`: The scene that will be called if the player does not have the item. - - `remove`: If the item will be removed from the player's inventory. +- `nextScene`: The name of the next scene. ## Return value diff --git a/index.js b/index.js index 1b4a388..60fa8a4 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,6 @@ import subScene from './src/sub-scene.js' import menu from './src/menu.js' import achievements from './src/achievements.js' import custom from './src/custom.js' -import items from './src/items.js' export default { coder, @@ -12,6 +11,5 @@ export default { subScene, menu, achievements, - custom, - items + custom } \ No newline at end of file diff --git a/package.json b/package.json index 1e97dcf..85ecb23 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "doc": "docs" }, "scripts": { - "test": "node tests/vn.js" + "test": "bun run tests/vn.js" }, "repository": { "type": "git", diff --git a/src/achievements.js b/src/achievements.js index 3ad4604..64dc2d7 100644 --- a/src/achievements.js +++ b/src/achievements.js @@ -1,6 +1,3 @@ -/* TODO: Achievements searchs from O(n) to O(1) through objects */ -/* TODO: Option for scenes to require an achievement and if not, fallback to another scene */ - import helper from './helper.js' function init(options) { diff --git a/src/coder.js b/src/coder.js index f6a7dbb..bb5dde0 100644 --- a/src/coder.js +++ b/src/coder.js @@ -1,13 +1,10 @@ -/* TODO: Remove ability to use achievements, items and menu init functions after using scene.finalize */ - import fs from 'fs' import helper from './helper.js' import achievements from './achievements.js' -import { _ItemsParsingFunction, _ItemsRestore, _ItemsSaver } from './items.js' -global.visualNovel = { menu: null, info: null, internalInfo: {}, code: '', scenes: [], subScenes: [], achievements: [], items: [], customXML: [], optimizations: {} } +global.visualNovel = { menu: null, info: null, internalInfo: {}, code: '', scenes: [], subScenes: [], achievements: [], customXML: [], optimizations: {} } global.PerforVNM = { codeGeneratorVersion: '1.23.0', generatedCodeVersion: '1.21.0', @@ -53,10 +50,6 @@ function init(options) { type: 'boolean', required: false }, - 'hashItemsId': { - type: 'boolean', - required: false - }, 'preCalculateRounding': { type: 'boolean', required: false @@ -80,7 +73,6 @@ function init(options) { visualNovel.info = options - /* TODO: Only add necessary `import`s */ visualNovel.code = helper.codePrepare(` package ${options.applicationId} @@ -95,7 +87,6 @@ function init(options) { import android.app.Activity import android.util.TypedValue import android.media.MediaPlayer - import android.widget.Toast import android.widget.TextView import android.widget.ImageView import android.widget.ScrollView @@ -171,7 +162,6 @@ function init(options) { helper.logOk('Base configuration files and main function coded.', 'Android') } -/* TODO: Create functions for stopping the music and sound effects */ function finalize() { helper.replace('__PERFORVNM_CODE__', '') @@ -190,57 +180,43 @@ function finalize() { visualNovel.scenes.forEach((scene, i) => { savesSwitchCode += helper.sceneEach(scene) - if (scene.next) { - const nextScene = visualNovel.scenes.find((nScene) => nScene.name == scene.next.scene) + if (i != visualNovel.scenes.length - 1) { + const nextScene = visualNovel.scenes[i + 1] const finishScene = [] - if (scene.next.item?.require?.fallback) { - const fallbackScene = visualNovel.scenes.find((fScene) => fScene.name == scene.next.item.require.fallback) - const functionParams = [] + if (scene.effect || scene.music) { + finishScene.push( + helper.codePrepare(` + if (mediaPlayer != null) { + mediaPlayer!!.stop() + mediaPlayer!!.release() + mediaPlayer = null + }\n`, 14 + ) + ) + } + + if (scene.effect && scene.music) { + finishScene.push( + helper.codePrepare(` + if (mediaPlayer2 != null) { + mediaPlayer2!!.stop() + mediaPlayer2!!.release() + mediaPlayer2 = null + }\n`, 14 + ) + ) + } - if (fallbackScene.speech && !scene.speech) { - functionParams.push('true') - } - if (fallbackScene.speech?.author?.name && scene.speech && !scene.speech?.author?.name) { - functionParams.push('true') - } + if (scene.speech || (scene.effect && scene.effect.delay != 0) || (scene.music && scene.music.delay != 0)) + finishScene.push(helper.codePrepare('handler.removeCallbacksAndMessages(null)', 0, 14, false)) - scene.code = scene.code.replace('__PERFORVNM_FALLBACK_SCENE_PARAMS__', functionParams.join(', ')) - } + if (i == visualNovel.scenes.length - 2) + finishScene.push(helper.codePrepare('findViewById(android.R.id.content).setOnClickListener(null)', 0, 14, false)) - if (scene.subScenes.length == 0) { - if (scene.effect || scene.music) { - finishScene.push( - helper.codePrepare(` - if (mediaPlayer != null) { - mediaPlayer!!.stop() - mediaPlayer!!.release() - mediaPlayer = null - }\n`, 14 - ) - ) - } - - if (scene.effect && scene.music) { - finishScene.push( - helper.codePrepare(` - if (mediaPlayer2 != null) { - mediaPlayer2!!.stop() - mediaPlayer2!!.release() - mediaPlayer2 = null - }\n`, 14 - ) - ) - } - - if (scene.speech || (scene.effect && scene.effect.delay != 0) || (scene.music && scene.music.delay != 0)) - finishScene.push(helper.codePrepare('handler.removeCallbacksAndMessages(null)', 0, 14, false)) - - if (i == visualNovel.scenes.length - 2) - finishScene.push(helper.codePrepare('findViewById(android.R.id.content).setOnClickListener(null)', 0, 14, false)) - - finishScene.push(helper.codePrepare('it.setOnClickListener(null)', 0, 14, false)) + finishScene.push(helper.codePrepare('it.setOnClickListener(null)', 0, 14, false)) + if (scene.subScenes.length == 0) { let code = '\n\n' + helper.codePrepare(` findViewById(android.R.id.content).setOnClickListener { ${finishScene.join('\n')}\n\n`, 8, 0) @@ -345,18 +321,9 @@ ${finishScene.join('\n')}\n\n`, 8, 0) functionParams2.switch.push('true') } - const functionParams = [] - if (scene.speech && !nextScene.speech) { - functionParams.push('true') - } - if (scene.speech?.author?.name && nextScene.speech && !nextScene.speech?.author?.name) { - functionParams.push('true') - } - switchesCode += '\n' + helper.codePrepare(`${helper.getSceneId(scene.name)} -> ${scene.name}(${functionParams2.switch.join(', ').replace(/true/g, 'false')})`, 0, 6, false) scene.code = scene.code.replace('__PERFORVNM_SCENE_PARAMS__', functionParams2.function.join(', ')) - scene.code = scene.code.replace('__PERFORVNM_NEXT_SCENE_PARAMS__', functionParams.join(', ')) if (scene.speech) { const speechHandler = helper.codePrepare(` @@ -452,8 +419,8 @@ ${finishScene.join('\n')}\n\n`, 8, 0) visualNovel.subScenes.forEach((scene, i) => { savesSwitchCode += helper.sceneEach(scene) - if (scene.next.scene) { - const nextScene = visualNovel.scenes.find((nScene) => nScene.name == scene.next.scene) + if (scene.next) { + const nextScene = visualNovel.scenes.find((nScene) => nScene.name == scene.next) if (!nextScene) helper.logFatal('Next scene does not exist.') @@ -639,16 +606,6 @@ ${finishScene.join('\n')}\n\n`, 6, 0) if (visualNovel.achievements.length != 0) helper.writeFunction(achievements._AchievementGiveFunction()) - if (visualNovel.items.length != 0) { - helper.writeFunction(_ItemsParsingFunction()) - - helper.replace('__PERFORVNM_ITEMS_RESTORE__', _ItemsRestore()) - helper.replace(/__PERFORVNM_ITEMS_SAVER__/g, _ItemsSaver()) - } else { - helper.replace('__PERFORVNM_ITEMS_RESTORE__', '') - helper.replace(/__PERFORVNM_ITEMS_SAVER__/g, '') - } - helper.replace('__PERFORVNM_SCENES__', '') helper.replace('__PERFORVNM_MENU__', '// No menu created.') helper.replace('__PERFORVNM_CLASSES__', '') @@ -729,18 +686,11 @@ ${finishScene.join('\n')}\n\n`, 6, 0) helper.replace(/__PERFORVNM_RELEASE_MEDIA_PLAYER__/g, releaseCode) } - helper.replace(/__PERFORVNM_SCENES_LENGTH__/g, visualNovel.scenes.length + visualNovel.subScenes.length) - let addHeaders = helper.codePrepare(` private var scenes = MutableList<${visualNovel.optimizations.hashScenesNames ? 'Int' : 'String'}>(${visualNovel.scenes.length + visualNovel.subScenes.length}) { ${visualNovel.optimizations.hashScenesNames ? '0' : '""'} } private var scenesLength = 1\n`, 2 ) - if (visualNovel.items.length != 0) - addHeaders += helper.codePrepare(` - private var items = MutableList<${visualNovel.optimizations.hashItemsId ? 'Int' : 'String'}>(${visualNovel.items.length}) { ${visualNovel.optimizations.hashItemsId ? '0' : '""'} } - private var itemsLength = 0\n`, 4) - if (visualNovel.internalInfo.hasSpeech || visualNovel.internalInfo.hasDelayedSoundEffect || visualNovel.internalInfo.hasEffect || visualNovel.internalInfo.hasDelayedMusic || visualNovel.internalInfo.hasDelayedAnimation) addHeaders += helper.codePrepare('private val handler = Handler(Looper.getMainLooper())\n', 0, 2, false) diff --git a/src/helper.js b/src/helper.js index bcb012d..b3bc2c2 100644 --- a/src/helper.js +++ b/src/helper.js @@ -1,6 +1,3 @@ -/* TODO: Create helper folder and move functions to there */ -/* CRITICAL TODO: Avoid collisions in hash functions */ - import fs from 'fs' function writeFunction(sceneCode) { @@ -195,23 +192,15 @@ function codePrepare(code, removeSpaceAmount = 0, addSpaceAmount = 0, removeFirs } function addResource(page, resource) { - if (page.resources[`${resource.dp}${resource.type}`]) return page - - page.resources = { - ...page.resources, - [`${resource.dp}${resource.type}`]: { - type: resource.type, - dp: resource.dp, - spaces: resource.spaces, - ...(resource.newLines ? { newLines: resource.newLines } : {}) - } - } + if (page.resources.find((cResource) => resource.dp == cResource.dp && resource.type == cResource.type)) return page + + page.resources.push(resource) return page } function getResource(page, resource) { - const cResource = page.resources[`${resource.dp}${resource.type}`] + const cResource = page.resources.find((cResource) => resource.dp == cResource.dp && resource.type == cResource.type) if (resource.type == 'sdp') { if (!visualNovel.optimizations.reuseResources) return { @@ -270,9 +259,7 @@ function getMultipleResources(page, page2, resource) { } function finalizeResources(page, code) { - Object.keys(page.resources).forEach((key) => { - const resource = page.resources[key] - + page.resources.forEach((resource) => { const defineRegex = new RegExp(`__PERFORVNM_${resource.dp}_${resource.type}_DEFINE__`, 'g') const inlineRegex = new RegExp(`__PERFORVNM_${resource.dp}_${resource.type}_INLINE__`, 'g') const variableRegex = new RegExp(`__PERFORVNM_${resource.dp}_${resource.type}_VARIABLE__`, 'g') @@ -336,11 +323,6 @@ function getAchievementId(achievement, parsed) { } } -function getItemId(item) { - if (visualNovel.optimizations.hashItemsId) return hash(item) - else return `"${item}"` -} - function removeAllDoubleLines(code) { switch (process.platform) { case 'win32': @@ -352,21 +334,21 @@ function removeAllDoubleLines(code) { function sceneEach(scene) { - let savesSwitchLocal = codePrepare(` - ${getSceneId(scene.name)} -> { + let savesSwitchLocal = helper.codePrepare(` + ${helper.getSceneId(scene.name)} -> { when (characterData.getString("name")) {`, 0, 6, false ) scene.characters.forEach((character) => { let optimizedSetImage = '' if (visualNovel.optimizations.preCalculateScenesInfo) { - optimizedSetImage = codePrepare(` + optimizedSetImage = helper.codePrepare(` imageViewCharacter.setImageResource(R.raw.${character.image})\n\n `, 8 ) } switch (character.position.side) { case 'left': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}val leftDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.side * 0.25)}sdp) @@ -377,7 +359,7 @@ function sceneEach(scene) { break } case 'leftTop': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}val leftDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.side * 0.25)}sdp) val topDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.top * 0.25)}sdp) @@ -389,7 +371,7 @@ function sceneEach(scene) { break } case 'right': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}val rightDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.side * 0.25)}sdp) @@ -400,7 +382,7 @@ function sceneEach(scene) { break } case 'rightTop': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}val rightDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.side * 0.25)}sdp) val topDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.top * 0.25)}sdp) @@ -412,7 +394,7 @@ function sceneEach(scene) { break } case 'top': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}val topDpCharacter = resources.getDimensionPixelSize(com.intuit.sdp.R.dimen._${Math.round(character.position.margins.side * 0.25)}sdp) @@ -423,7 +405,7 @@ function sceneEach(scene) { break } case 'center': { - savesSwitchLocal += codePrepare(` + savesSwitchLocal += helper.codePrepare(` "${character.name}" -> { ${optimizedSetImage}layoutParamsImageViewCharacter.setMargins(leftDpLoad, topDpLoad, 0, 0) }`, 0, 4, false @@ -434,14 +416,14 @@ function sceneEach(scene) { } }) - return savesSwitchLocal + '\n' + codePrepare('}\n', 0, 12, false) + codePrepare('}', 0, 10, false) + return savesSwitchLocal + '\n' + helper.codePrepare('}\n', 0, 12, false) + helper.codePrepare('}', 0, 10, false) } function sceneEachFinalize(savesSwitchCode) { - return codePrepare(` + return helper.codePrepare(` when (buttonData.get${visualNovel.optimizations.hashScenesNames ? 'Int' : 'String'}("scene")) {`, 0, 4 ) + savesSwitchCode + '\n' + - codePrepare('}', 0, 8, false) + helper.codePrepare('}', 0, 8, false) } export default { @@ -462,7 +444,6 @@ export default { hash, getSceneId, getAchievementId, - getItemId, removeAllDoubleLines, sceneEach, sceneEachFinalize diff --git a/src/items.js b/src/items.js deleted file mode 100644 index 3121db4..0000000 --- a/src/items.js +++ /dev/null @@ -1,90 +0,0 @@ -/* TODO: Items searchs from O(n) to O(1) through objects */ -/* TODO: Cross-saves items */ -/* TODO: Option for scenes to require an item and if not, fallback to another scene */ - -import helper from './helper.js' - -export function init(options) { - const checks = { - 'id': { - type: 'string', - extraVerification: (param) => { - if (visualNovel.items.find((achievement) => achievement.id == param)) - helper.logFatal('An item already exists with this id.') - } - }, - 'name': { - type: 'string', - extraVerification: (param) => { - if (visualNovel.items.find((item) => item.name == param)) - helper.logFatal('An item already exists with this name.') - } - } - } - - helper.verifyParams(checks, options) - - visualNovel.items = options || [] -} - -export function give(page, itemId) { - const checks = { - 'id': { - type: 'string', - extraVerification: (param) => { - if (!visualNovel.items.find((item) => item.id == param)) - helper.logFatal(`The item '${param}' doesn't exist.`) - - if (page.items.give.find((item) => item.id == param)) - helper.logFatal(`The item '${param}' was already given.`) - } - } - } - - page.items.give.push(itemId) - - return page -} - -export function _ItemGive(item) { - return helper.codePrepare(` - items.set(itemsLength, ${helper.getItemId(item)}) - itemsLength++\n\n`) -} - -export function _ItemRemove(item) { - return helper.codePrepare(` - items.set(itemsLength, ${visualNovel.optimizations.hashItemsId ? '0' : '""'}) - itemsLength--`, 0, 6) -} - -export function _ItemsParsingFunction() { - return helper.codePrepare(` - private fun itemsToJson(): String { - var json = "[" - - for (i in 0 until itemsLength) { - json += ${visualNovel.optimizations.hashItemsId ? 'items.get(i).toString() + "' : '"\\"" + items.get(i) + "\\"'}," - } - - return json.dropLast(1) + "]" - }`, 2) -} - -export function _ItemsRestore() { - return helper.codePrepare(`\n - val sceneItems = buttonData.getJSONArray("items") - for (j in 0 until sceneItems.length()) { - items.set(j, sceneItems.getInt(j)) - } - itemsLength = sceneItems.length()`, 0, 4, false) -} - -export function _ItemsSaver() { - return helper.codePrepare(` ",\\"items\\":" + itemsToJson() + `, 0, 0, false) -} - -export default { - init, - give -} \ No newline at end of file diff --git a/src/menu.js b/src/menu.js index 1005250..043bde9 100644 --- a/src/menu.js +++ b/src/menu.js @@ -1,6 +1,3 @@ -/* TODO: Allow to remove footer and add buttons manually */ -/* TODO (Critical): Fix saves, if saves topDp > 620 then it will crash the app */ - import helper from './helper.js' function init(options) { @@ -71,33 +68,32 @@ function init(options) { custom: [], pages: { main: { - resources: {} + resources: [] }, about: { - resources: {} + resources: [] }, settings: { - resources: {} + resources: [] }, saves: { - resources: {} + resources: [] }, savesFor: { - resources: {} + resources: [] }, achievements: { - resources: {} + resources: [] }, achievementsFor: { - resources: {} + resources: [] } }, - resources: {} + resources: [] } } function finalize(menu) { - /* TODO: Centralized private function that will generate custom code */ let customCode = '' menu.custom.forEach((custom, index) => { switch (custom.type) { @@ -1849,7 +1845,7 @@ __PERFORVNM_SAVES_SWITCH__ for (j in 0 until historyScenes.length()) { scenes.set(j, historyScenes.get${visualNovel.optimizations.hashScenesNames ? 'Int' : 'String'}(j)) } - scenesLength = historyScenes.length()__PERFORVNM_ITEMS_RESTORE__ + scenesLength = historyScenes.length() switchScene(buttonData.${visualNovel.optimizations.hashScenesNames ? 'getInt' : 'getString'}("scene")) } diff --git a/src/scene.js b/src/scene.js index 64cc557..a5ec007 100644 --- a/src/scene.js +++ b/src/scene.js @@ -1,10 +1,5 @@ -/* TODO: Scenes searchs from O(n) to O(1) through objects */ -/* TODO (unconfirmed): Set the scenes in order through a queue [ 'scene1', 'scene2', ... ] */ - import helper from './helper.js' -import { _ItemGive, _ItemRemove } from './items.js' - function init(options) { const checks = { 'name': { @@ -49,12 +44,8 @@ function init(options) { music: null, transition: null, achievements: [], - items: { - give: [], - require: [] - }, custom: [], - resources: {} + resources: [] } } @@ -308,41 +299,12 @@ function setNextScene(scene, options) { const checks = { 'scene': { type: 'string' - }, - 'item': { - type: 'object', - required: false, - params: { - 'require': { - type: 'object', - params: { - 'id': { - type: 'string', - extraVerification: (param) => { - if (!visualNovel.items.find((item) => item.id == param)) - helper.logFatal(`The item '${param}' doesn't exist.`) - } - }, - 'fallback': { - type: 'string', - } - } - }, - 'remove': { - type: 'boolean', - required: false, - extraVerification: (param, additionalinfo) => { - if (param && !additionalinfo.parent?.require?.id) - helper.logFatal('You must specify an item to be removed once used.') - } - } - } } } helper.verifyParams(checks, options) - scene.next = options + scene.next = options.scene return scene } @@ -352,27 +314,6 @@ function addSubScenes(scene, options) { 'text': { type: 'string' }, - 'item': { - type: 'object', - required: false, - params: { - 'require': { - type: 'string', - extraVerification: (param) => { - if (!visualNovel.items.find((item) => item.id == param)) - helper.logFatal(`The item '${param}' doesn't exist.`) - } - }, - 'remove': { - type: 'boolean', - required: false, - extraVerification: (param, additionalinfo) => { - if (param && !additionalinfo.parent?.item?.require) - helper.logFatal('You must specify an item to be removed once used.') - } - } - } - }, 'scene': { type: 'string', extraVerification: (param) => { @@ -881,7 +822,7 @@ function finalize(scene) { rectangleViewSpeech.layoutParams = layoutParamsRectangleSpeech\n`, 2, 0, false ) - const oldScene = visualNovel.subScenes.find((subScene) => subScene.next.scene == scene.name) || visualNovel.scenes[visualNovel.scenes.length - 1] + const oldScene = visualNovel.subScenes.find((subScene) => subScene.next == scene.name) || visualNovel.scenes[visualNovel.scenes.length - 1] if (visualNovel.scenes.length != 0 && oldScene.speech) { sceneCode += helper.codePrepare(`rectangleViewSpeech.setAlpha(${scene.speech.text.rectangle.opacity}f)\n`, 0, 4, false) @@ -989,7 +930,7 @@ function finalize(scene) { textViewAuthor.layoutParams = layoutParamsAuthor\n\n`, 4, 0, false ) - const oldScene = visualNovel.subScenes.find((subScene) => subScene.next.scene == scene.name) || visualNovel.scenes[visualNovel.scenes.length - 1] + const oldScene = visualNovel.subScenes.find((subScene) => subScene.next == scene.name) || visualNovel.scenes[visualNovel.scenes.length - 1] if ( visualNovel.scenes.length == 0 || @@ -1133,7 +1074,7 @@ function finalize(scene) { mediaPlayer!!.stop() mediaPlayer!!.release() mediaPlayer = null - }`, 0, 2 + }` ) ) } @@ -1145,7 +1086,7 @@ function finalize(scene) { mediaPlayer!!.stop() mediaPlayer!!.release() mediaPlayer = null - }`, 0, 2 + }` ) ) @@ -1155,22 +1096,15 @@ function finalize(scene) { mediaPlayer2!!.stop() mediaPlayer2!!.release() mediaPlayer2 = null - }`, 0, 2 + }` ) ) } if (scene.speech || (scene.effect && scene.effect.delay != 0) || (scene.music && scene.music.delay != 0)) - finishScene.push(helper.codePrepare('handler.removeCallbacksAndMessages(null)', 0, 10, false)) + finishScene.push(helper.codePrepare('handler.removeCallbacksAndMessages(null)', 0, 8, false)) - finishScene.push(helper.codePrepare('findViewById(android.R.id.content).setOnClickListener(null)', 0, 10, false)) - - const itemRemover = [] - if (scene.items.give.length != 0) { - scene.items.give.forEach((item) => { - itemRemover.push(_ItemRemove(item)) - }) - } + finishScene.push(helper.codePrepare('findViewById(android.R.id.content).setOnClickListener(null)', 0, 8, false)) const buttonSizeSsp = helper.getResource(scene, { type: 'ssp', dp: '8' }) scene = helper.addResource(scene, { type: 'ssp', dp: '8', spaces: 4 }) @@ -1246,7 +1180,7 @@ function finalize(scene) { scene = helper.addResource(scene, { type: 'sdp', dp: '23', spaces: 4 }) sceneCode += helper.codePrepare(` - val newSave = "${JSON.stringify(JSON.stringify(sceneJson)).slice(1, -2)},\\"history\\":" + scenesToJson() +__PERFORVNM_ITEMS_SAVER__ "}" + val newSave = "${JSON.stringify(JSON.stringify(sceneJson)).slice(1, -2)},\\"history\\":" + scenesToJson() + "}" if (saves == "[]") saves = "[" + newSave + "]" else saves = saves.dropLast(1) + "," + newSave + "]" @@ -1275,23 +1209,9 @@ function finalize(scene) { buttonMenu.layoutParams = layoutParamsMenu\n\n` ) - let itemsRemove = '' - if (visualNovel.items.length != 0) { - itemsRemove = helper.codePrepare(`\n - for (j in 0 until itemsLength) { - items.set(j, ${visualNovel.optimizations.hashItemsId ? '0' : '""'}) - } - itemsLength = 0`, 0, 4, false - ) - } sceneCode += helper.codePrepare(` - buttonMenu.setOnClickListener { - for (j in 0 until scenesLength) { - scenes.set(j, ${visualNovel.optimizations.hashScenesNames ? '0' : '""'}) - } - scenesLength = 0${itemsRemove} - -${finishScene.join('\n\n')}__PERFORVNM_START_MUSIC__\n\n`, 4 + buttonMenu.setOnClickListener { +${finishScene.join('\n\n')}__PERFORVNM_START_MUSIC__\n\n`, 2 ) sceneCode += helper.codePrepare(` @@ -1324,13 +1244,13 @@ ${finishScene.join('\n\n')}__PERFORVNM_START_MUSIC__\n\n`, 4 ) sceneCode += helper.codePrepare(` - buttonBack.setOnClickListener { -${finishScene.join('\n\n')}${itemRemover.join('\n\n')}\n\n`, 4 + buttonBack.setOnClickListener { +${finishScene.join('\n\n')}\n\n`, 2 ) - let oldScene = visualNovel.subScenes.find((subScene) => subScene.next.scene == scene.name) + const oldScene = visualNovel.subScenes.find((subScene) => subScene.next == scene.name) || visualNovel.scenes[visualNovel.scenes.length - 1] - if (oldScene || visualNovel.scenes.find((cScene) => scene.name == cScene.next?.item?.require?.fallback) || visualNovel.subScenes.find((cScene) => scene.name == cScene.next?.item?.require?.fallback)) { + if (visualNovel.subScenes.find((subScene) => subScene.next == scene.name)) { sceneCode += helper.codePrepare(` val scene = scenes.get(scenesLength - 1) @@ -1340,24 +1260,14 @@ ${finishScene.join('\n\n')}${itemRemover.join('\n\n')}\n\n`, 4 switchScene(scene)\n`, 2 ) } else { - oldScene = visualNovel.scenes[visualNovel.scenes.length - 1] - - const functionParams = [] - const olderOldScene = visualNovel.subScenes.find((subScene) => subScene.next.scene == oldScene.name) - - if (olderOldScene) { - if (olderOldScene.speech && oldScene.speech) functionParams.push('false') - if (olderOldScene.speech?.author?.name && olderOldScene.speech && !olderOldScene.speech?.author?.name) functionParams.push('false') - } - if (visualNovel.scenes.length == 1) { - sceneCode += helper.codePrepare(`${oldScene.name}(${functionParams.join(', ')})\n`, 0, 6, false) + sceneCode += helper.codePrepare(`${oldScene.name}(${(oldScene.speech ? 'false' : '' )})\n`, 0, 6, false) } else { sceneCode += helper.codePrepare(` scenesLength-- scenes.set(scenesLength, ${visualNovel.optimizations.hashScenesNames ? '0' : '""'}) - ${oldScene.name}(${functionParams.join(', ')})\n`, 4 + ${oldScene.name}(${(oldScene.speech ? 'false' : '' )})\n`, 4 ) } } @@ -1401,72 +1311,43 @@ ${finishScene.join('\n\n')}${itemRemover.join('\n\n')}\n\n`, 4 const sdp150 = helper.getResource(scene, { type: 'sdp', dp: '150' }) scene = helper.addResource(scene, { type: 'sdp', dp: '150', spaces: 4 }) - let requireItems = [ '', '' ] - let i = 0 - - while (true) { - if (scene.subScenes[i].item?.require) { - requireItems[i] = helper.codePrepare(` - if (!items.contains(${helper.getItemId(scene.subScenes[0].item.require)})) { - Toast.makeText(this, "You don't have the required item.", Toast.LENGTH_SHORT).show()`) - - if (scene.subScenes[i].item.remove) { - requireItems[i] += helper.codePrepare(` - items.remove(${helper.getItemId(scene.subScenes[0].item.require)}) - - return@setOnClickListener - }\n\n`, 2, 0, false) - } else { - requireItems[i] += helper.codePrepare(`\n - return@setOnClickListener - }\n\n`, 2, 0, false) - } - } - - if (i == 1) break - - i++ - } - sceneCode += helper.codePrepare(` - buttonSubScenes.setOnClickListener { -${requireItems[0]}${finishScene.join('\n\n')} + buttonSubScenes.setOnClickListener { +${finishScene.join('\n\n')} - __PERFORVNM_SUBSCENE_1__ - } + __PERFORVNM_SUBSCENE_1__ + } - frameLayout.addView(buttonSubScenes) + frameLayout.addView(buttonSubScenes) - val buttonSubScenes2 = Button(this) - buttonSubScenes2.text = "${scene.subScenes[1].text}" - buttonSubScenes2.setTextSize(TypedValue.COMPLEX_UNIT_PX, ${subScenesTextSsp.variable}) - buttonSubScenes2.setTextColor(0xFF${scene.options.buttonsColor}.toInt()) - buttonSubScenes2.background = null + val buttonSubScenes2 = Button(this) + buttonSubScenes2.text = "${scene.subScenes[1].text}" + buttonSubScenes2.setTextSize(TypedValue.COMPLEX_UNIT_PX, ${subScenesTextSsp.variable}) + buttonSubScenes2.setTextColor(0xFF${scene.options.buttonsColor}.toInt()) + buttonSubScenes2.background = null - val layoutParamsSubScenes2 = LayoutParams( - LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT - ) + val layoutParamsSubScenes2 = LayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT + ) - ${sdp150.definition}layoutParamsSubScenes2.gravity = Gravity.CENTER_HORIZONTAL - layoutParamsSubScenes2.setMargins(0, ${sdp150.variable}, 0, 0) + ${sdp150.definition}layoutParamsSubScenes2.gravity = Gravity.CENTER_HORIZONTAL + layoutParamsSubScenes2.setMargins(0, ${sdp150.variable}, 0, 0) - buttonSubScenes2.layoutParams = layoutParamsSubScenes2 + buttonSubScenes2.layoutParams = layoutParamsSubScenes2 - buttonSubScenes2.setOnClickListener { -${requireItems[1]}${finishScene.join('\n\n')} + buttonSubScenes2.setOnClickListener { +${finishScene.join('\n\n')} - __PERFORVNM_SUBSCENE_2__ - } + __PERFORVNM_SUBSCENE_2__ + } - frameLayout.addView(buttonSubScenes2)\n\n`, 4 + frameLayout.addView(buttonSubScenes2)\n\n`, 2 ) } else if (scene.subScenes.length != 0) { - /* TODO: Allow to have more than 2 sub-scenes */ helper.logWarning('Unecessary sub-scenes, only 2 are allowed.', 'Android') } - /* TODO: Centralized private function that will generate custom code */ scene.custom.forEach((custom, index) => { switch (custom.type) { case 'text': { @@ -1849,39 +1730,32 @@ ${requireItems[1]}${finishScene.join('\n\n')} else return `giveAchievement(${helper.getAchievementId(achievement.id)}, "${helper.getAchievementId(achievement.id, true)}")` }).join('\n')}\n\n`, 2) - } /* TODO: Move this to private function of achievements.js */ - - scene.items.give.forEach((item) => sceneCode += _ItemGive(item)) - - if (scene.next?.scene) { - let nextCode = helper.codePrepare(`${scene.next.scene}(__PERFORVNM_NEXT_SCENE_PARAMS__)`, 0, 10, false) + } - if (scene.next.item?.require) { - nextCode = helper.codePrepare(` - if (!items.contains(${helper.getItemId(scene.next.item.require.id)})) { - ${scene.next.item.require.fallback}(__PERFORVNM_FALLBACK_SCENE_PARAMS__) - } else { - ${scene.next.scene}(__PERFORVNM_NEXT_SCENE_PARAMS__) - }`, 0, 2) - } + if (scene.type == 'normal') { sceneCode += helper.codePrepare(` - findViewById(android.R.id.content).setOnClickListener { -${finishScene.join('\n\n')} - - scenes.set(scenesLength, ${helper.getSceneId(scene.name)}) - scenesLength++ - -${nextCode} - } - - setContentView(frameLayout) + setContentView(frameLayout)__PERFORVNM_SCENE_${scene.name.toUpperCase()}__ }`, 4 ) } else { - sceneCode += helper.codePrepare(` - setContentView(frameLayout) - }`, 4 - ) + if (scene.next) { + sceneCode += helper.codePrepare(` + findViewById(android.R.id.content).setOnClickListener { + scenes.set(scenesLength, ${helper.getSceneId(scene.name)}) + scenesLength++ + + ${scene.next}(__PERFORVNM_NEXT_SCENE_PARAMS__) + } + + setContentView(frameLayout) + }`, 6 + ) + } else { + sceneCode += helper.codePrepare(` + setContentView(frameLayout) + }`, 6 + ) + } } sceneCode = helper.finalizeResources(scene, sceneCode) diff --git a/src/sub-scene.js b/src/sub-scene.js index ce0fa5a..b40f631 100644 --- a/src/sub-scene.js +++ b/src/sub-scene.js @@ -1,5 +1,3 @@ -/* TODO: Sub-scene searchs from O(n) to O(1) through objects */ - import helper from './helper.js' function init(options) { @@ -46,12 +44,8 @@ function init(options) { music: null, transition: null, achievements: [], - items: { - give: [], - require: [] - }, custom: [], - resources: {} + resources: [] } } diff --git a/tests/vn.js b/tests/vn.js index 20c1757..d93f3c8 100644 --- a/tests/vn.js +++ b/tests/vn.js @@ -14,7 +14,6 @@ perfor.coder.init({ hashAchievementIds: true, hashScenesNames: true, reuseResources: true, - hashItemsId: true, // minify: true } }) @@ -93,11 +92,6 @@ perfor.achievements.init([{ image: 'achievement' }]) -perfor.items.init([{ - id: 'first_item', - name: 'First item' -}]) - let firstScene = perfor.scene.init({ name: 'scene1', textColor: 'FFFFFF', @@ -161,20 +155,8 @@ firstScene = perfor.custom.addCustomRectangle(firstScene, { firstScene = perfor.scene.addScenario(firstScene, { image: 'background_thanking' }) /* Adds a scenario to the scene */ firstScene = perfor.scene.addSoundEffects(firstScene, [{ sound: 'menu_music', delay: 0 }]) /* Adds a sound effect to the scene at second 1 */ firstScene = perfor.scene.addTransition(firstScene, { duration: 1000 }) /* Adds a transition to the scene */ -firstScene = perfor.scene.addSubScenes(firstScene, [{ - text: 'second', - scene: 'scene2', - item: { - require: 'first_item', - remove: true - } - }, { - text: 'third', - scene: 'scene3' - } -]) /* Adds the subscenes to the first scene */ +firstScene = perfor.scene.addSubScenes(firstScene, [{ text: 'second', scene: 'scene2' }, { text: 'third', scene: 'scene3' }]) /* Adds the subscenes to the first scene */ firstScene = perfor.achievements.give(firstScene, 'first_achievement') /* Gives the first achievement to the scene */ -firstScene = perfor.items.give(firstScene, 'first_item') /* Gives the first item to the scene */ perfor.scene.finalize(firstScene) /* Finishes up the scene */ let secondScene = perfor.subScene.init({ @@ -313,16 +295,7 @@ fourthScene = perfor.scene.addSpeech(fourthScene, { } } }) -fourthScene = perfor.scene.setNextScene(fourthScene, { - scene: 'scene5', - item: { - require: { - id: 'first_item', - fallback: 'no_items' - }, - remove: true - } -}) +fourthScene = perfor.scene.setNextScene(fourthScene, { scene: 'scene5' }) perfor.scene.finalize(fourthScene) let fifthScene = perfor.scene.init({ @@ -365,44 +338,4 @@ fifthScene = perfor.scene.addSpeech(fifthScene, { }) perfor.scene.finalize(fifthScene) -let noItemsScene = perfor.scene.init({ - name: 'no_items', - textColor: 'FFFFFF', - backTextColor: 'FFFFFF', - buttonsColor: 'FFFFFF', - footerTextColor: 'FFFFFF' -}) -noItemsScene = perfor.scene.addCharacter(noItemsScene, { - name: 'Pedro', - image: 'pedro_staring', - position: { - side: 'left', - margins: { - side: 20, - top: 0 - } - } -}) -noItemsScene = perfor.scene.addScenario(noItemsScene, { image: 'background_thanking' }) -noItemsScene = perfor.scene.addSpeech(noItemsScene, { - author: { - name: 'Pedro', - textColor: 'FFFFFF', - rectangle: { - color: '000000', - opacity: 0.6 - } - }, - text: { - content: '"You don\'t have the item, sorry."', - color: 'FFFFFF', - fontSize: 9, - rectangle: { - color: '000000', - opacity: 0.8 - } - } -}) -perfor.scene.finalize(noItemsScene) - perfor.coder.finalize() /* Finishes up the code */