Skip to content

Commit

Permalink
zzre: Fix exception for duplicated labels in scripts
Browse files Browse the repository at this point in the history
Fixes #277
  • Loading branch information
Helco committed Jan 21, 2024
1 parent 0dd5f06 commit e31011d
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 13 deletions.
25 changes: 17 additions & 8 deletions zzre/game/components/ScriptExecution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace zzre.game.components;
public class ScriptExecution // reference type as we have to have reference members as well
{
public IReadOnlyList<RawInstruction> Instructions { get; }
public IReadOnlyDictionary<int, int> LabelTargets { get; }
public int CurrentI;

public bool HasStopped => CurrentI >= Instructions.Count;
Expand All @@ -21,17 +20,27 @@ public ScriptExecution(string script)
.Select(s => new RawInstruction(s))
.Select(Compile)
.ToArray();

LabelTargets = Instructions
.Indexed()
.Where(t => t.Value.Command == "$")
.ToDictionary(
t => int.Parse(t.Value.Arguments.First()),
t => t.Index);
}

// TODO: Replace ScriptExecution ctor with actual compiler

public bool GoToLabel(int labelId)
{
int i;
for (i = CurrentI; i < Instructions.Count; i++)
{
if (Instructions[i].Command == "$" &&
int.Parse(Instructions[i].Arguments.First()) == labelId)
break;
}
if (i < Instructions.Count)
{
CurrentI = i;
return true;
}
return false;
}

private static RawInstruction Compile(RawInstruction raw) => LongToShortCommand.TryGetValue(raw.Command, out var shortCommand) ?
new RawInstruction(shortCommand, raw.Arguments)
: raw;
Expand Down
6 changes: 3 additions & 3 deletions zzre/game/systems/BaseScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,22 @@ private OpReturn ExecuteSystem(in DefaultEcs.Entity entity, ref components.Scrip

case CmdGoto:
var label = int.Parse(instruction.Arguments.Single());
script.CurrentI = script.LabelTargets[label];
script.GoToLabel(label);
return OpReturn.Continue;

case CmdGotoRandomLabel:
var range = int.Parse(instruction.Arguments[0]);
var start = int.Parse(instruction.Arguments[1]);
label = start + Random.Shared.Next(range);
script.CurrentI = script.LabelTargets[label];
script.GoToLabel(label);
return OpReturn.Continue;

case CmdGotoLabelByRandom:
// a percentage of *not* jumping to a label -_-
var percentage = int.Parse(instruction.Arguments[0]);
label = int.Parse(instruction.Arguments[1]);
if (Random.Shared.Next(100) >= percentage)
script.CurrentI = script.LabelTargets[label];
script.GoToLabel(label);
return OpReturn.Continue;

case CmdSetGlobal:
Expand Down
2 changes: 1 addition & 1 deletion zzre/game/systems/dialog/DialogChoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private void HandleElementDown(DefaultEcs.Entity _, components.ui.ElementId clic
var dialogChoice = uiEntity.Get<components.DialogChoice>();
var dialogEntity = dialogChoice.DialogEntity;
ref var script = ref dialogEntity.Get<components.ScriptExecution>();
script.CurrentI = script.LabelTargets[dialogChoice.Labels[choiceI]];
script.GoToLabel(dialogChoice.Labels[choiceI]);
dialogEntity.Set(components.DialogState.NextScriptOp);
uiEntity.Dispose();
}
Expand Down
2 changes: 1 addition & 1 deletion zzre/game/systems/dialog/DialogTalk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private void HandleElementDown(DefaultEcs.Entity clickedEntity, components.ui.El
var talkLabels = dialogEntity.Get<components.DialogTalkLabels>();
int targetLabel = clickedId == IDYes ? talkLabels.LabelYes : talkLabels.LabelNo;
ref var scriptExec = ref dialogEntity.Get<components.ScriptExecution>();
scriptExec.CurrentI = scriptExec.LabelTargets[targetLabel];
scriptExec.GoToLabel(targetLabel);
dialogEntity.Set(components.DialogState.NextScriptOp);
talkEntity.Dispose();
}
Expand Down

0 comments on commit e31011d

Please sign in to comment.