Пример #1
0
        /// <summary>
        /// Transforms FML into BML and executes
        /// </summary>
        /// <param name="body">the FML body containing the FML functions to be interpreted</param>
        private void interpret(FMLBody body)
        {
            foreach (var chunk in body.chunks) {
                BMLBody curr = new BMLBody();
                chunk.BMLRef = curr;
                foreach (var function in chunk.functions) {
                    Vocalisation voc = new Vocalisation("Vocal", chunk.owner, 1f, mood.GetArousal(), mood.GetValence());
                    switch (function.Function) {
                        case FMLFunction.FunctionType.BOARDGAME_REACT_MOVE:
                            ReactMoveFunction react = function as ReactMoveFunction;
                            this.react(react.MoveToReact[0], react.MyMove ? player : (player == Player.First ? Player.Second : Player.First));
                            FaceEmotion faceReact;
                            Posture poser = new Posture("postureReact", chunk.owner, Behaviour.Lexemes.Stance.SITTING, 0f, 8f);
                            if (surprised.Check()) {
                                int coin = UnityEngine.Random.Range(0, 3);
                                faceReact = new FaceEmotion("ConfusedFace", chunk.owner, 0f, 1.4f * expressionIntensity, 0.8f * expressionIntensity);
                                if (coin < 2) {
                                    poser.AddPose(Behaviour.Lexemes.BodyPart.RIGHT_ARM, Behaviour.Lexemes.BodyPose.FIST_COVER_MOUTH);
                                    curr.AddChunk(poser);
                                }
                                coin = UnityEngine.Random.Range(0, noiseChance);
                                curr.AddChunk(faceReact);
                                if (coin == 0) curr.AddChunk(voc);
                            }
                            break;
                        case FMLFunction.FunctionType.BOARDGAME_CONSIDER_MOVE:
                            //tbh this shouldn't be here
                            if (impatient.Check()) {
                                Debug.Log("IMPATIENT");
                                Gaze glanceAtPlayer = new Gaze("glanceAtPlayer", chunk.owner, motion.Player, Behaviour.Lexemes.Influence.HEAD, start: 0f, end: 0.25f, priority: 2);
                                curr.AddChunk(glanceAtPlayer);
                                curr.AddChunk(voc);
                            } else {
                                ConsiderMoveFunction func = function as ConsiderMoveFunction;
                                if (func.MoveToConsider.Type == MoveType.MOVE) {
                                    Gaze glanceFrom = new Gaze("glanceAtFrom", chunk.owner, BoardgameManager.Instance.GetCellObject(func.MoveToConsider.From),
                                        Behaviour.Lexemes.Influence.HEAD, start: 0f, end: 2f);
                                    curr.AddChunk(glanceFrom);
                                    Gaze glanceTo = new Gaze("glanceAtTo", chunk.owner, BoardgameManager.Instance.GetCellObject(func.MoveToConsider.To),
                                        Behaviour.Lexemes.Influence.HEAD, start: 2.1f, end: 2f, priority: 2);
                                    curr.AddChunk(glanceTo);
                                } else {
                                    Gaze glanceTo = new Gaze("glanceAtCell", chunk.owner, BoardgameManager.Instance.GetCellObject(func.MoveToConsider.To),
                                       Behaviour.Lexemes.Influence.HEAD, start: 0f, end: 2f);
                                    curr.AddChunk(glanceTo);
                                }
                            }

                            break;
                        case FMLFunction.FunctionType.BOARDGAME_MAKE_MOVE:
                            MakeMoveFunction move = function as MakeMoveFunction;
                            PhysicalCell from, to;
                            BoardgameManager.Instance.GetMoveFromTo(move.MoveToMake[0], player, out from, out to);
                            Grasp reach = new Grasp("reachTowardsPiece", chunk.owner, from.gameObject,
                                Behaviour.Lexemes.Mode.LEFT_HAND, (arm) => { graspPiece(from, arm); }, 0, end: 1.5f);
                            Posture leanReach = new Posture("leantowardsPiece", chunk.owner, Behaviour.Lexemes.Stance.SITTING, 0, end: 1.5f, priority: 2);
                            Gaze lookReach = new Gaze("glanceAtReach", chunk.owner, from.gameObject, Behaviour.Lexemes.Influence.HEAD, start: 0f, end: 1.25f);
                            Debug.Log((int)(Vector3.Distance(from.transform.position, transform.position) * 40));
                            leanReach.AddPose(Behaviour.Lexemes.BodyPart.WHOLEBODY, Behaviour.Lexemes.BodyPose.LEANING_FORWARD,
                                (int)(Vector3.Distance(from.transform.position, transform.position) * 40));
                            Place place = new Place("placePiece", chunk.owner, to.gameObject,
                                Behaviour.Lexemes.Mode.LEFT_HAND, (piece) => {
                                    placePiece(piece, to);
                                    BoardgameManager.Instance.MoveMade(move.MoveToMake, player); BoardgameManager.Instance.SyncState(); BoardgameManager.Instance.MakeNoise(to.id);
                                },
                                1.25f, end: 2f);
                            Posture leanPlace = new Posture("leantowardsCell", chunk.owner, Behaviour.Lexemes.Stance.SITTING, 1.25f, end: 1.5f, priority: 3);
                            leanPlace.AddPose(Behaviour.Lexemes.BodyPart.WHOLEBODY, Behaviour.Lexemes.BodyPose.LEANING_FORWARD,
                                (int)(Vector3.Distance(to.transform.position, transform.position) * 40));
                            Gaze lookPlace = new Gaze("glanceAtPlace", chunk.owner, to.gameObject, Behaviour.Lexemes.Influence.HEAD, start: 1.25f, end: 2f, priority: 2);
                            Gaze glance = new Gaze("glanceAtPlayer", chunk.owner, motion.Player, Behaviour.Lexemes.Influence.HEAD, start: 2f, end: 1.25f, priority: 3);
                            curr.AddChunk(glance);
                            curr.AddChunk(lookReach);
                            curr.AddChunk(lookPlace);
                            curr.AddChunk(leanReach);
                            curr.AddChunk(leanPlace);
                            curr.AddChunk(reach);
                            curr.AddChunk(place);
                            break;
                        case FMLFunction.FunctionType.EMOTION:
                            //transform expression
                            EmotionFunction f = function as EmotionFunction;
                            float v = Mathf.Clamp(f.Valence, 0, 2);

                            if (v < Config.Neutral) {
                                v = (v - Config.Neutral) * 0.8f + Config.Neutral;
                            }
                            float a = Mathf.Clamp(f.Arousal, 0, 2);
                            if (a > Config.Neutral) {
                                a = (a - Config.Neutral) * 0.6f + Config.Neutral;
                            }
                            FaceEmotion fe = new FaceEmotion("emote " + f.Arousal + " " + f.Valence, chunk.owner, 0f, a, v);
                            float lean = Mathf.Clamp((f.Arousal - Config.Neutral) * 30, -20, 30);
                            Posture emoLean = new Posture("emoteLean", chunk.owner, Behaviour.Lexemes.Stance.SITTING, 0, end: 3f);
                            emoLean.AddPose(Behaviour.Lexemes.BodyPart.WHOLEBODY, Behaviour.Lexemes.BodyPose.LEANING_FORWARD, (int)lean);
                            curr.AddChunk(emoLean);
                            curr.AddChunk(fe);
                            break;
                    }
                }
            }
            //sort out timing
            foreach (var chunk in body.chunks) {
                if (chunk.timing != null) {
                    switch (chunk.timing.Primitive) {
                        case Primitive.MustEndBefore:
                            chunk.timing.ChunkReference.BMLRef.ExecuteAfter(chunk.BMLRef);
                            break;
                        case Primitive.StartImmediatelyAfter:
                            chunk.BMLRef.ExecuteAfter(chunk.timing.ChunkReference.BMLRef);
                            break;
                    }
                }
            }

            //let's refactor this later so that we don't have to do 3N
            foreach (var chunk in body.chunks) {
                behave.ScheduleBehaviour(chunk.BMLRef);
            }
        }