Skip to content

Commit

Permalink
Merge pull request #2172 from ivan-mogilko/361--noautorestorepoint
Browse files Browse the repository at this point in the history
3.6.1: disable hardcoded SetRestartPoint
  • Loading branch information
ivan-mogilko authored Oct 15, 2023
2 parents 7a55820 + d9c12f0 commit 9adc7ea
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 44 deletions.
5 changes: 4 additions & 1 deletion Common/ac/game_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ Idle animation speed, modifiable hotspot names, fixed video frame
Some adjustments to gui text alignment.
3.6.1:
In RTL mode all text is reversed, not only wrappable (labels etc).
3.6.1.10:
Disabled automatic SetRestartPoint.
*/

Expand Down Expand Up @@ -153,7 +155,8 @@ enum GameDataVersion
kGameVersion_360_16 = 3060016,
kGameVersion_360_21 = 3060021,
kGameVersion_361 = 3060100,
kGameVersion_Current = kGameVersion_361
kGameVersion_361_10 = 3060110,
kGameVersion_Current = kGameVersion_361_10
};

// Data format version of the loaded game
Expand Down
17 changes: 11 additions & 6 deletions Editor/AGS.Editor/AGSEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ public class AGSEditor
* 3.6.1.2 - GUIListBox.Translated property moved to GUIControl parent
* 3.6.1.3 - RuntimeSetup.TextureCache, SoundCache
* 3.6.1.9 - Settings.ScaleCharacterSpriteOffsets
* 3.6.1.10 - SetRestartPoint() is no longer auto called in the engine,
* add one into the global script when importing older games.
*/
public const int LATEST_XML_VERSION_INDEX = 3060109;
public const int LATEST_XML_VERSION_INDEX = 3060110;
/*
* LATEST_USER_DATA_VERSION is the last version of the user data file that used a
* 4-point-4-number string to identify the version of AGS that saved the file.
Expand Down Expand Up @@ -873,13 +875,16 @@ private Script CompileDialogs(CompileMessages errors, bool rebuildAll)
DialogScriptConverter dialogConverter = new DialogScriptConverter();
string dialogScriptsText = dialogConverter.ConvertGameDialogScripts(_game, errors, rebuildAll);
Script dialogScripts = new Script(Script.DIALOG_SCRIPTS_FILE_NAME, dialogScriptsText, false);
Script globalScript = _game.RootScriptFolder.GetScriptByFileName(Script.GLOBAL_SCRIPT_FILE_NAME, true);
if (!System.Text.RegularExpressions.Regex.IsMatch(globalScript.Text, @"function\s+dialog_request\s*\("))

// A dialog_request must exist in the global script, otherwise
// the dialogs script fails to load at run-time
// TODO: check if it's still true, and is necessary!
Script script = CurrentGame.RootScriptFolder.GetScriptByFileName(Script.GLOBAL_SCRIPT_FILE_NAME, true);
if (script != null)
{
// A dialog_request must exist in the global script, otherwise
// the dialogs script fails to load at run-time
globalScript.Text += Environment.NewLine + "function dialog_request(int param) {" + Environment.NewLine + "}";
script.Text = ScriptGeneration.InsertFunction(script.Text, "dialog_request", "int param");
}

return dialogScripts;
}

Expand Down
1 change: 1 addition & 0 deletions Editor/AGS.Editor/AGSEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@
<Compile Include="Utils\ArgumentBuilder.cs" />
<Compile Include="Utils\ConcurrentCircularBuffer.cs" />
<Compile Include="Utils\MathExtra.cs" />
<Compile Include="Utils\ScriptGeneration.cs" />
<Compile Include="Utils\Validation.cs" />
<EmbeddedResource Include="GUI\frmMain.resx">
<SubType>Designer</SubType>
Expand Down
33 changes: 9 additions & 24 deletions Editor/AGS.Editor/Components/RoomsComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -859,32 +859,17 @@ private bool AddPlayMusicCommandToPlayerEntersRoomScript(Room room, CompileMessa
return scriptModified;
}

string scriptName = room.Interactions.GetScriptFunctionNameForInteractionSuffix(Room.EVENT_SUFFIX_ROOM_LOAD);
if (string.IsNullOrEmpty(scriptName))
string functionName = room.Interactions.GetScriptFunctionNameForInteractionSuffix(Room.EVENT_SUFFIX_ROOM_LOAD);
if (string.IsNullOrEmpty(functionName))
{
scriptName = "Room_" + Room.EVENT_SUFFIX_ROOM_LOAD;
room.Interactions.SetScriptFunctionNameForInteractionSuffix(Room.EVENT_SUFFIX_ROOM_LOAD, scriptName);
room.Script.Text += Environment.NewLine + "function " + scriptName + "()" +
Environment.NewLine + "{" + Environment.NewLine +
"}" + Environment.NewLine;
scriptModified = true;
}
int functionOffset = room.Script.Text.IndexOf(scriptName);
if (functionOffset < 0)
{
errors.Add(new CompileWarning("Room " + room.Number + ": Unable to find definition for " + scriptName + " to add Room Load music " + room.PlayMusicOnRoomLoad));
}
else
{
functionOffset = room.Script.Text.IndexOf('{', functionOffset);
functionOffset = room.Script.Text.IndexOf('\n', functionOffset) + 1;
string newScript = room.Script.Text.Substring(0, functionOffset);
newScript += " " + clip.ScriptName + ".Play();" + Environment.NewLine;
newScript += room.Script.Text.Substring(functionOffset);
room.Script.Text = newScript;
room.PlayMusicOnRoomLoad = 0;
scriptModified = true;
functionName = "Room_" + Room.EVENT_SUFFIX_ROOM_LOAD;
room.Interactions.SetScriptFunctionNameForInteractionSuffix(Room.EVENT_SUFFIX_ROOM_LOAD, functionName);
}

room.Script.Text = ScriptGeneration.InsertFunction(room.Script.Text, functionName, "",
" " + clip.ScriptName + ".Play();", amendExisting: true, insertBeforeExistingCode: true);
room.PlayMusicOnRoomLoad = 0;
scriptModified = true;
}

return scriptModified;
Expand Down
23 changes: 23 additions & 0 deletions Editor/AGS.Editor/Components/ScriptsComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public ScriptsComponent(GUIController guiController, AGSEditor agsEditor)
_guiController.OnScriptChanged += new GUIController.ScriptChangedHandler(GUIController_OnScriptChanged);
_guiController.OnGetScriptEditorControl += new GUIController.GetScriptEditorControlHandler(_guiController_OnGetScriptEditorControl);
_guiController.ProjectTree.OnAfterLabelEdit += new ProjectTree.AfterLabelEditHandler(ProjectTree_OnAfterLabelEdit);

Factory.Events.GamePostLoad += Events_GamePostLoad;
}

private void _guiController_OnGetScriptEditorControl(GetScriptEditorControlEventArgs evArgs)
Expand Down Expand Up @@ -630,5 +632,26 @@ protected override IList<ScriptAndHeader> GetFlatList()
{
return null;
}

private void Events_GamePostLoad()
{
var game = _agsEditor.CurrentGame;
if (game.SavedXmlVersionIndex >= 3060110)
return; // no upgrade necessary

// < 3060110 - SetRestartPoint() has to be added to Global Script's game_start,
// emulate legacy behavior where its call was hardcoded in the engine.
if (game.SavedXmlVersionIndex < 3060110)
{
Script script = AGSEditor.Instance.CurrentGame.RootScriptFolder.GetScriptByFileName(Script.GLOBAL_SCRIPT_FILE_NAME, true);
if (script != null)
{
script.Text =
ScriptGeneration.InsertFunction(script.Text, "game_start", "", " SetRestartPoint();", amendExisting: true);
// CHECKME: do not save the script here, in case user made a mistake opening this in a newer editor
// and closes project without saving after upgrade? Upgrade process is not well defined...
}
}
}
}
}
15 changes: 4 additions & 11 deletions Editor/AGS.Editor/GUI/GUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,18 +1296,11 @@ private void ScriptFunctionUIEditor_CreateScriptFunction(bool isGlobalScript, st
OnGetScript(scriptToRetrieve, ref script);
if (script != null)
{
string functionStart = "function " + functionName + "(";
if (script.Text.IndexOf(functionStart) < 0)
if (_agsEditor.AttemptToGetWriteAccess(script.FileName))
{
if (_agsEditor.AttemptToGetWriteAccess(script.FileName))
{
script.Text += Environment.NewLine + functionStart + parameters + ")" + Environment.NewLine;
script.Text += "{" + Environment.NewLine + Environment.NewLine + "}" + Environment.NewLine;
if (OnScriptChanged != null)
{
OnScriptChanged(script);
}
}
script.Text = ScriptGeneration.InsertFunction(script.Text, functionName, parameters);
if (script.Modified)
OnScriptChanged?.Invoke(script);
}
}
}
Expand Down
98 changes: 98 additions & 0 deletions Editor/AGS.Editor/Utils/ScriptGeneration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace AGS.Editor
{
/// <summary>
/// Helper class ScriptGeneration provides methods for automatic script editing.
/// </summary>
public class ScriptGeneration
{
/// <summary>
/// Counts braces starting with the startIndex, and finds the matching closing one.
/// Returns an index of a closing brace.
/// </summary>
public static int FindClosingBrace(string text, int startIndex, char braceOpenChar = '{', char braceCloseChar = '}')
{
// TODO: is it possible to do this using regex?
int count = 0;
int closeBraceAt = -1;
for (int i = startIndex; i < text.Length; ++i)
{
if (text[i] == braceOpenChar)
{
count++;
}
else if (text[i] == braceCloseChar)
{
count--;
if (count == 0)
{
closeBraceAt = i;
break;
}
}
}
return closeBraceAt;
}

/// <summary>
/// Appends a function with optional parameter list and optional contents to a
/// script's text.
/// </summary>
/// <param name="amendExisting">Tells whether to amend the function code in existing
/// function, or only set it if the new function is created.</param>
/// <returns>Resulting script's text.</returns>
public static string InsertFunction(string text, string functionName, string paramList = "", string functionCode = "",
bool amendExisting = false, bool insertBeforeExistingCode = false)
{
// TODO: support matching indentation for the new code?

// NOTE: we must find a function with opening brace, because there may also
// be a function prototype somewhere.
var match = Regex.Match(text, string.Format(@"function\s+{0}\s*\(.*\)\s*{{", functionName));
if (match.Success && (!amendExisting || string.IsNullOrWhiteSpace(functionCode)))
return text; // function already exists and don't have to amend
if (match.Success)
{
// Find the required position in the existing function, and insert required code
int functionStart = match.Index + match.Length;
if (insertBeforeExistingCode)
{
text = string.Format("{0}{1}{2}{3}{4}",
text.Substring(0, functionStart),
Environment.NewLine, functionCode, Environment.NewLine,
text.Substring(functionStart));
}
else
{
int closeBraceAt = FindClosingBrace(text, match.Index);
if (closeBraceAt >= 0)
{
text = string.Format("{0}{1}{2}{3}{4}",
text.Substring(0, closeBraceAt),
Environment.NewLine, functionCode, Environment.NewLine,
text.Substring(closeBraceAt));
}
else
{
// Script missing closing brace?
text = string.Format("{0}{1}{2}{3}}}",
text, Environment.NewLine, functionCode, Environment.NewLine);
}
}
}
else
{
// Add a new function to the end of the script
text += string.Format("{0}function {1}({2}){3}{{{4}{5}{6}}}{7}",
Environment.NewLine, functionName, paramList, Environment.NewLine, Environment.NewLine,
functionCode, Environment.NewLine, Environment.NewLine);
}
return text;
}
}
}
9 changes: 8 additions & 1 deletion Editor/AGS.Types/Script.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,14 @@ public Script(string fileName, string text, string name, string description, str
public string Text
{
get { return _text; }
set { _text = value ?? string.Empty; _modified = true; }
set
{
if (_text != value)
{
_text = value ?? string.Empty;
_modified = true;
}
}
}

[ReadOnly(true)]
Expand Down
5 changes: 4 additions & 1 deletion Engine/main/game_start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ void start_game() {

our_eip = -43;

SetRestartPoint();
// Only auto-set first restart point in < 3.6.1 games,
// since 3.6.1+ users are suggested to set one manually in script.
if (loaded_game_file_version < kGameVersion_361_10)
SetRestartPoint();

our_eip=-3;

Expand Down

0 comments on commit 9adc7ea

Please sign in to comment.