Пример #1
0
    public override void Initialize(Vector3 surfacePosition)
    {
        base.Initialize(surfacePosition);

        emptyBlock = new MaterialPropertyBlock();

        sampler.SampleMesh();

        blorbs          = new Blorb[sampler.Samples.Length];
        matrixes        = new Matrix4x4[sampler.Samples.Length];
        fingerPositions = new Vector3[fingers.Length];

        for (int i = 0; i < sampler.Samples.Length; i++)
        {
            MeshSample sample = sampler.Samples[i];
            Blorb      e      = new Blorb();
            e.Point         = sample.Point;
            e.Dir           = e.Point.normalized;
            e.Radius        = Random.Range(minRadius, maxRadius);
            e.Agitation     = Random.value;
            e.Goop          = GameObject.Instantiate(goopBlorbPrefabs[Random.Range(0, goopBlorbPrefabs.Length)], transform).GetComponent <GoopBlorb>();
            e.Rotation      = Random.Range(0, 360);
            e.RotationSpeed = Random.Range(-rotationSpeed, rotationSpeed);
            blorbs[i]       = e;
        }

        timeLastPopped = -100;

        updateBlorbs = true;
        Task updateTask = UpdateBlorbsLoop();
    }
Пример #2
0
        private static void ReadChunk(Blorb blorb, Stream stream, int start, int length, ReadOnlySpan <char> type, IDictionary <int, Chunk> chunks)
        {
            byte[]? rentedFromPool = null;
            Span <byte> buffer = length > 0xff
                ? (rentedFromPool = ArrayPool <byte> .Shared.Rent(length))
                : stackalloc byte[length];

            try
            {
                int bytesRead = stream.Read(buffer[..length]);
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the ZLR engine from a given stream.
        /// The stream must remain open while the engine is in use.
        /// </summary>
        /// <param name="gameStream">A stream containing either a plain Z-code
        /// file or a Blorb file which in turn contains a Z-code resource.</param>
        /// <param name="io"></param>
        public ZMachine(Stream gameStream, IZMachineIO io)
        {
            if (gameStream == null)
            {
                throw new ArgumentNullException("gameStream");
            }
            if (io == null)
            {
                throw new ArgumentNullException("io");
            }

            this.io = io;

            // check for Blorb
            byte[] temp = new byte[12];
            gameStream.Seek(0, SeekOrigin.Begin);
            gameStream.Read(temp, 0, 12);
            if (temp[0] == 'F' && temp[1] == 'O' && temp[2] == 'R' && temp[3] == 'M' &&
                temp[8] == 'I' && temp[9] == 'F' && temp[10] == 'R' && temp[11] == 'S')
            {
                Blorb blorb = new Blorb(gameStream);
                if (blorb.GetStoryType() == "ZCOD")
                {
                    gameStream = blorb.GetStoryStream();
                }
                else
                {
                    throw new ArgumentException("Not a Z-code Blorb");
                }
            }

            this.gameFile = gameStream;

            zmem = new byte[gameStream.Length];
            gameStream.Seek(0, SeekOrigin.Begin);
            gameStream.Read(zmem, 0, (int)gameStream.Length);

            if (zmem.Length < 64)
            {
                throw new ArgumentException("Z-code file is too short: must be at least 64 bytes");
            }

            zversion = zmem[0];

            if (zversion != 5 && zversion != 8)
            {
                throw new ArgumentException("Z-code version must be 5 or 8");
            }

            io.SizeChanged += new EventHandler(io_SizeChanged);
        }
Пример #4
0
        private static void HandleForm(Blorb blorb, Stream stream, int start, int length, IDictionary <int, Chunk> chunks)
        {
            _level++;
            Span <char> type = stackalloc char[4];

            while (stream.Position < start + length)
            {
                ReadChars(stream, type);
                int len = ReadInt(stream);
                // ReadBuffer(len);

                ReadChunk(blorb, stream, (int)stream.Position, len, type, chunks);
            }
            _level--;
        }
        public void StoryStarted(string StoryFileName, Blorb BlorbFile)
        {
            invoke(() =>
            {
                if (os_._blorbFile != null)
                {
                    _parent.Title = String.Format("FrotzNET - {0}", os_._blorbFile.StoryName);
                }
                else
                {
                    _parent.Title = String.Format("FrotzNET - {0}", StoryFileName);
                }

                OnStoryStarted(new GameSelectedEventArgs(StoryFileName, BlorbFile));
                _scrollback.Reset();
            });
        }
Пример #6
0
        public void StoryStarted(string StoryFileName, Blorb BlorbFile)
        {
            Dispatcher.Invoke(new Action(delegate
            {
                if (os_._blorbFile != null)
                {
                    _parent.Title = String.Format("FrotzNET - {0}", os_._blorbFile.StoryName);
                }
                else
                {
                    _parent.Title = String.Format("FrotzNET - {0}", StoryFileName);
                }

                if (GameSelected != null)
                {
                    GameSelected(this, new GameSelectedEventArgs(StoryFileName, BlorbFile));
                }
            }));
        }
Пример #7
0
    private void DrawBlorbs()
    {
        Color centerPoppedColor = centerPoppedGradient.Evaluate(centerPoppedCurve.Evaluate(Time.time - timeLastPopped));
        bool  applyPoppedColor  = centerPoppedColor.r > 0;
        float popScale          = popRecoveryScaleCurve.Evaluate(Time.time - timeLastPopped);

        for (int i = 0; i < blorbs.Length; i++)
        {
            Blorb e = blorbs[i];
            if (e.Popped)
            {
                float poppedTime = (Time.time - e.TimePopped) / respawnTime;
                e.Goop.Renderer.SetPropertyBlock(emptyBlock);
                e.Goop.transform.localScale = Vector3.one * Mathf.Lerp(minRadius, e.Radius + e.Bloat, poppedTime);
            }
            else
            {
                float normalizedBloat = Mathf.Clamp01(e.Bloat / maxBloatBeforePop);
                e.Goop.transform.localPosition = e.Point;
                e.Goop.transform.forward       = e.Dir;
                e.Goop.transform.Rotate(0f, 0f, e.Rotation, Space.Self);
                e.Goop.transform.localScale = Vector3.one * (e.Radius + e.Bloat) * popScale;

                if (normalizedBloat > 0.01f || applyPoppedColor)
                {
                    Color bloatColor = bloatGradientEmission.Evaluate(normalizedBloat);
                    bloatColor += centerPoppedColor;
                    e.Goop.PropertyBlock.SetColor(emissionColorPropName, bloatColor);
                    e.Goop.Renderer.SetPropertyBlock(e.Goop.PropertyBlock);
                }
                else
                {
                    e.Goop.Renderer.SetPropertyBlock(emptyBlock);
                }
            }
        }

        if (popEvents.Count > 0)
        {
            Blorb popEvent = popEvents.Dequeue();

            // Try getting a random one first
            int randomIndex = Random.Range(0, popParticles.Length);
            if (!popParticles[randomIndex].gameObject.activeSelf)
            {
                popParticles[randomIndex].transform.localPosition = popEvent.Point;
                popParticles[randomIndex].transform.forward       = popEvent.Dir;
                popParticles[randomIndex].gameObject.SetActive(true);
                return;
            }

            // If that didn't work just go through the list
            for (int i = 0; i < popParticles.Length; i++)
            {
                if (popParticles[i].gameObject.activeSelf)
                {
                    continue;
                }

                popParticles[i].transform.localPosition = popEvent.Point;
                popParticles[i].transform.forward       = popEvent.Dir;
                popParticles[i].gameObject.SetActive(true);
                break;
            }

            // Slime all fingers nearby
            for (int i = 0; i < fingerTips.Length; i++)
            {
                if (Vector3.Distance(popEvent.Point, fingers[i].position) < maxDistToFinger)
                {
                    FingerTip fingerTip = fingerTips[i];
                    fingerTip.SlimeIntensity = 1;
                    fingerTips[i]            = fingerTip;
                }
            }
        }

        popEvents.Clear();
    }
Пример #8
0
    private async Task UpdateBlorbs()
    {
        await new WaitForBackgroundThread();

        float timeSincePopped = time - timeLastPopped;
        float popRecovery     = popRecoveryCurve.Evaluate(timeSincePopped);
        int   numBlorbs       = blorbs.Length;

        //Gravity
        for (int i = 0; i < numBlorbs; i++)
        {
            Blorb   e        = blorbs[i];
            Vector3 idealPos = (e.Point.normalized * SurfaceRadius);
            e.Point   = Vector3.Lerp(e.Point, idealPos, gravity);
            blorbs[i] = e;
        }

        // Agitation / Rotation
        for (int i = 0; i < numBlorbs; i++)
        {
            Blorb   e           = blorbs[i];
            Vector3 randomPoint = RandomInsideSphere(random) * ((e.Agitation + e.Bloat) * agitationForce * deltaTime);
            e.Point = Vector3.Lerp(e.Point, e.Point + randomPoint, deltaTime);
            float newRadius = Mathf.Clamp(e.Radius + (RandomRange(random, -1f, 1f) * (e.Agitation + e.Bloat) * deltaTime), minRadius, maxRadius);
            e.Radius    = Mathf.Lerp(e.Radius, newRadius, radiusChangeSpeed * deltaTime);
            e.Bloat     = Mathf.Lerp(e.Bloat, 0, deltaTime * radiusChangeSpeed);
            e.Rotation += deltaTime * e.RotationSpeed;
            blorbs[i]   = e;
        }

        // Fingers
        totalAgitation = 0;
        for (int f = 0; f < fingerPositions.Length; f++)
        {
            Vector3 fingerPos = fingerPositions[f];

            for (int i = 0; i < numBlorbs; i++)
            {
                Blorb e            = blorbs[i];
                float distToFinger = Vector3.Distance(fingerPos, e.Point);
                if (distToFinger > maxDistToFinger)
                {
                    continue;
                }

                float fingerAgitation = fingerAgitationCurve.Evaluate(distToFinger / maxDistToFinger) * popRecovery;
                totalAgitation += fingerAgitation;
                e.Bloat         = Mathf.Lerp(e.Bloat, Mathf.Clamp(e.Bloat + fingerAgitation, 0, Mathf.Infinity), deltaTime * radiusChangeSpeed);
                blorbs[i]       = e;
            }
        }

        // Forces
        for (int i = 0; i < numBlorbs; i++)
        {
            for (int j = 0; j < numBlorbs; j++)
            {
                if (i == j)
                {
                    continue;
                }

                Blorb e1 = blorbs[i];
                Blorb e2 = blorbs[j];

                if (e1.Popped || e2.Popped)
                {
                    continue;
                }

                float dist         = Vector3.Distance(e1.Point, e2.Point);
                float touchingDist = (e1.Radius + e1.Bloat) + (e2.Radius + e2.Bloat);

                if (dist > touchingDist)
                {
                    continue;
                }

                float   overlap = touchingDist - dist;
                Vector3 dir     = (e1.Point - e2.Point).normalized;

                if (e1.Radius > e2.Radius)
                {
                    e2.Point -= dir * (overlap * deltaTime);
                    blorbs[j] = e2;
                }
                else
                {
                    e1.Point += dir * (overlap * deltaTime);
                    blorbs[i] = e1;
                }
            }
        }

        // Direction
        for (int i = 0; i < numBlorbs; i++)
        {
            Blorb e1 = blorbs[i];
            e1.Dir    = e1.Point.normalized;
            blorbs[i] = e1;
        }

        for (int i = 0; i < blorbs.Length; i++)
        {
            Blorb e = blorbs[i];
            if (e.Popped)
            {
                if (time > e.TimePopped + respawnTime)
                {
                    e.Popped  = false;
                    blorbs[i] = e;
                }
            }
            else
            {
                float normalizedBloat = (e.Bloat / maxBloatBeforePop);
                if (normalizedBloat >= 1)
                {
                    e.Popped       = true;
                    e.TimePopped   = time;
                    timeLastPopped = time;
                    popEvents.Enqueue(e);
                }
            }
        }
    }
Пример #9
0
        /// <summary>
        /// Initializes a new instance of the ZLR engine from a given stream.
        /// The stream must remain open while the engine is in use.
        /// </summary>
        /// <param name="gameStream">A stream containing either a plain Z-code
        /// file or a Blorb file which in turn contains a Z-code resource.</param>
        /// <param name="io"></param>
        public ZMachine(Stream gameStream, IZMachineIO io)
        {
            if (gameStream == null)
                throw new ArgumentNullException("gameStream");
            if (io == null)
                throw new ArgumentNullException("io");

            this.io = io;

            // check for Blorb
            byte[] temp = new byte[12];
            gameStream.Seek(0, SeekOrigin.Begin);
            gameStream.Read(temp, 0, 12);
            if (temp[0] == 'F' && temp[1] == 'O' && temp[2] == 'R' && temp[3] == 'M' &&
                temp[8] == 'I' && temp[9] == 'F' && temp[10] == 'R' && temp[11] == 'S')
            {
                Blorb blorb = new Blorb(gameStream);
                if (blorb.GetStoryType() == "ZCOD")
                    gameStream = blorb.GetStoryStream();
                else
                    throw new ArgumentException("Not a Z-code Blorb");
            }

            this.gameFile = gameStream;

            zmem = new byte[gameStream.Length];
            gameStream.Seek(0, SeekOrigin.Begin);
            gameStream.Read(zmem, 0, (int)gameStream.Length);

            if (zmem.Length < 64)
                throw new ArgumentException("Z-code file is too short: must be at least 64 bytes");

            zversion = zmem[0];

            if (zversion < 1 || zversion > 8)
                throw new ArgumentException("Z-code version must be between 1 and 8");

            io.SizeChanged += new EventHandler(io_SizeChanged);
        }
Пример #10
0
 public void StoryStarted(string StoryName, Blorb BlorbFile)
 {
     Console.WriteLine("Starting " + StoryName);
 }