public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMRunFunctionalTreeOperand)args; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; var ent = context.StackObject; if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this... { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction() { Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), }) == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } if (Execute) { //push it onto our stack, except now the stack object owns our soul! var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context); var routine = context.VM.Assemble(Behavior.bhav); var childFrame = new VMStackFrame { Routine = routine, Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent }; if (operand.Flags > 0) { context.Thread.Queue[0].IconOwner = context.StackObject; } childFrame.Args = new short[routine.Arguments]; context.Thread.Push(childFrame); return(VMPrimitiveExitCode.CONTINUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } } else { return(VMPrimitiveExitCode.GOTO_FALSE); } }
public override VMPrimitiveExitCode Execute(VMStackFrame context) { var operand = context.GetCurrentOperand <VMFindBestObjectForFunctionOperand>(); var entities = context.VM.Entities; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction() { Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } if (Execute) { //we can run this, it's suitable, yes I'LL TAKE IT context.StackObject = ent; return(VMPrimitiveExitCode.GOTO_TRUE); } //if not just keep searching } } return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( }
// End Container SLOTs interface public List <VMPieMenuInteraction> GetPieMenu(VM vm,VMEntity caller) { var pie = new List <VMPieMenuInteraction>(); if (TreeTable == null) { return(pie); } for (int i = 0; i < TreeTable.Interactions.Length; i++) { var action = TreeTable.Interactions[i]; bool CanRun = false; if (action.TestFunction != 0 && (((TTABFlags)action.Flags & TTABFlags.Debug) != TTABFlags.Debug)) { caller.ObjectData[(int)VMStackObjectVariable.HideInteraction] = 0; var Behavior = GetBHAVWithOwner(action.TestFunction,vm.Context); CanRun = (VMThread.EvaluateCheck(vm.Context,caller,new VMQueuedAction() { Callee = this, CodeOwner = Behavior.owner, StackObject = this, Routine = vm.Assemble(Behavior.bhav), }) == VMPrimitiveExitCode.RETURN_TRUE); if (caller.ObjectData[(int)VMStackObjectVariable.HideInteraction] == 1) { CanRun = false; } } else { CanRun = true; } if (CanRun) { pie.Add(new VMPieMenuInteraction() { Name = TreeTableStrings.GetString((int)action.TTAIndex), ID = (byte)action.TTAIndex }); } } return(pie); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMFindBestObjectForFunctionOperand)args; var entities = context.VM.Entities; int bestScore = int.MinValue; VMEntity bestObj = null; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), Args = new short[4] }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else { Execute = true; } if (Execute) { //calculate the score for this object. int score = 0; if (ScoreVar[operand.Function] != VMStackObjectVariable.Invalid) { score = ent.GetValue(ScoreVar[operand.Function]); if (ScoreVar[operand.Function] == VMStackObjectVariable.DirtyLevel && score < 800) { continue; //only clean "dirty" things. } } LotTilePos posDiff = ent.Position - context.Caller.Position; score -= (int)Math.Sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + (posDiff.Level * posDiff.Level * 900 * 256)) / 3; if (score > bestScore) { bestScore = score; bestObj = ent; } } } } if (bestObj != null) { context.StackObject = bestObj; return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( } }
public bool ExecuteEntryPoint(int entry,VMContext context,bool runImmediately,VMEntity stackOBJ,short[] args) { if (entry == 11) { //user placement, hack to do auto floor removal/placement for stairs if (Object.OBJ.LevelOffset > 0 && Position != LotTilePos.OUT_OF_WORLD) { var floor = context.Architecture.GetFloor(Position.TileX,Position.TileY,Position.Level); var placeFlags = (VMPlacementFlags)ObjectData[(int)VMStackObjectVariable.PlacementFlags]; if ((placeFlags & VMPlacementFlags.InAir) > 0) { context.Architecture.SetFloor(Position.TileX,Position.TileY,Position.Level,new FloorTile(),true); } if ((placeFlags & VMPlacementFlags.OnFloor) > 0 && (floor.Pattern == 0)) { context.Architecture.SetFloor(Position.TileX,Position.TileY,Position.Level,new FloorTile { Pattern = 1 },true); } } } bool result = false; if (EntryPoints[entry].ActionFunction > 255) { VMSandboxRestoreState SandboxState = null; if (GhostImage && runImmediately) { SandboxState = context.VM.Sandbox(); for (int i = 0; i < MultitileGroup.Objects.Count; i++) { var obj = MultitileGroup.Objects[i]; context.VM.AddEntity(obj); } } BHAV bhav; GameObject CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get <BHAV>(ActionID); } else if (ActionID < 8192) { //local bhav = Object.Resource.Get <BHAV>(ActionID); } else { //semi-global bhav = SemiGlobal.Get <BHAV>(ActionID); } CodeOwner = Object; if (bhav != null) { var routine = context.VM.Assemble(bhav); var action = new VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = stackOBJ, Routine = routine, Args = args }; if (runImmediately) { var checkResult = VMThread.EvaluateCheck(context,this,action); result = (checkResult == VMPrimitiveExitCode.RETURN_TRUE); } else { this.Thread.EnqueueAction(action); } } if (GhostImage && runImmediately) { //restore state context.VM.SandboxRestore(SandboxState); } return(result); } else { return(false); } }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMRunFunctionalTreeOperand)args; if (operand.Function == 65535) { return(VMPrimitiveExitCode.GOTO_FALSE); //wedding cake: invalid primitive operand } var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; var ent = context.StackObject; if (ent == null || ent.Dead) { return(VMPrimitiveExitCode.GOTO_FALSE); } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this... { var Behavior = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = Behavior.routine, Args = new short[4] }) == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else { Execute = true; } if (Execute) { //push it onto our stack, except now the stack object owns our soul! var tree = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context); if (tree == null) { return(VMPrimitiveExitCode.GOTO_FALSE); //does not exist } var routine = tree.routine; var childFrame = new VMStackFrame { Routine = routine, Caller = context.Caller, Callee = ent, CodeOwner = tree.owner, StackObject = ent, ActionTree = context.ActionTree }; if (operand.Flags > 0 && context.ActionTree) { context.Thread.ActiveAction.IconOwner = context.StackObject; } childFrame.Args = new short[routine.Arguments]; context.Thread.Push(childFrame); return(VMPrimitiveExitCode.CONTINUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } } else { return(VMPrimitiveExitCode.GOTO_FALSE); } }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMFindBestObjectForFunctionOperand)args; var entities = context.VM.Entities; int bestScore = int.MinValue; VMEntity bestObj = null; var entry = FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.GetValue(VMStackObjectVariable.LockoutCount) > 0 || (ent is VMGameObject && ((VMGameObject)ent).Disabled > 0) || ent.Position == LotTilePos.OUT_OF_WORLD) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = Behavior.routine, Args = new short[4] }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else if (SurfaceFunctions.Contains(entry)) { //ts1: surface functions that have no check tree rely on the engine to check there is nothing in slot 0. Execute = ent.GetSlot(0) == null; } else { Execute = true; } if (Execute) { if (ent.IsInUse(context.VM.Context, true)) { continue; //this object is in use. this check is more expensive than check trees, so do it last. } //calculate the score for this object. int score = 0; if (ScoreVar[operand.Function] != VMStackObjectVariable.Invalid) { var funcVar = ScoreVar[operand.Function]; score = ent.GetValue(funcVar); if (context.VM.TS1 || funcVar != VMStackObjectVariable.RepairState) { if (Thresholds.TryGetValue(funcVar, out var threshold) && score < threshold) { continue; } } else if (ent is VMAvatar || !((Model.TSOPlatform.VMTSOObjectState)ent.TSOState).Broken) { continue; } } LotTilePos posDiff = ent.Position - context.Caller.Position; score -= (int)Math.Sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + (posDiff.Level * posDiff.Level * 900 * 256)) / 3; if (score > bestScore) { bestScore = score; bestObj = ent; } } } } if (bestObj != null) { context.StackObject = bestObj; return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( } }
public void ExecuteEntryPoint(int entry,VMContext context,bool runImmediately) { if (EntryPoints[entry].ActionFunction > 255) { BHAV bhav; GameIffResource CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get <BHAV>(ActionID); CodeOwner = context.Globals.Resource; } else if (ActionID < 8192) { //local bhav = Object.Resource.Get <BHAV>(ActionID); CodeOwner = Object.Resource; } else { //semi-global bhav = SemiGlobal.Resource.Get <BHAV>(ActionID); CodeOwner = SemiGlobal.Resource; } var routine = context.VM.Assemble(bhav); if (bhav == null) { return; //throw new Exception("Invalid BHAV call!"); } short[] Args = null; VMEntity StackOBJ = null; if (entry == 1) { if (MainParam != 0) { Args = new short[4]; Args[0] = MainParam; MainParam = 0; } if (MainStackOBJ != 0) { StackOBJ = context.VM.GetObjectById(MainStackOBJ); MainStackOBJ = 0; } } var action = new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = StackOBJ, Routine = routine, Args = Args }; if (runImmediately) { VMThread.EvaluateCheck(context,this,action); } else { this.Thread.EnqueueAction(action); } } }