private void SetPlayerNumberOnPlayerControlsPanel(VoosActor actor, Behaviors.BehaviorUse use, int playerNumber) { use = use.DeepClone(); use.SetPropertyValue(PLAYER_NUMBER_PROP_NAME, playerNumber); Behaviors.Brain brain = actor.GetBehaviorSystem().GetBrain(actor.GetBrainName()); if (brain == null) { Debug.LogErrorFormat("Could not set player# on actor {0} ({1}). No brain.", actor.GetName(), actor.GetDisplayName()); return; } brain.SetUse(use); actor.GetBehaviorSystem().PutBrain(actor.GetBrainName(), brain); }
private static Behaviors.BehaviorUse TryGetPlayerControlsPanel(VoosActor actor) { Behaviors.Brain brain = actor.GetBehaviorSystem().GetBrain(actor.GetBrainName()); if (brain == null) { return(null); } foreach (Behaviors.BehaviorUse use in actor.GetBehaviorSystem().GetBrain(actor.GetBrainName()).GetUses()) { if (use.behaviorUri == PLAYER_CONTROLS_PANEL_URI) { return(use); } } return(null); }
private void HandleBehaviorException(VoosEngine.BehaviorLogItem item) { MaybeNotifyUserOfBehaviorError(item); VoosActor actor = voosEngine.GetActor(item.actorId); string behDesc = GetBehaviorTitle(actor.GetBrainName(), item.useId); CommandTerminal.HeadlessTerminal.Buffer.HandleLog($"<color=yellow>[{actor.GetDisplayName()} '{behDesc}' on{item.messageName}:{item.lineNum}]</color> <color=red>{item.message}</color>", TerminalLogType.Error, null); }
private void DeletePlayerControlsPanel(VoosActor actor) { Debug.Assert(actor.IsLocallyOwned(), "Actor should be locally owned"); Behaviors.BehaviorUse playerControlsPanel = TryGetPlayerControlsPanel(actor); if (playerControlsPanel == null) { return; } Behaviors.Brain brain = actor.GetBehaviorSystem().GetBrain(actor.GetBrainName()); if (brain == null) { Debug.LogErrorFormat("Could not set player# on actor {0} ({1}). No brain.", actor.GetName(), actor.GetDisplayName()); return; } // PLAYER_CONTROLS_PANEL_HAS_NO_DECKS_ASSUMPTION // WARNING: this is a naive delete that doesn't recursively look for behavior uses mentioned // in any decks used by the Player Controls panel, so if in the future we do add decks to it, // we need to update this logic to remove the panel properly. brain.DeleteUse(playerControlsPanel.id); actor.GetBehaviorSystem().PutBrain(actor.GetBrainName(), brain); }
private void HandleBehaviorLogMessage(VoosEngine.BehaviorLogItem item) { UpdateFloodDetection(); if (item.message.Contains("ERROR: ")) { MaybeNotifyUserOfBehaviorError(item); } VoosActor actor = voosEngine.GetActor(item.actorId); string behDesc = GetBehaviorTitle(actor.GetBrainName(), item.useId); CommandTerminal.HeadlessTerminal.Buffer.HandleLog($"<color=#666666>[{actor.GetDisplayName()} '{behDesc}' on{item.messageName}:{item.lineNum}]</color> <color=white>{item.message}</color>", TerminalLogType.Message, null); }
private void BreakLink(bool withUndo = true) { VoosActor actor = currActor; // Save for undo string prevParent = actor.GetCloneParent(); SetActorInternal(null); actor.SetCloneParent(null); actor.MakeOwnCopyOfBrain(); if (withUndo) { // Setup undo item string actorName = actor.GetName(); string newBrain = actor.GetBrainName(); undo.Push(new UndoStack.Item { actionLabel = $"Break copy-link of {actor.GetDisplayName()}", getUnableToDoReason = () => ActorUndoUtil.GetUnableToEditActorReason(voosEngine, actorName), doIt = () => { var redoActor = voosEngine.GetActor(actorName); redoActor.SetCloneParent(null); // A bit sloppy: We're relying on the fact that brains are never deleted // (except on load). redoActor.SetBrainName(newBrain); OnBreakLinkChanged(redoActor); }, getUnableToUndoReason = () => { var prevParentActor = voosEngine.GetActor(prevParent); if (prevParentActor == null) { return($"The original copy no longer exists."); } return(null); }, undo = () => { var undoActor = voosEngine.GetActor(actorName); var prevParentActor = voosEngine.GetActor(prevParent); Debug.Assert(prevParent != null, "BreakLink undo action: prevParent does not exist anymore"); undoActor.SetCloneParent(prevParent); undoActor.SetBrainName(prevParentActor.GetBrainName()); OnBreakLinkChanged(undoActor); } }); } SetActorInternal(actor); }
public IEnumerator TestHandleMultipleInOneFrame() { yield return(Setup()); VoosActor actor = voosEngine.CreateActor(new Vector3(1, 2, 3), Quaternion.identity, newActor => { }); actor.SetTint(new Color(0.1f, 0.1f, 0.1f)); Assert.NotNull(actor); Assert.AreEqual(1.0, actor.transform.position.x, 1e-4); string brainId = actor.GetBrainName(); string behaviorId = behaviorSystem.GenerateUniqueId(); string js = @" export function onMoveRight() { const c = getTint(); c.r += 0.1; setTint(c.r, c.g, c.b); } "; behaviorSystem.PutBehavior(behaviorId, new Behaviors.Behavior { javascript = js }); PutTestUse(new TestUse { behaviorUri = IdToEmbeddedBehaviorUri(behaviorId), brainId = brainId }); // We expect x to increment by 2.. voosEngine.EnqueueMessage(new VoosEngine.ActorMessage { name = "MoveRight", targetActor = actor.GetName() }); voosEngine.EnqueueMessage(new VoosEngine.ActorMessage { name = "MoveRight", targetActor = actor.GetName() }); // Let it run at least one voos update yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); Assert.AreEqual(0.3, actor.GetTint().r, 1e-4); }
void MaybeNotifyUserOfBehaviorError(VoosEngine.BehaviorLogItem item) { // Errors are a big deal - quietly failing just leads to further confusion. // So, we're just gonna do popups. if (Time.unscaledTime - lastErrorPopupTime > 3f && (!IsCodeEditorOpen() || item.lineNum == -1)) { lastErrorPopupTime = Time.unscaledTime; var brainId = voosEngine.GetActor(item.actorId).GetBrainName(); var uri = behaviorSystem.GetBrain(brainId).GetUse(item.useId).behaviorUri; VoosActor actor = voosEngine.GetActor(item.actorId); string behDesc = GetBehaviorTitle(actor.GetBrainName(), item.useId); var niceMsg = $"Script error for actor '{actor.GetDisplayName()}' from card '{behDesc}':\n{item.message}"; string fullMessage = $"{niceMsg}\n<color=yellow>'on{item.messageName}' will be disabled until the script is edited or the game is reset.</color>\nYou may want to pause the game if the error is repeating."; onDisplayCodeError?.Invoke(fullMessage, uri, item); } }
public IEnumerator TestBasic() { yield return(Setup()); VoosActor actor = voosEngine.CreateActor(new Vector3(1, 2, 3), Quaternion.identity, _ => { }); Assert.NotNull(actor); Assert.AreEqual(1.0, actor.GetTint().r, 1e-4); string brainId = actor.GetBrainName(); string behaviorId = NewGUID(); string js = @" export function onTick(api) { setTint(0.12, 0.34, 0.56); } "; behaviorSystem.PutBehavior(behaviorId, new Behavior { javascript = js }); var use = new BehaviorUse { id = NewGUID(), behaviorUri = IdToEmbeddedBehaviorUri(behaviorId) }; var brain = new Brain { behaviorUses = new BehaviorUse[] { use } }; behaviorSystem.PutBrain(brainId, brain); // Let it run at least one voos update yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); Assert.AreEqual(0.12, actor.GetTint().r, 1e-4); }