public ActorBehaviorsEditor(string actorId, VoosEngine engine, UndoStack undoStack)
 {
     this.actorId        = actorId;
     this.engine         = engine;
     this.undoStack      = undoStack;
     this.behaviorSystem = actor.GetBehaviorSystem();
 }
    // Best-effort semantics. This will silently fail and just not call thenFunc
    // is the actor can't be found or can't be owned before timeout.
    public static void GetValidActorThen(
        VoosEngine engineRef, string actorName,
        System.Action <VoosActor> thenFunc)
    {
        VoosActor currentActor = engineRef.GetActor(actorName);

        if (currentActor == null)
        {
            return;
        }
        currentActor.RequestOwnershipThen(() => thenFunc(currentActor));
    }
    public static string GetUnableToEditActorReason(VoosEngine engineRef, string actorName)
    {
        VoosActor currentActor = engineRef.GetActor(actorName);

        if (currentActor == null)
        {
            return($"The actor does not exist anymore.");
        }
        if (currentActor.IsLockedByAnother())
        {
            return($"{currentActor.GetLockingOwnerNickName()} is editing '{currentActor.GetDisplayName()}'.");
        }
        return(null);
    }
    public static void PushUndoForActor(this UndoStack stack, VoosActor theActor, string label, System.Action <VoosActor> doIt, System.Action <VoosActor> undo)
    {
        // IMPORTANT: Do *NOT* use a reference to the actor! It may be deleted,
        // un-deleted, etc. So use its name, which is stable.
        string actorName = theActor.GetName();

        // Assume the VoosEngine instance is stable.
        VoosEngine engineRef = theActor.GetEngine();

        stack.Push(new UndoStack.Item
        {
            actionLabel           = label,
            getUnableToDoReason   = () => GetUnableToEditActorReason(engineRef, actorName),
            getUnableToUndoReason = () => GetUnableToEditActorReason(engineRef, actorName),
            doIt = () => GetValidActorThen(engineRef, actorName, doIt),
            undo = () => GetValidActorThen(engineRef, actorName, undo)
        });
    }
Beispiel #5
0
    public IEnumerator Setup()
    {
        TestUtil.TestScene scene = new TestUtil.TestScene("main");
        yield return(scene.LoadAndWait());

        behaviorSystem = scene.FindRootComponent <BehaviorSystem>("ScriptingSystems");
        voosEngine     = scene.FindRootComponent <VoosEngine>("ScriptingSystems");

        // Wait for loading done..
        while (true)
        {
            if (voosEngine.GetIsRunning())
            {
                yield break;
            }
            yield return(null);
        }
    }
Beispiel #6
0
 public Services(
     TerrainManager terrainSystem,
     VoosEngine engine,
     GameUiMain gameUiMain,
     SoundEffectSystem soundEffectSystem,
     ParticleEffectSystem particleEffectSystem,
     VirtualPlayerManager virtualPlayerManager,
     PlayerControlsManager playerControlsManager,
     GameBuilderStage gbStage)
 {
     this.terrainSystem         = terrainSystem;
     this.engine                = engine;
     this.gameUiMain            = gameUiMain;
     this.soundEffectSystem     = soundEffectSystem;
     this.particleEffectSystem  = particleEffectSystem;
     this.virtualPlayerManager  = virtualPlayerManager;
     this.playerControlsManager = playerControlsManager;
     this.gbStage               = gbStage;
 }
    public string ToUserFriendlyString(VoosEngine engine)
    {
        switch (mode)
        {
        case Mode.NONE:
            return("(Nothing)");

        case Mode.BY_TAG:
            return((tagOrName == "player") ? "(Player)" : "Tag: " + tagOrName);

        case Mode.BY_NAME:
            VoosActor actor = engine.GetActor(tagOrName);
            return(actor != null?actor.GetDisplayName() : "(invalid)");

        case Mode.ANY:
            return("(any actor)");

        default:
            throw new System.Exception("Invalid mode " + mode);
        }
    }
    public void Load(SaveGame saved, string voosFilePath = null)
    {
        StartCoroutine(PerformDeferredBehaviorUpgrades(saved.version));

        bool removeUnusedBehaviors = saved.version < FirstVersionAllowingUnusedBehaviors;
        var  usedBrainIds          = VoosEngine.GetUsedBrainIds(saved.voosEngineState.actors);

        if (saved.version < FirstVersionWithLegacyWarning)
        {
            behaviors.returnEmptyForMissingBuiltinBehaviors = true;
        }
        behaviors.LoadDatabase(saved.behaviorDatabase, removeUnusedBehaviors, usedBrainIds);

        engine.SetPersistedState(saved.voosEngineState);
        // Load stage before terrain..dependency there for world size. Not sure if good...shouldn't terrain just have its own size?
        stage.Load(saved.stage);
        terrain.SetPersistedState(stage.GetGroundSize(), saved.gridState);

        sojoSystem.Reset();
        if (saved.version >= FirstVersionWithSojoDatabase)
        {
            sojoSystem.LoadDatabase(saved.sojoDatabase);
        }
        if (saved.cardPacks != null)
        {
            behaviors.LoadCardPacks(saved.cardPacks);
        }
        if (saved.actorPacks != null)
        {
            sceneActorLibrary.LoadActorPacks(saved.actorPacks);
        }

        if (saved.version < FirstVersionWithLegacyWarning && !SuppressLegacyWarning)
        {
            popups.ShowTwoButtons(OLD_SAVE_MESSAGE,
                                  "Open Project Location", () => { Application.OpenURL("file://" + System.IO.Path.GetDirectoryName(voosFilePath)); },
                                  "OK", null, 800f);
        }
    }
    public static void PushUndoForMany(this UndoStack stack, VoosEngine engine, IEnumerable <VoosActor> actors, string verb, System.Action <VoosActor> doIt, System.Action <VoosActor> undo)
    {
        List <string> actorNames = (from actor in actors select actor.GetName()).ToList();

        if (actorNames.Count == 1)
        {
            // Special case this to be the fancier.
            string actorName = actorNames[0];
            if (GetUnableToEditActorReason(engine, actorName) == null)
            {
                VoosActor actor = engine.GetActor(actorName);
                stack.PushUndoForActor(actor, $"{verb} {actor.GetDisplayName()}", doIt, undo);
            }
            return;
        }

        stack.Push(new UndoStack.Item
        {
            actionLabel = $"{verb} {actorNames.Count} actors",
            // We'll just do best effort for all this - so never block it.
            getUnableToDoReason   = () => null,
            getUnableToUndoReason = () => null,
            doIt = () =>
            {
                foreach (string name in actorNames)
                {
                    GetValidActorThen(engine, name, doIt);
                }
            },
            undo = () =>
            {
                foreach (string name in actorNames)
                {
                    GetValidActorThen(engine, name, undo);
                }
            }
        });
    }
    public virtual VoosActor Instantiate(VoosEngine engine, BehaviorSystem behaviorSystem, Vector3 position, Quaternion rotation, System.Action <VoosActor> setupActor)
    {
        // TODO TODO we should make a copy of 'saved' in case Instantiate is called again..
        if (this.saved.sojos != null)
        {
            foreach (var savedSojo in this.saved.sojos)
            {
                if (sojos.GetSojoById(savedSojo.id) == null)
                {
                    sojos.PutSojo(Sojo.Load(savedSojo));
                }
            }
        }

        // Import behaviors. For now, create entirely new brain IDs.
        var brainIdMap = new Dictionary <string, string>();

        for (int i = 0; i < this.saved.brainDatabase.brainIds.Length; i++)
        {
            string brainId = this.saved.brainDatabase.brainIds[i];
            string newId   = behaviorSystem.GenerateUniqueId();
            brainIdMap[brainId] = newId;
            this.saved.brainDatabase.brainIds[i] = newId;
        }

        // Use the new brain IDs..
        for (int i = 0; i < saved.actors.Length; i++)
        {
            if (brainIdMap.ContainsKey(saved.actors[i].brainName))
            {
                saved.actors[i].brainName = brainIdMap[saved.actors[i].brainName];
            }
            else
            {
                // Always default to default brain. Some prefabs have dangling brain
                // IDs, and bad stuff can happen if we just keep those.
                Util.LogWarning($"WARNING: Actor prefab '{saved.actors[i].displayName}' ({saved.actors[i].name}) had dangling brainName: {saved.actors[i].brainName}");
                saved.actors[i].brainName = VoosEngine.DefaultBrainUid;
            }
        }

        var expectedBrainIds = new HashSet <string>(from actor in this.saved.actors select actor.brainName);

        behaviorSystem.MergeNonOverwrite(saved.brainDatabase, expectedBrainIds);

        // Instantiate the actor hierarchy - very important we update the parent
        // references, as well as any property references in the use..

        // Create new names for all actors
        var actorNameMap = new Dictionary <string, string>();

        foreach (var savedActor in saved.actors)
        {
            actorNameMap[savedActor.name] = engine.GenerateUniqueId();
        }

        // Compute xform to go from saved to instance... then just apply to all.
        var savedRoot = saved.actors[0];

        Matrix4x4 savedRootLocalToWorld = new Matrix4x4();

        savedRootLocalToWorld.SetTRS(savedRoot.position, savedRoot.rotation, savedRoot.localScale);

        Matrix4x4 instRootLocalToWorld = new Matrix4x4();

        instRootLocalToWorld.SetTRS(position, rotation, savedRoot.localScale);

        Matrix4x4 savedToInstance = instRootLocalToWorld * savedRootLocalToWorld.inverse;

        // Instantiate the tree.
        List <VoosActor> instances = new List <VoosActor>();

        foreach (var savedActor in saved.actors)
        {
            string instanceName = actorNameMap[savedActor.name];

            Vector3    instPos = savedToInstance * savedActor.position.ToHomogeneousPosition();
            Quaternion instRot = savedToInstance.rotation * savedActor.rotation;

            System.Action <VoosActor> setupThisActor = actor =>
            {
                Debug.Assert(actor.GetName() == instanceName, "New instance did not have the new name we generated");
                // Push the saved data to this new actor
                var actorDataCopy = savedActor;
                actorDataCopy.position = instPos;
                actorDataCopy.rotation = instRot;
                actorDataCopy.name     = instanceName;

                // Make sure we update the transform parent!
                if (!actorDataCopy.transformParent.IsNullOrEmpty() &&
                    actorNameMap.ContainsKey(actorDataCopy.transformParent))
                {
                    actorDataCopy.transformParent = actorNameMap[actorDataCopy.transformParent];
                }

                if (!actorDataCopy.spawnTransformParent.IsNullOrEmpty() &&
                    actorNameMap.ContainsKey(actorDataCopy.spawnTransformParent))
                {
                    actorDataCopy.spawnTransformParent = actorNameMap[actorDataCopy.spawnTransformParent];
                }

                actor.UpdateFrom(actorDataCopy);
                setupActor(actor);
            };

            VoosActor instance = engine.CreateActor(instPos, instRot, setupThisActor, instanceName);
            instances.Add(instance);
        }

        // FINALLY...fix up any actor refs!
        foreach (VoosActor inst in instances)
        {
            var brain = ActorBehaviorsEditor.FromActor(inst);
            foreach (var assigned in brain.GetAssignedBehaviors())
            {
                foreach (var prop in assigned.GetProperties())
                {
                    if (prop.propType == BehaviorProperties.PropType.Actor)
                    {
                        string refActorName = (string)prop.data;
                        if (!refActorName.IsNullOrEmpty() && actorNameMap.ContainsKey(refActorName))
                        {
                            prop.SetData(actorNameMap[refActorName]);
                        }
                    }
                    else if (prop.propType == BehaviorProperties.PropType.ActorGroup)
                    {
                        ActorGroupSpec group = ActorGroupSpec.FromString((string)prop.data);
                        if (group.mode == ActorGroupSpec.Mode.BY_NAME && actorNameMap.ContainsKey(group.tagOrName))
                        {
                            group = group.WithTagOrName(actorNameMap[group.tagOrName]);
                            prop.SetData(group.ToString());
                        }
                    }
                }
            }
        }

        return(instances[0]);
    }
Beispiel #11
0
 public int GetLineNumberForError(string errorMessage)
 {
     return(VoosEngine.ExtractFirstLineNumberForModuleError(this.behaviorUri, errorMessage));
 }