From c084fd380841dab2236b97a3b041678d43f19847 Mon Sep 17 00:00:00 2001 From: FrobozzWaxwing Date: Sat, 8 Apr 2023 01:58:48 -0500 Subject: [PATCH] Version 0.1.0. Launch of public beta. * Fixed a display bug when refreshing the list of properties associated with a character on the character editing screen. * Selecting a property on the property creation screen will now load the property for editing; double-clicking is no longer needed. However, only one property can be selected at a time, now. * Fixed a bug involving authored properties that applied to specific characters rather than the entire cast. * Changed lapis lazuli theme to use custom close icons for popup windows. * Changed titles of PersonalityModel and GraphView tabs to have spaces between the words. * Updated README.txt file. * Changed patron lists in editor. * Added tooltips to add, delete, move, and edit buttons on various screens in editor. * Made minor changes to how property creation screen looks, to bring it more in line with how other screens look. * Fixed a bug on the settings screen so that it will now correctly display the save path. * Updated download link on updates screen. * Updated project load functions and incremented version number from 0.0.38 to 0.1.0. --- README.md | 139 ++---------------- godot/Actor.gd | 18 ++- godot/AuthoredPropertyCreationScreen.gd | 34 +++-- godot/AuthoredPropertyCreationScreen.tscn | 70 +++++---- godot/BNumberEffect.gd | 4 +- godot/CharacterEditScreen.tscn | 6 +- godot/CharacterTraitEditingInterface.gd | 31 +++- godot/CharacterTraitEditingInterface.tscn | 9 +- godot/DocPageDisplay.tscn | 2 + godot/EncounterEditScreen.tscn | 15 +- godot/GUI.gd | 10 +- godot/GUI.tscn | 6 +- godot/PlayScreen.tscn | 1 + .../SearchandReplace.gd | 0 .../SearchandReplace.tscn | 2 +- godot/SettingsEditScreen.gd | 4 +- godot/SpoolEditScreen.tscn | 2 + godot/SpoolEffect.gd | 4 +- godot/Storyworld.gd | 36 +++-- godot/UpdateScreen.gd | 2 +- godot/custom_resources/lapis_lazuli.tres | 6 +- .../writing_with_sweepweave.json | 4 +- godot/custom_resources/x.svg | 40 +++++ godot/custom_resources/x_green.svg | 40 +++++ godot/export_presets.cfg | 33 ++++- godot/sw_scripting/ScriptManager.gd | 8 +- 26 files changed, 305 insertions(+), 221 deletions(-) rename godot/{custom_resources => }/SearchandReplace.gd (100%) rename godot/{custom_resources => }/SearchandReplace.tscn (89%) create mode 100644 godot/custom_resources/x.svg create mode 100644 godot/custom_resources/x_green.svg diff --git a/README.md b/README.md index 4c25779..3374315 100644 --- a/README.md +++ b/README.md @@ -1,140 +1,27 @@ # SweepWeave -SweepWeave is an integrated development environment for creating interactive storyworlds. Storyworlds are computer games, or interactive fiction works, which focus on interaction with fictional characters as the central game mechanic, which track dynamic relationships between characters, (including, in particular, between non-player characters and the player character,) and which employ these simulated characters and relationships to assemble pieces of handcrafted content into a coherent narrative shaped, in part, by player choice. +SweepWeave is an integrated development environment for creating interactive storyworlds. Storyworlds are computer games which focus on interaction with fictional characters as the central game mechanic, which track dynamic relationships between characters, and which employ these simulated characters and relationships to assemble pieces of handcrafted content into a coherent narrative shaped, in part, by player choice. -SweepWeave is based on design work by Chris Crawford and Sasha Fenn, and has been coded and implemented by Sasha Fenn. The suite consists of a storyworld interpretter, written in html and javascript, and a storyworld editor, written in the Godot game engine. Storyworlds are written and scripted in the editor, projects can be saved as .json files, and storyworlds can be exported as standalone html pages, which combine the interpreter with a block of data unique to the storyworld, and which can be played in a web browser. +SweepWeave is based on design work by Chris Crawford and Sasha Fenn, and has been coded and implemented by Sasha Fenn. The suite consists of a storyworld interpreter, written in html and javascript, and a storyworld editor, written in the Godot game engine. Storyworlds can be exported as standalone html pages, which can be played in a web browser. -Storyworlds consist of a collection of characters and a collection of "encounters," which contain the game's story content. - -*********** -Characters: -*********** - -Each character has personality traits, which track their tendency to act in certain ways, and traits that track their relationship to the player character over the course of the game. - -Both personality traits and relationship traits are tracked via "bounded numbers," which are numbers limited to the range: -1 to 1, (including the lower and upper limits within the range.) - -*********** -Encounters: -*********** - -Each encounter includes a title, a piece of main text that can describe events that happen within the story, a set of options for the player to choose from, such that they can respond to story events, and a set of reactions associated with each of these options, such that a specified character can react to the player's choice. - -Authors can also change the settings of the encounter and the options available to the player, changing when encounters occur or when certain options are available for players to choose. - -Each encounter has a single character associated with it as an "antagonist;" this character's personality and relationship traits are used by the game to determine which reaction occurs after the player has chosen an option. Each reaction has an associated script by which the game calculates the character's inclination to select that reaction; during play, the reaction with the highest inclination is selected. (Ties are broken by choosing the earlier reaction in the list of reactions for the option in question.) - -Once a reaction has been selected by the a.i., the game may also change the relationships between any non-player character and the player character. This allows authors to set certain consequences to occur as a result of the player's choices. In turn, these consequences can carry over to later parts of the story, since character relationships can affect which encounters occur, at what time they occur, and how characters react to the player's actions. - -Reactions may also cause a specific encounter to occur next, bypassing the usual methods used by the game to select which encounter occurs. - -********* -Gameplay: -********* - -A playthrough runs through the following process: - -1) The game selects an encounter to display. - 1-A) If the reaction selected during the last encounter specifies an encounter to occur next, this encounter is displayed. - 1-B) Otherwise, the game tests each encounter in the storyworld, checking when it can occur and whether all of its prerequisites are met. - 1-C) The game then calculates the desirability of each valid encounter, displaying the most desirable encounter and displaying it to the player. -2) The game displays an encounter. - 2-A) The encounter's main text is displayed to the player. - 2-B) The game calculates each option's visibility and performability prerequisites, displaying only those which meet their visibility prerequisites, and only allowing players to choose one that meets both its visibility and performability prerequisites. - 2-C) If no options pass their visibility and performability prerequisites, or the encounter has no options, then the game ends with this encounter. -3) The player chooses an option. -4) The game selects a reaction for the encounter's antagonist to perform, and displays the text of this reaction to the player. - 4-A) The game calculates the inclination of each reaction associated with the option chosen by the player. This is done using the scripts associated with each reaction, which use the antagonist's personality and relationship traits. - 4-B) The reaction with the highest inclination is selected. - 4-C) The game resets the options panel to display only the option the player chose. - 4-D) The text of the selected reaction is displayed to the player. This text can, for example, describe the antagonist's actions in response to the player's choice. - 4-E) The relationship changes associated with the selected reaction are calculated, and the game changes the designated character relationships accordingly. (The relationships of any character in the game can be changed, during this phase.) - 4-F) The game takes note of whether or not the selected reaction forces a specific encounter to occur next, and, if so, of which encounter must occur. -5) The game returns to step 1, repeating this loop until the game runs out of valid encounters, or reaches an encounter without any performable options, at which point the story ends. - -********** -Scripting: -********** - -Storyworlds employ scripts for several sets of calculations. This section contains some technical details for those interested. - -1) Reactions: - -When the game calculates the inclinations for each reaction associated with a given option, it looks up two of the current antagonist's traits and blends them together. This "blend" operation is a weighted average of the two traits. A weighting factor of -1 will set the result equal to the first trait, a weight of 1 will set it equal to the second trait, and a weight of 0 will set it equal to the simple average of both traits, (i.e., adding up the value of both traits and dividing by two.) - -If one normalizes the weight from a number between -1 and 1 to a number between 0 and 1, (which can be done by averaging the weight with the number 1,) then the algorithm for a blend calculation consists of the following: - -Result = x * (1 - w) + y * w. - -Here, "x" equals the value of the first trait, y equals the value of the second trait, and w equals the value of the normalized weight. - -2) Consequences: - -Once a reaction occurs, the game may change the value of various character relationships. Authors can determine what modifications are made by setting up "blend change" scripts. Simply select the character and pValue to modify, then choose a weight. - -A weight of 0 will leave the relationship unchanged. A weight above 0 will increase the value of the relationship trait, (i.e., the selected pValue.) A weight below 0 will decrease the pValue. - -The change made either increases or decreases the pValue a certain percentage of the distance towards the upper or lower limit. For example, a weight of 1 will increase the pValue 100% of the distance towards 1, (i.e., the pValue will be set to 1.) A weight of 0.5 will increase the pValue 50% of the distance from its present value to 1. For example, if the character's current level of affection for the player character equals 0.2, and the designated weight equals 0.5, then the character's affection for the player character will increase to 0.6. - -The algorithm for blend change operations consists of the following: - -Result = x * (1 - absolute_value_of(delta)) + delta. - -Here, "x" is the current value of the relationship trait in question, and "delta" is the weighting factor. - -3) Encounter Settings: - -Encounters can have both prerequisites and target conditions. Prerequisites allow authors to set encounters to only occur when certain conditions are met, for example when another encounter has occurred earlier in the playthrough. Target conditions are used by the game to calculate the desirability of each encounter. - -Target conditions use a distance calculation to determine the encounter's desirability. - -4) Option Settings: - -Options can also have prerequisites, which determine whether or not an option is visible should the encounter occur, as well as whether the player can choose the option when it is visible. - -******** -Credits: -******** +To run SweepWeave on Linux, you will need to manually change the permissions of the executable file, (the .x86_64 file,) after downloading it so that you can run the program. SweepWeave is available as open source software under an MIT License. All storyworlds created with SweepWeave belong to their respective authors. You are free to publish your storyworlds as you please, including for commercial purposes. +Updates regarding SweepWeave's development can be found at https://sweepweave.org/ +SweepWeave can be downloaded from https://github.com/FrobozzWaxwing/Sweep_Weave/releases +Discussion of storyworld design and development can be had on Discord: https://discord.gg/a3aXjtAuDF Chris Crawford can be found online at http://erasmatazz.com/ -Sasha Fenn can be found online at https://www.patreon.com/sasha_fenn -SweepWeave can be downloaded from http://www.emptiestvoid.com/encounter_system/ -If you would like to help support me financially, you can do so through my Patreon page, reached via the second link above. +If you would like to help support me financially, you can do so through my Patreon page: +https://www.patreon.com/sasha_fenn + Thanks to my patrons for their encouragement and support: -Pamela Beck Chris Conley Jóhannes Ævarsson - -You can contact me through Chris Crawford's Thaddeus discussion board, through our interactive storytelling workgroup on Slack, via github, or through my Patreon page. On github I am FrobozzWaxwing. +Felipe Vega +Pixel Brownie Software +Craig Maloney Thanks, and peace to you. -~Sasha Fenn - -******** -License: -******** - -MIT License - -Copyright (c) 2020-2021 ~ Sasha Fenn - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +~Sasha Fenn \ No newline at end of file diff --git a/godot/Actor.gd b/godot/Actor.gd index d1f58f1..470b769 100644 --- a/godot/Actor.gd +++ b/godot/Actor.gd @@ -41,8 +41,8 @@ func set_as_copy_of(in_character, create_mutual_links = true): bnumber_properties = in_character.bnumber_properties.duplicate(true) authored_properties = [] authored_property_directory = {} - #Sanity check: for property in in_character.authored_properties: + #Sanity check: if (is_instance_valid(property)): index_authored_property(property) if (create_mutual_links): @@ -56,14 +56,18 @@ func set_as_copy_of(in_character, create_mutual_links = true): func remap(to_storyworld): storyworld = to_storyworld + var properties_to_index = authored_properties.duplicate() authored_properties = [] authored_property_directory = {} - for property_blueprint in storyworld.authored_properties: - if (property_blueprint.attribution_target == property_blueprint.possible_attribution_targets.ENTIRE_CAST): - index_authored_property(property_blueprint) - elif (property_blueprint.attribution_target == property_blueprint.possible_attribution_targets.CAST_MEMBERS): - if (property_blueprint.affected_characters.has(self)): - index_authored_property(property_blueprint) + for property_blueprint in properties_to_index: + if (storyworld.authored_property_directory.has(property_blueprint.id)): + index_authored_property(storyworld.authored_property_directory[property_blueprint.id]) +# for property_blueprint in storyworld.authored_properties: +# if (property_blueprint.attribution_target == property_blueprint.possible_attribution_targets.ENTIRE_CAST): +# index_authored_property(property_blueprint) +# elif (property_blueprint.attribution_target == property_blueprint.possible_attribution_targets.CAST_MEMBERS): +# if (property_blueprint.affected_characters.has(self)): +# index_authored_property(property_blueprint) func set_classical_personality_model(in_Bad_Good, in_False_Honest, in_Timid_Dominant, in_pBad_Good, in_pFalse_Honest, in_pTimid_Dominant): initialize_bnumber_properties() diff --git a/godot/AuthoredPropertyCreationScreen.gd b/godot/AuthoredPropertyCreationScreen.gd index 1f6fa35..e5f9454 100644 --- a/godot/AuthoredPropertyCreationScreen.gd +++ b/godot/AuthoredPropertyCreationScreen.gd @@ -25,22 +25,22 @@ func load_authored_property(property_blueprint): $PropertyCreationWindow/VBC/BNumberEditPanel.creating_new_property = false $ColorRect/VBC/HBC/BNumberEditPanel.refresh() if (!storyworld.authored_properties.empty()): - $ColorRect/VBC/HBC/VBC1/PropertyList.select(storyworld.authored_properties.find(property_blueprint)) + $ColorRect/VBC/HBC/VBC/PropertyList.select(storyworld.authored_properties.find(property_blueprint)) func refresh_property_list(): - $ColorRect/VBC/HBC/VBC1/PropertyList.clear() + $ColorRect/VBC/HBC/VBC/PropertyList.clear() var item_index = 0 for property_blueprint in storyworld.authored_properties: - $ColorRect/VBC/HBC/VBC1/PropertyList.add_item(property_blueprint.get_property_name()) - $ColorRect/VBC/HBC/VBC1/PropertyList.set_item_metadata(item_index, property_blueprint) + $ColorRect/VBC/HBC/VBC/PropertyList.add_item(property_blueprint.get_property_name()) + $ColorRect/VBC/HBC/VBC/PropertyList.set_item_metadata(item_index, property_blueprint) item_index += 1 if (!storyworld.authored_properties.empty()): load_authored_property(storyworld.authored_properties.front()) func refresh_property_name(property_blueprint): var index = storyworld.authored_properties.find(property_blueprint) - if (property_blueprint == $ColorRect/VBC/HBC/VBC1/PropertyList.get_item_metadata(index)): - $ColorRect/VBC/HBC/VBC1/PropertyList.set_item_text(index, property_blueprint.get_property_name()) + if (property_blueprint == $ColorRect/VBC/HBC/VBC/PropertyList.get_item_metadata(index)): + $ColorRect/VBC/HBC/VBC/PropertyList.set_item_text(index, property_blueprint.get_property_name()) else: refresh_property_list() emit_signal("refresh_authored_property_lists") @@ -75,7 +75,7 @@ func _on_DeleteButton_pressed(): each.call_deferred('free') #Refill window. var new_label = Label.new() - var selected_indices = $ColorRect/VBC/HBC/VBC1/PropertyList.get_selected_items() + var selected_indices = $ColorRect/VBC/HBC/VBC/PropertyList.get_selected_items() authored_properties_to_delete.clear() if (0 == selected_indices.size()): #No properties are currently selected. @@ -86,7 +86,7 @@ func _on_DeleteButton_pressed(): new_label.text = "You cannot delete all authored properties from your storyworld." $ConfirmPropertyDeletionWindow/VBC.add_child(new_label) elif (1 == selected_indices.size()): - var property_blueprint = $ColorRect/VBC/HBC/VBC1/PropertyList.get_item_metadata(selected_indices[0]) + var property_blueprint = $ColorRect/VBC/HBC/VBC/PropertyList.get_item_metadata(selected_indices[0]) new_label.text = "Are you sure that you want to remove the \"" + property_blueprint.get_property_name() + "\" property from your storyworld?" $ConfirmPropertyDeletionWindow/VBC.add_child(new_label) authored_properties_to_delete.append(property_blueprint) @@ -94,7 +94,7 @@ func _on_DeleteButton_pressed(): new_label.text = "Are you sure that you want to remove the following authored properties? This will delete these properties from all characters and scripts." $ConfirmPropertyDeletionWindow/VBC.add_child(new_label) for index in selected_indices: - var property_blueprint = $ColorRect/VBC/HBC/VBC1/PropertyList.get_item_metadata(index) + var property_blueprint = $ColorRect/VBC/HBC/VBC/PropertyList.get_item_metadata(index) authored_properties_to_delete.append(property_blueprint) new_label = Label.new() new_label.text = property_blueprint.get_property_name() @@ -164,8 +164,8 @@ func _on_ConfirmPropertyDeletionWindow_confirmed(): refresh_property_list() emit_signal("refresh_authored_property_lists") -func _on_PropertyList_item_activated(index): - var property_blueprint = $ColorRect/VBC/HBC/VBC1/PropertyList.get_item_metadata(index) +func _on_PropertyList_item_selected(index): + var property_blueprint = $ColorRect/VBC/HBC/VBC/PropertyList.get_item_metadata(index) load_authored_property(property_blueprint) func on_character_properties_changed(property, character): @@ -173,8 +173,20 @@ func on_character_properties_changed(property, character): #GUI Themes: +onready var add_icon_light = preload("res://custom_resources/add_icon.svg") +onready var add_icon_dark = preload("res://custom_resources/add_icon_dark.svg") +onready var delete_icon_light = preload("res://custom_resources/delete_icon.svg") +onready var delete_icon_dark = preload("res://custom_resources/delete_icon_dark.svg") + func set_gui_theme(theme_name, background_color): $ColorRect.color = background_color $ColorRect/VBC/ColorRect.color = background_color $ColorRect/VBC/HBC/BNumberEditPanel.set_gui_theme(theme_name, background_color) $PropertyCreationWindow/VBC/BNumberEditPanel.set_gui_theme(theme_name, background_color) + match theme_name: + "Clarity": + $ColorRect/VBC/HBC/VBC/HBC/AddButton.icon = add_icon_dark + $ColorRect/VBC/HBC/VBC/HBC/DeleteButton.icon = delete_icon_dark + "Lapis Lazuli": + $ColorRect/VBC/HBC/VBC/HBC/AddButton.icon = add_icon_light + $ColorRect/VBC/HBC/VBC/HBC/DeleteButton.icon = delete_icon_light diff --git a/godot/AuthoredPropertyCreationScreen.tscn b/godot/AuthoredPropertyCreationScreen.tscn index 2e16d21..48452dd 100644 --- a/godot/AuthoredPropertyCreationScreen.tscn +++ b/godot/AuthoredPropertyCreationScreen.tscn @@ -1,7 +1,9 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://AuthoredPropertyCreationScreen.gd" type="Script" id=1] [ext_resource path="res://SingleBNumberBlueprintEditPanel.tscn" type="PackedScene" id=2] +[ext_resource path="res://custom_resources/add_icon.svg" type="Texture" id=3] +[ext_resource path="res://custom_resources/delete_icon.svg" type="Texture" id=4] [node name="Control" type="Control"] anchor_right = 1.0 @@ -18,6 +20,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 [node name="ColorRect" type="ColorRect" parent="ColorRect/VBC"] +visible = false margin_right = 1366.0 margin_bottom = 32.0 rect_min_size = Vector2( 0, 32 ) @@ -37,40 +40,52 @@ align = 1 valign = 1 [node name="HBC" type="HBoxContainer" parent="ColorRect/VBC"] -margin_top = 36.0 margin_right = 1366.0 margin_bottom = 736.0 size_flags_vertical = 3 -[node name="VBC1" type="VBoxContainer" parent="ColorRect/VBC/HBC"] -margin_right = 143.0 -margin_bottom = 700.0 +[node name="VBC" type="VBoxContainer" parent="ColorRect/VBC/HBC"] +margin_right = 160.0 +margin_bottom = 736.0 size_flags_vertical = 3 -[node name="AddButton" type="Button" parent="ColorRect/VBC/HBC/VBC1"] -margin_right = 143.0 -margin_bottom = 20.0 -text = "Create New Property" - -[node name="DeleteButton" type="Button" parent="ColorRect/VBC/HBC/VBC1"] -margin_top = 24.0 -margin_right = 143.0 -margin_bottom = 44.0 -text = "Delete Property" - -[node name="PropertyList" type="ItemList" parent="ColorRect/VBC/HBC/VBC1"] -margin_top = 48.0 -margin_right = 143.0 -margin_bottom = 700.0 +[node name="HBC" type="HBoxContainer" parent="ColorRect/VBC/HBC/VBC"] +margin_right = 160.0 +margin_bottom = 30.0 + +[node name="AddButton" type="Button" parent="ColorRect/VBC/HBC/VBC/HBC"] +margin_right = 36.0 +margin_bottom = 30.0 +hint_tooltip = "Add new property." +icon = ExtResource( 3 ) + +[node name="DeleteButton" type="Button" parent="ColorRect/VBC/HBC/VBC/HBC"] +margin_left = 40.0 +margin_right = 76.0 +margin_bottom = 30.0 +hint_tooltip = "Delete selected property." +icon = ExtResource( 4 ) + +[node name="Label" type="Label" parent="ColorRect/VBC/HBC/VBC/HBC"] +margin_left = 80.0 +margin_top = 8.0 +margin_right = 150.0 +margin_bottom = 22.0 +text = "Properties:" + +[node name="PropertyList" type="ItemList" parent="ColorRect/VBC/HBC/VBC"] +margin_top = 34.0 +margin_right = 160.0 +margin_bottom = 736.0 +rect_min_size = Vector2( 160, 0 ) size_flags_vertical = 3 -select_mode = 1 [node name="BNumberEditPanel" parent="ColorRect/VBC/HBC" instance=ExtResource( 2 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_left = 147.0 -margin_right = 147.0 -margin_bottom = 700.0 +margin_left = 164.0 +margin_right = 164.0 +margin_bottom = 736.0 [node name="PropertyCreationWindow" type="ConfirmationDialog" parent="."] margin_right = 300.0 @@ -105,8 +120,9 @@ margin_top = 8.0 margin_right = 192.0 margin_bottom = 34.0 -[connection signal="pressed" from="ColorRect/VBC/HBC/VBC1/AddButton" to="." method="_on_AddButton_pressed"] -[connection signal="pressed" from="ColorRect/VBC/HBC/VBC1/DeleteButton" to="." method="_on_DeleteButton_pressed"] -[connection signal="item_activated" from="ColorRect/VBC/HBC/VBC1/PropertyList" to="." method="_on_PropertyList_item_activated"] +[connection signal="pressed" from="ColorRect/VBC/HBC/VBC/HBC/AddButton" to="." method="_on_AddButton_pressed"] +[connection signal="pressed" from="ColorRect/VBC/HBC/VBC/HBC/DeleteButton" to="." method="_on_DeleteButton_pressed"] +[connection signal="item_selected" from="ColorRect/VBC/HBC/VBC/PropertyList" to="." method="_on_PropertyList_item_selected"] +[connection signal="multi_selected" from="ColorRect/VBC/HBC/VBC/PropertyList" to="." method="_on_PropertyList_multi_selected"] [connection signal="confirmed" from="PropertyCreationWindow" to="." method="_on_PropertyCreationWindow_confirmed"] [connection signal="confirmed" from="ConfirmPropertyDeletionWindow" to="." method="_on_ConfirmPropertyDeletionWindow_confirmed"] diff --git a/godot/BNumberEffect.gd b/godot/BNumberEffect.gd index d4e2281..b62461f 100644 --- a/godot/BNumberEffect.gd +++ b/godot/BNumberEffect.gd @@ -100,7 +100,7 @@ func load_from_json_v0_0_21_through_v0_0_29(storyworld, data_to_load): else: return false -func load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): +func load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load): clear() if (data_to_load.has_all(["Set", "to"])): if (data_to_load["Set"].has_all(["pointer_type", "character", "coefficient", "keyring"]) and "Bounded Number Pointer" == data_to_load["Set"]["pointer_type"] and TYPE_STRING == typeof(data_to_load["Set"]["character"]) and storyworld.character_directory.has(data_to_load["Set"]["character"])): @@ -117,7 +117,7 @@ func load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): output_datatype = sw_script_data_types.BNUMBER elif (assignee.output_type == sw_script_data_types.BOOLEAN): output_datatype = sw_script_data_types.BOOLEAN - script.load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load["to"], output_datatype) + script.load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load["to"], output_datatype) assignment_script = script if (null != assignee and assignee is BNumberPointer and null != assignment_script and assignment_script is ScriptManager): return true diff --git a/godot/CharacterEditScreen.tscn b/godot/CharacterEditScreen.tscn index f73d5c0..e7f7919 100644 --- a/godot/CharacterEditScreen.tscn +++ b/godot/CharacterEditScreen.tscn @@ -27,12 +27,14 @@ margin_bottom = 30.0 [node name="AddCharacter" type="Button" parent="HBC/VBC/Header"] margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Add new character." icon = ExtResource( 3 ) [node name="DeleteCharacter" type="Button" parent="HBC/VBC/Header"] margin_left = 40.0 margin_right = 76.0 margin_bottom = 30.0 +hint_tooltip = "Delete selected characters." icon = ExtResource( 2 ) [node name="Label" type="Label" parent="HBC/VBC/Header"] @@ -47,6 +49,7 @@ margin_top = 34.0 margin_right = 160.0 margin_bottom = 634.0 rect_min_size = Vector2( 160, 600 ) +scroll_horizontal_enabled = false [node name="CharacterList" type="ItemList" parent="HBC/VBC/Scroll"] margin_right = 160.0 @@ -91,8 +94,7 @@ caret_blink_speed = 0.5 margin_top = 109.0 margin_right = 320.0 margin_bottom = 634.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 +rect_min_size = Vector2( 0, 525 ) scroll_horizontal_enabled = false [node name="VBC" type="VBoxContainer" parent="HBC/VBC2/Scroll_Properties"] diff --git a/godot/CharacterTraitEditingInterface.gd b/godot/CharacterTraitEditingInterface.gd index e540992..ae02f21 100644 --- a/godot/CharacterTraitEditingInterface.gd +++ b/godot/CharacterTraitEditingInterface.gd @@ -13,6 +13,15 @@ signal bnumber_property_changed(character, keyring, new_value) func _ready(): pass # Replace with function body. +func set_error_message(text = ""): + $VBC/Label.set_text(text) + if ("" == text): + $VBC/HBC1.set_visible(true) + $VBC/HBC2.set_visible(true) + else: + $VBC/HBC1.set_visible(false) + $VBC/HBC2.set_visible(false) + func refresh_character_name(character): for child in $VBC/HBC1/KeyringHBC.get_children(): for index in range(child.get_item_count()): @@ -20,12 +29,26 @@ func refresh_character_name(character): child.set_item_text(index, character.char_name) func refresh(): - if (0 == keyring.size() or null == character): + if (0 == keyring.size()): + set_error_message("Error: Empty property keyring.") + return false + elif (null == character): + set_error_message("Error: Null character reference.") + return false + elif (null == storyworld): + set_error_message("Error: Null storyworld reference.") return false var value = character.get_bnumber_property(keyring) - $VBC/HBC2/Slidebar.value = value - $VBC/HBC2/SpinBox.value = value - var property_id = keyring[0] + if (null == value): + set_error_message("Error: Could not find property when checking character.") + return false + else: + $VBC/HBC2/Slidebar.set_value(value) + $VBC/HBC2/SpinBox.set_value(value) + var property_id = keyring.front() + if (!storyworld.authored_property_directory.has(property_id)): + set_error_message("Error: Could not find property when checking storyworld.") + return false var property = storyworld.authored_property_directory[property_id] var text = property.get_property_name() text += ": " diff --git a/godot/CharacterTraitEditingInterface.tscn b/godot/CharacterTraitEditingInterface.tscn index e532484..0e5c484 100644 --- a/godot/CharacterTraitEditingInterface.tscn +++ b/godot/CharacterTraitEditingInterface.tscn @@ -5,7 +5,7 @@ [node name="Background" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 -size_flags_horizontal = 3 +rect_min_size = Vector2( 0, 68 ) size_flags_vertical = 3 script = ExtResource( 1 ) @@ -13,18 +13,20 @@ script = ExtResource( 1 ) anchor_right = 1.0 anchor_bottom = 1.0 margin_left = 5.0 +rect_min_size = Vector2( 0, 64 ) size_flags_horizontal = 3 size_flags_vertical = 3 [node name="Label" type="Label" parent="VBC"] margin_right = 1361.0 margin_bottom = 14.0 +rect_min_size = Vector2( 0, 14 ) +size_flags_vertical = 5 [node name="HBC1" type="HBoxContainer" parent="VBC"] margin_top = 18.0 margin_right = 1361.0 margin_bottom = 18.0 -size_flags_horizontal = 3 alignment = 2 [node name="KeyringHBC" type="HBoxContainer" parent="VBC/HBC1"] @@ -38,10 +40,12 @@ size_flags_horizontal = 3 margin_top = 22.0 margin_right = 1361.0 margin_bottom = 46.0 +rect_min_size = Vector2( 0, 24 ) [node name="Slidebar" type="HSlider" parent="VBC/HBC2"] margin_right = 1283.0 margin_bottom = 16.0 +rect_min_size = Vector2( 0, 16 ) size_flags_horizontal = 3 min_value = -0.99 max_value = 0.99 @@ -53,6 +57,7 @@ ticks_on_borders = true margin_left = 1287.0 margin_right = 1361.0 margin_bottom = 24.0 +rect_min_size = Vector2( 0, 24 ) min_value = -0.99 max_value = 0.99 step = 0.01 diff --git a/godot/DocPageDisplay.tscn b/godot/DocPageDisplay.tscn index bcd8224..1cbb405 100644 --- a/godot/DocPageDisplay.tscn +++ b/godot/DocPageDisplay.tscn @@ -15,5 +15,7 @@ size_flags_vertical = 3 scroll_horizontal_enabled = false [node name="VBC" type="VBoxContainer" parent="Scroll"] +margin_right = 1366.0 +margin_bottom = 736.0 size_flags_horizontal = 3 size_flags_vertical = 3 diff --git a/godot/EncounterEditScreen.tscn b/godot/EncounterEditScreen.tscn index a6fb08f..ecc95ce 100644 --- a/godot/EncounterEditScreen.tscn +++ b/godot/EncounterEditScreen.tscn @@ -38,12 +38,14 @@ margin_bottom = 20.0 [node name="AddButton" type="Button" parent="Column1/HBC"] margin_right = 20.0 margin_bottom = 20.0 +hint_tooltip = "Add new encounter." icon = ExtResource( 11 ) [node name="DeleteButton" type="Button" parent="Column1/HBC"] margin_left = 24.0 margin_right = 41.0 margin_bottom = 20.0 +hint_tooltip = "Delete selected encounters." icon = ExtResource( 10 ) [node name="Label" type="Label" parent="Column1/HBC"] @@ -159,24 +161,28 @@ size_flags_horizontal = 3 [node name="AddOption" type="Button" parent="HSC/Column2/HBCOptionButtons"] margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Add new option." icon = ExtResource( 11 ) [node name="DeleteOption" type="Button" parent="HSC/Column2/HBCOptionButtons"] margin_left = 40.0 margin_right = 76.0 margin_bottom = 30.0 +hint_tooltip = "Delete selected options." icon = ExtResource( 10 ) [node name="MoveOptionUpButton" type="Button" parent="HSC/Column2/HBCOptionButtons"] margin_left = 80.0 margin_right = 116.0 margin_bottom = 30.0 +hint_tooltip = "Move option up." icon = ExtResource( 2 ) [node name="MoveOptionDownButton" type="Button" parent="HSC/Column2/HBCOptionButtons"] margin_left = 120.0 margin_right = 156.0 margin_bottom = 30.0 +hint_tooltip = "Move option down." icon = ExtResource( 3 ) [node name="Label" type="Label" parent="HSC/Column2/HBCOptionButtons"] @@ -253,12 +259,14 @@ margin_bottom = 30.0 [node name="AddReaction" type="Button" parent="HSC/Column3/HBC"] margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Add new reaction." icon = ExtResource( 11 ) [node name="DeleteReaction" type="Button" parent="HSC/Column3/HBC"] margin_left = 40.0 margin_right = 76.0 margin_bottom = 30.0 +hint_tooltip = "Delete selected reactions." icon = ExtResource( 10 ) [node name="MoveReactionUpButton" type="Button" parent="HSC/Column3/HBC"] @@ -266,13 +274,14 @@ margin_left = 80.0 margin_right = 116.0 margin_bottom = 30.0 rect_min_size = Vector2( 25, 25 ) +hint_tooltip = "Move reaction up." icon = ExtResource( 2 ) [node name="MoveReactionDownButton" type="Button" parent="HSC/Column3/HBC"] margin_left = 120.0 margin_right = 156.0 margin_bottom = 30.0 -custom_colors/font_color = Color( 0.803922, 0.054902, 0.054902, 1 ) +hint_tooltip = "Move reaction down." icon = ExtResource( 3 ) [node name="ReactionsHeadLabel" type="Label" parent="HSC/Column3/HBC"] @@ -390,23 +399,27 @@ __meta__ = { [node name="AddEffect" type="Button" parent="HSC/Column3/HBCEffectButtons"] margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Add new effect." icon = ExtResource( 11 ) [node name="DeleteEffect" type="Button" parent="HSC/Column3/HBCEffectButtons"] margin_left = 40.0 margin_right = 76.0 margin_bottom = 30.0 +hint_tooltip = "Delete selected effects." icon = ExtResource( 10 ) [node name="MoveEffectUpButton" type="Button" parent="HSC/Column3/HBCEffectButtons"] margin_left = 80.0 margin_right = 92.0 margin_bottom = 30.0 +hint_tooltip = "Move effect up." [node name="MoveEffectDownButton" type="Button" parent="HSC/Column3/HBCEffectButtons"] margin_left = 96.0 margin_right = 108.0 margin_bottom = 30.0 +hint_tooltip = "Move effect down." [node name="ReactionEffectsLabel" type="Label" parent="HSC/Column3/HBCEffectButtons"] margin_left = 112.0 diff --git a/godot/GUI.gd b/godot/GUI.gd index 11c3945..f1cad96 100644 --- a/godot/GUI.gd +++ b/godot/GUI.gd @@ -4,7 +4,7 @@ var current_project_path = "" var current_html_template_path = "res://custom_resources/encounter_engine.html" var open_after_compiling = false -var sweepweave_version_number = "0.0.38" +var sweepweave_version_number = "0.1.0" var storyworld = null var clipboard = Clipboard.new() @@ -122,9 +122,6 @@ func _ready(): $Background/VBC/MenuBar/ViewMenu.get_popup().connect("id_pressed", self, "_on_viewmenu_item_pressed") $Background/VBC/MenuBar/ViewMenu.connect("menu_input", self, "_on_viewmenu_item_toggled") $Background/VBC/MenuBar/HelpMenu.get_popup().connect("id_pressed", self, "_on_helpmenu_item_pressed") - $About/VBC/VersionMessage.text = "SweepWeave v." + sweepweave_version_number - $CheckForUpdates/UpdateScreen/VBC/VersionMessage.text = "Current SweepWeave version: " + sweepweave_version_number - $CheckForUpdates/UpdateScreen.sweepweave_version_number = sweepweave_version_number $Background/VBC/EditorTabs/Play.connect("encounter_edit_button_pressed", self, "display_encounter_by_id") $Background/VBC/EditorTabs/Characters.connect("new_character_created", $Background/VBC/EditorTabs/Encounters, "add_character_to_lists") $Background/VBC/EditorTabs/Characters.connect("character_deleted", $Background/VBC/EditorTabs/Encounters, "replace_character") @@ -144,6 +141,11 @@ func _ready(): $Background/VBC/EditorTabs/GraphView.connect("load_encounter_from_graphview", self, "display_encounter") $Background/VBC/EditorTabs/PersonalityModel.connect("refresh_authored_property_lists", $Background/VBC/EditorTabs/Characters, "refresh_property_list") $Background/VBC/EditorTabs/PersonalityModel.connect("refresh_authored_property_lists", $Background/VBC/EditorTabs/Encounters, "refresh_bnumber_property_lists") + $About/VBC/VersionMessage.text = "SweepWeave v." + sweepweave_version_number + $CheckForUpdates/UpdateScreen/VBC/VersionMessage.text = "Current SweepWeave version: " + sweepweave_version_number + $CheckForUpdates/UpdateScreen.sweepweave_version_number = sweepweave_version_number + $Background/VBC/EditorTabs.set_tab_title(4, "Personality Model") + $Background/VBC/EditorTabs.set_tab_title(7, "Graph View") $Background/VBC/EditorTabs.set_current_tab(1) #Initialize clipboard: $Background/VBC/EditorTabs/Encounters.set_clipboard(clipboard) diff --git a/godot/GUI.tscn b/godot/GUI.tscn index e51c167..0eed9d7 100644 --- a/godot/GUI.tscn +++ b/godot/GUI.tscn @@ -240,13 +240,11 @@ size_flags_horizontal = 3 size_flags_vertical = 3 size_flags_stretch_ratio = 1.5 text = "Thanks to my patrons for their encouragement and support: -Jóhannes Ævarsson Chris Conley +Jóhannes Ævarsson +Felipe Vega Pixel Brownie Software Craig Maloney -Felipe Vega -Patrick Dugan -Pamela Beck If you would like to help support me as well, you can find me at my patreon page via the link below." diff --git a/godot/PlayScreen.tscn b/godot/PlayScreen.tscn index 02716bd..e1d2011 100644 --- a/godot/PlayScreen.tscn +++ b/godot/PlayScreen.tscn @@ -90,6 +90,7 @@ text = "Start" visible = false margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Edit encounter." icon = ExtResource( 3 ) [node name="EncounterTitle" type="Label" parent="Layout/L2/ColorRect/VBC/TitleBar"] diff --git a/godot/custom_resources/SearchandReplace.gd b/godot/SearchandReplace.gd similarity index 100% rename from godot/custom_resources/SearchandReplace.gd rename to godot/SearchandReplace.gd diff --git a/godot/custom_resources/SearchandReplace.tscn b/godot/SearchandReplace.tscn similarity index 89% rename from godot/custom_resources/SearchandReplace.tscn rename to godot/SearchandReplace.tscn index ad7432b..30e7fb4 100644 --- a/godot/custom_resources/SearchandReplace.tscn +++ b/godot/SearchandReplace.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://custom_resources/SearchandReplace.gd" type="Script" id=1] +[ext_resource path="res://SearchandReplace.gd" type="Script" id=1] [node name="Control" type="Control"] anchor_right = 1.0 diff --git a/godot/SettingsEditScreen.gd b/godot/SettingsEditScreen.gd index 7e31ef6..8656ff0 100644 --- a/godot/SettingsEditScreen.gd +++ b/godot/SettingsEditScreen.gd @@ -1,12 +1,12 @@ extends Control var storyworld = null -var current_project_path = "" +#var current_project_path = "" func refresh(): $VBC/TitleEdit.text = storyworld.storyworld_title $VBC/AuthorEdit.text = storyworld.storyworld_author - $VBC/SavePathDisplay.set_text("Current project save path: " + current_project_path) + $VBC/SavePathDisplay.set_text("Current project save path: " + get_node("../../../../").current_project_path) $VBC/HBC1/IFIDDisplay.set_text("Storyworld IFID: " + storyworld.ifid) $VBC/HBC2/DBMSwitch.pressed = storyworld.storyworld_debug_mode_on match storyworld.storyworld_display_mode: diff --git a/godot/SpoolEditScreen.tscn b/godot/SpoolEditScreen.tscn index 74f71c4..0979aa9 100644 --- a/godot/SpoolEditScreen.tscn +++ b/godot/SpoolEditScreen.tscn @@ -32,12 +32,14 @@ margin_bottom = 30.0 [node name="AddButton" type="Button" parent="Background/HBC/Column1/HBC"] margin_right = 36.0 margin_bottom = 30.0 +hint_tooltip = "Add new spool." icon = ExtResource( 5 ) [node name="DeleteButton" type="Button" parent="Background/HBC/Column1/HBC"] margin_left = 40.0 margin_right = 76.0 margin_bottom = 30.0 +hint_tooltip = "Delete selected spool." icon = ExtResource( 4 ) [node name="SpoolsLabel" type="Label" parent="Background/HBC/Column1/HBC"] diff --git a/godot/SpoolEffect.gd b/godot/SpoolEffect.gd index 394e9b1..ac0ba55 100644 --- a/godot/SpoolEffect.gd +++ b/godot/SpoolEffect.gd @@ -79,7 +79,7 @@ func compile(parent_storyworld, include_editor_only_variables = false): output["to"] = assignment_script.compile(parent_storyworld, include_editor_only_variables) return output -func load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): +func load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load): clear() if (data_to_load.has_all(["Set", "to"])): if (TYPE_STRING == typeof(data_to_load["Set"]) and storyworld.spool_directory.has(data_to_load["Set"])): @@ -93,7 +93,7 @@ func load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): output_datatype = sw_script_data_types.BNUMBER elif (assignee.output_type == sw_script_data_types.BOOLEAN): output_datatype = sw_script_data_types.BOOLEAN - script.load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load["to"], output_datatype) + script.load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load["to"], output_datatype) assignment_script = script if (null != assignee and assignee is SpoolPointer and null != assignment_script and assignment_script is ScriptManager): return true diff --git a/godot/Storyworld.gd b/godot/Storyworld.gd index aee3d9f..6043e73 100644 --- a/godot/Storyworld.gd +++ b/godot/Storyworld.gd @@ -79,9 +79,12 @@ func clear(): #Personality / relationship model: -func add_authored_property(property): +func index_authored_property(property): authored_properties.append(property) authored_property_directory[property.id] = property + +func add_authored_property(property): + index_authored_property(property) if (property.attribution_target == property.possible_attribution_targets.CAST_MEMBERS): for character in property.affected_characters: character.add_property_to_bnumber_properties(property, characters) @@ -115,11 +118,12 @@ func init_classical_personality_model(): func add_all_authored_properties_from(original): for property in original.authored_properties: + print(property.get_property_name()) var new_index = unique_id_seeds["authored_property"] unique_id_seeds["authored_property"] += 1 var copy = BNumberBlueprint.new(self, new_index, "", "", 0, 0) copy.set_as_copy_of(property, false) #create_mutual_links == false - add_authored_property(copy) + index_authored_property(copy) #Characters: @@ -779,7 +783,7 @@ func parse_reactions_data_v0_0_34_through_v0_0_37(reactions_data, option): reaction_directory[reaction_data["id"]] = reaction return result -func load_from_json_v0_0_34_through_v0_0_38(data_to_load): +func load_from_json_v0_0_34_through_v0_1_0(data_to_load): #Load characters. for entry in data_to_load.characters: if (entry.has_all(["name", "pronoun", "bnumber_properties", "id", "creation_index", "creation_time", "modified_time"])): @@ -836,41 +840,41 @@ func load_from_json_v0_0_34_through_v0_0_38(data_to_load): #Parse scripts: for encounter in encounters: var new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, encounter.text_script, sw_script_data_types.STRING) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, encounter.text_script, sw_script_data_types.STRING) encounter.text_script = new_script new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, encounter.acceptability_script, sw_script_data_types.BOOLEAN) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, encounter.acceptability_script, sw_script_data_types.BOOLEAN) encounter.acceptability_script = new_script new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, encounter.desirability_script, sw_script_data_types.BNUMBER) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, encounter.desirability_script, sw_script_data_types.BNUMBER) encounter.desirability_script = new_script for option in encounter.options: new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, option.text_script, sw_script_data_types.STRING) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, option.text_script, sw_script_data_types.STRING) option.text_script = new_script new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, option.visibility_script, sw_script_data_types.BOOLEAN) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, option.visibility_script, sw_script_data_types.BOOLEAN) option.visibility_script = new_script new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, option.performability_script, sw_script_data_types.BOOLEAN) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, option.performability_script, sw_script_data_types.BOOLEAN) option.performability_script = new_script for reaction in option.reactions: new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, reaction.text_script, sw_script_data_types.STRING) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, reaction.text_script, sw_script_data_types.STRING) reaction.text_script = new_script new_script = ScriptManager.new(null) - new_script.load_from_json_v0_0_34_through_v0_0_38(self, reaction.desirability_script, sw_script_data_types.BNUMBER) + new_script.load_from_json_v0_0_34_through_v0_1_0(self, reaction.desirability_script, sw_script_data_types.BNUMBER) reaction.desirability_script = new_script var parsed_effects = [] for effect_data in reaction.after_effects: if ("Bounded Number Effect" == effect_data["effect_type"] and effect_data["Set"].has_all(["pointer_type", "character", "coefficient", "keyring"]) and "Bounded Number Pointer" == effect_data["Set"]["pointer_type"] and TYPE_STRING == typeof(effect_data["Set"]["character"]) and effect_data["to"].has("script_element_type")): var new_effect = BNumberEffect.new() - var effect_is_valid = new_effect.load_from_json_v0_0_34_through_v0_0_38(self, effect_data) + var effect_is_valid = new_effect.load_from_json_v0_0_34_through_v0_1_0(self, effect_data) if (effect_is_valid): parsed_effects.append(new_effect) elif ("Spool Effect" == effect_data["effect_type"] and TYPE_STRING == typeof(effect_data["Set"])): var new_effect = SpoolEffect.new() - var effect_is_valid = new_effect.load_from_json_v0_0_34_through_v0_0_38(self, effect_data) + var effect_is_valid = new_effect.load_from_json_v0_0_34_through_v0_1_0(self, effect_data) if (effect_is_valid): parsed_effects.append(new_effect) reaction.after_effects.clear() @@ -949,7 +953,11 @@ func load_from_json(file_text): return "Passed." elif (0 == int(version[0]) and 0 == int(version[1]) and 34 <= int(version[2]) and 38 >= int(version[2])): clear() - load_from_json_v0_0_34_through_v0_0_38(data_to_load) + load_from_json_v0_0_34_through_v0_1_0(data_to_load) + return "Passed." + elif (0 == int(version[0]) and 1 == int(version[1])): + clear() + load_from_json_v0_0_34_through_v0_1_0(data_to_load) return "Passed." else: print ("Cannot load project file. The project appears to have been made using an unrecognized version of SweepWeave.") diff --git a/godot/UpdateScreen.gd b/godot/UpdateScreen.gd index d774afe..5ca21cc 100644 --- a/godot/UpdateScreen.gd +++ b/godot/UpdateScreen.gd @@ -38,4 +38,4 @@ func _on_HTTPRequest_request_completed(result, response_code, headers, body): $VBC/WebText.append_bbcode("Error: Could not determine latest stable version number.") func _on_DownloadButton_pressed(): - OS.shell_open("https://www.patreon.com/sasha_fenn") + OS.shell_open("https://github.com/FrobozzWaxwing/Sweep_Weave/releases") diff --git a/godot/custom_resources/lapis_lazuli.tres b/godot/custom_resources/lapis_lazuli.tres index 441e447..0731c4d 100644 --- a/godot/custom_resources/lapis_lazuli.tres +++ b/godot/custom_resources/lapis_lazuli.tres @@ -1,4 +1,4 @@ -[gd_resource type="Theme" load_steps=31 format=2] +[gd_resource type="Theme" load_steps=33 format=2] [ext_resource path="res://custom_resources/NotoMono-Regular.tres" type="DynamicFont" id=1] [ext_resource path="res://custom_resources/NotoSerif-Bold.tres" type="DynamicFont" id=2] @@ -8,6 +8,8 @@ [ext_resource path="res://custom_resources/grabber_orange.svg" type="Texture" id=6] [ext_resource path="res://custom_resources/grabber_green.svg" type="Texture" id=7] [ext_resource path="res://custom_resources/grabber_white.svg" type="Texture" id=8] +[ext_resource path="res://custom_resources/x_green.svg" type="Texture" id=9] +[ext_resource path="res://custom_resources/x.svg" type="Texture" id=10] [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.0392157, 0.117647, 0.196078, 1 ) @@ -339,4 +341,6 @@ Tree/styles/bg = SubResource( 5 ) Tree/styles/title_button_normal = SubResource( 17 ) VSeparator/styles/separator = SubResource( 19 ) WindowDialog/colors/title_color = Color( 1, 1, 1, 1 ) +WindowDialog/icons/close = ExtResource( 10 ) +WindowDialog/icons/close_highlight = ExtResource( 9 ) WindowDialog/styles/panel = SubResource( 22 ) diff --git a/godot/custom_resources/writing_with_sweepweave.json b/godot/custom_resources/writing_with_sweepweave.json index ff49a1d..81621be 100644 --- a/godot/custom_resources/writing_with_sweepweave.json +++ b/godot/custom_resources/writing_with_sweepweave.json @@ -539,7 +539,7 @@ { "id": "7293E085", "title": "1", - "text": "SweepWeave is based on design work by Chris Crawford and Sasha Fenn, and has been coded and implemented by Sasha Fenn.\n\nThe suite consists of a storyworld interpreter, written in html and javascript, and a storyworld editor, written in [url=https://godotengine.org/]the Godot game engine[/url]. Storyworlds are written and scripted in the editor, projects can be saved as .json files, and storyworlds can be exported as standalone html pages, which combine the interpreter with a block of data unique to the storyworld, and which can be played in a web browser.\n\nSweepWeave is available as open source software under an MIT License. [url=https://github.com/FrobozzWaxwing/Sweep_Weave]The sourcecode can be obtained through github.[/url] All storyworlds created with SweepWeave belong to their respective authors. You are free to publish your storyworlds as you please, including for commercial purposes.\n\nSweepWeave incorporates a bit of code by Xavier Sellier for use when generating universally unique identifiers, or UUIDs. In particular, SweepWeave uses UUIDs to create IFIDs for storyworlds, as IFIDs are intended to be unique even when completely different development systems are used to create works of interactive fiction. Credit and thanks go to Xavier Sellier for writing and releasing their code under an MIT License.\n\nChris Crawford can be found online at [url=https://erasmatazz.com/]https://erasmatazz.com/[/url]\nSasha Fenn can be found online at [url=https://www.patreon.com/sasha_fenn]https://www.patreon.com/sasha_fenn[/url]\n\nIf you would like to help support me financially, you can do so through my Patreon page, reached via the second link above.\nThanks to my patrons for their encouragement and support:\nJóhannes Ævarsson\nChris Conley\nPixel Brownie Software\nCraig Maloney\nFelipe Vega\nPatrick Dugan\nPamela Beck\n\nYou can contact me through Chris Crawford's interactive storytelling workgroup on Discord, via github, through my Patreon page, or via email. On github I am FrobozzWaxwing. My email address is sasha@emptiestvoid.com.\n\nThanks, and peace to you.\n~ Sasha Fenn", + "text": "SweepWeave is based on design work by Chris Crawford and Sasha Fenn, and has been coded and implemented by Sasha Fenn.\n\nThe suite consists of a storyworld interpreter, written in html and javascript, and a storyworld editor, written in [url=https://godotengine.org/]the Godot game engine[/url]. Storyworlds are written and scripted in the editor, projects can be saved as .json files, and storyworlds can be exported as standalone html pages, which combine the interpreter with a block of data unique to the storyworld, and which can be played in a web browser.\n\nSweepWeave is available as open source software under an MIT License. [url=https://github.com/FrobozzWaxwing/Sweep_Weave]The sourcecode can be obtained through github.[/url] All storyworlds created with SweepWeave belong to their respective authors. You are free to publish your storyworlds as you please, including for commercial purposes.\n\nSweepWeave incorporates a bit of code by Xavier Sellier for use when generating universally unique identifiers, or UUIDs. In particular, SweepWeave uses UUIDs to create IFIDs for storyworlds, as IFIDs are intended to be unique even when completely different development systems are used to create works of interactive fiction. Credit and thanks go to Xavier Sellier for writing and releasing their code under an MIT License.\n\nChris Crawford can be found online at [url=https://erasmatazz.com/]https://erasmatazz.com/[/url]\nSasha Fenn can be found online at [url=https://www.patreon.com/sasha_fenn]https://www.patreon.com/sasha_fenn[/url]\n\nIf you would like to help support me financially, you can do so through my Patreon page, reached via the second link above.\nThanks to my patrons for their encouragement and support:\nChris Conley\nJóhannes Ævarsson\nFelipe Vega\nPixel Brownie Software\nCraig Maloney\n\nYou can contact me through Chris Crawford's interactive storytelling workgroup on Discord, via github, through my Patreon page, or via email. On github I am FrobozzWaxwing. My email address is sasha@emptiestvoid.com.\n\nThanks, and peace to you.\n~ Sasha Fenn", "illustration": null } ] @@ -549,5 +549,5 @@ ], "doc_format_version": "0.0.3.0", "creation_time": 1676451694, - "modified_time": 1678501870 + "modified_time": 1680932091 } \ No newline at end of file diff --git a/godot/custom_resources/x.svg b/godot/custom_resources/x.svg new file mode 100644 index 0000000..cc22299 --- /dev/null +++ b/godot/custom_resources/x.svg @@ -0,0 +1,40 @@ + + + + + + diff --git a/godot/custom_resources/x_green.svg b/godot/custom_resources/x_green.svg new file mode 100644 index 0000000..72238bf --- /dev/null +++ b/godot/custom_resources/x_green.svg @@ -0,0 +1,40 @@ + + + + + + diff --git a/godot/export_presets.cfg b/godot/export_presets.cfg index e7c67ef..6b30b37 100644 --- a/godot/export_presets.cfg +++ b/godot/export_presets.cfg @@ -81,7 +81,7 @@ custom_features="" export_filter="all_resources" include_filter="*.html, *.json" exclude_filter="" -export_path="../Internal_TestBed/SweepWeave_Win_0_0_38.exe" +export_path="../Internal_TestBed/SweepWeave_Win_0_1_0.exe" script_export_mode=1 script_encryption_key="" @@ -107,10 +107,35 @@ codesign/description="" codesign/custom_options=PoolStringArray( ) application/modify_resources=true application/icon="res://custom_resources/ball_of_yarn.ico" -application/file_version="0.0.38.0" -application/product_version="0.0.38.0" +application/file_version="0.1.0.0" +application/product_version="0.1.0.0" application/company_name="Neon Hopscotch" application/product_name="SweepWeave" -application/file_description="An application for creating storylet-based interactive storyworlds. Made with Godot Engine by Sasha Fenn." +application/file_description="An open source tool for creating interactive storyworlds. Made with Godot Engine by Sasha Fenn." application/copyright="MIT License, Sasha Fenn, 2020 - 2023" application/trademarks="" + +[preset.2] + +name="Linux/X11" +platform="Linux/X11" +runnable=true +custom_features="" +export_filter="all_resources" +include_filter="*.html, *.json" +exclude_filter="" +export_path="../Internal_TestBed/SweepWeave_Linux_0_1_0.x86_64" +script_export_mode=1 +script_encryption_key="" + +[preset.2.options] + +custom_template/debug="" +custom_template/release="" +binary_format/64_bits=true +binary_format/embed_pck=false +texture_format/bptc=false +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false +texture_format/no_bptc_fallbacks=true diff --git a/godot/sw_scripting/ScriptManager.gd b/godot/sw_scripting/ScriptManager.gd index ff991fd..3e83595 100644 --- a/godot/sw_scripting/ScriptManager.gd +++ b/godot/sw_scripting/ScriptManager.gd @@ -685,7 +685,7 @@ func load_from_json_v0_0_21_through_v0_0_29(storyworld, data_to_load, expected_o else: set_contents(parsed_script) -func recursive_load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): +func recursive_load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load): var element = null if (TYPE_BOOL == typeof(data_to_load)): #Data should be either a boolean value, (true or false,) or a dictionary. @@ -723,7 +723,7 @@ func recursive_load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): #Parse operands: var operands = [] for operand in data_to_load["operands"]: - var parsed_operand = recursive_load_from_json_v0_0_34_through_v0_0_38(storyworld, operand) + var parsed_operand = recursive_load_from_json_v0_0_34_through_v0_1_0(storyworld, operand) if (null != parsed_operand and parsed_operand is SWScriptElement): operands.append(parsed_operand) #Create operator: @@ -769,8 +769,8 @@ func recursive_load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load): element = NudgeOperator.new(operands.pop_front(), operands.pop_front()) return proofread(element) -func load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load, expected_output_datatype): - var parsed_script = recursive_load_from_json_v0_0_34_through_v0_0_38(storyworld, data_to_load) +func load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load, expected_output_datatype): + var parsed_script = recursive_load_from_json_v0_0_34_through_v0_1_0(storyworld, data_to_load) if (null == parsed_script): if (sw_script_data_types.BNUMBER == expected_output_datatype): # print ("Warning, script has null or invalid contents. Setting script contents to bounded number constant to match expected output datatype.")