void DoSentence()
{
var a = GetVarOrDirectByte(OpCodeParameter.Param1);
if (a == 0xFC)
{
SentenceNum = 0;
StopScript(SENTENCE_SCRIPT);
return;
}
if (a == 0xFB)
{
ResetSentence();
return;
}
var st = Sentence[SentenceNum++] = new Sentence(
(byte)a,
(ushort)GetVarOrDirectWord(OpCodeParameter.Param2),
(ushort)GetVarOrDirectWord(OpCodeParameter.Param3));
// Execute or print the sentence
_opCode = ReadByte();
switch (_opCode)
{
case 0:
// Do nothing (besides setting up the sentence above)
break;
case 1:
// Execute the sentence
SentenceNum--;
if (st.Verb == 254)
{
StopObjectScriptCore(st.ObjectA);
}
else
{
bool isBackgroundScript;
bool isSpecialVerb;
if (st.Verb != 253 && st.Verb != 250)
{
Variables[VariableActiveVerb.Value] = st.Verb;
Variables[VariableActiveObject1.Value] = st.ObjectA;
Variables[VariableActiveObject2.Value] = st.ObjectB;
isBackgroundScript = false;
isSpecialVerb = false;
}
else
{
isBackgroundScript = (st.Verb == 250);
isSpecialVerb = true;
st = Sentence[SentenceNum] = new Sentence(
253,
st.ObjectA,
st.ObjectB);
}
// Check if an object script for this object is already running. If
// so, reuse its script slot. Note that we abuse two script flags:
// freezeResistant and recursive. We use them to track two
// script flags used in V1/V2 games. The main reason we do it this
// ugly evil way is to avoid having to introduce yet another save
// game revision.
int slot = -1;
for (var i = 0; i < Slots.Length; i++)
{
var ss = Slots[i];
if (st.ObjectA == ss.Number &&
ss.FreezeResistant == isBackgroundScript &&
ss.Recursive == isSpecialVerb &&
(ss.Where == WhereIsObject.Room || ss.Where == WhereIsObject.Inventory || ss.Where == WhereIsObject.FLObject))
{
slot = i;
break;
}
}
RunObjectScript(st.ObjectA, st.Verb, isBackgroundScript, isSpecialVerb, new int[0], slot);
}
break;
case 2:
// Print the sentence
SentenceNum--;
Variables[VariableSentenceVerb.Value] = st.Verb;
Variables[VariableSentenceObject1.Value] = st.ObjectA;
Variables[VariableSentenceObject2.Value] = st.ObjectB;
DrawSentence();
break;
default:
throw new NotSupportedException(string.Format("DoSentence: unknown subopcode {0}", _opCode));
}
}