Example #1
0
    /// <summary>
    /// Every so often, shoots a shotBlob from itself at closest enemy DestructableObject
    /// </summary>
    /// <param name="thisBlob">The Blob this behavior is attached to.</param>
    public override void Update(Blob thisBlob)
    {
        if (thisBlob.scale.x > shotSize)
        {
            shootTimer--;

            if (shootTimer <= 0)
            {
                //reset shootTimer
                shootTimer = (int)(shootTimeSecs * Level.current.updatesPerSec / magnitude / thisBlob.difficultyModifier);

                SpaceObject target = thisBlob.ClosestObject <SpaceObject>(Level.current.GetTypes(true, true, false, false), false);

                if (target != null)
                {
                    thisBlob.TurnTowards(target);

                    //find where the shotBlob should be shot to hit the target, given their current positions and velocities
                    Vector3 aimAt = SpaceObject.IntersectPosTime(target, shotSpeed, thisBlob.position + new Vector2(0, thisBlob.scale.x * 3).Rotate(thisBlob.angle));

                    //if the taget cannot be hit, just shoot straight at its current position
                    if (aimAt.z < 0)
                    {
                        aimAt = target.position;
                    }

                    //create the shotBlob with an the velocity to hit where it is being aimed at
                    float theAngle = thisBlob.AngleToAbsolute(aimAt);
                    Blob  shotBlob = (Blob)Level.current.CreateObject("BlobPF", thisBlob.position + new Vector2(0, thisBlob.scale.x * 3).Rotate(thisBlob.angle), theAngle,
                                                                      new Vector2(0, shotSpeed).Rotate(theAngle), thisBlob.angularVelocity + magnitude, shotSize);

                    float shotPortion = shotSize / thisBlob.scale.x;
                    float thisPortion = 1 - shotPortion;

                    //make the shotBlob's health, mass and Behaviors proportional to how much of thisBlob is it taking
                    //also decrease thisBlob's behaviors baised on how much the shotBlob took from it
                    shotBlob.mass   = thisBlob.mass * shotPortion;
                    shotBlob.health = thisBlob.health * shotPortion;
                    foreach (BlobBehaviour item in thisBlob.behaviors)
                    {
                        BlobBehaviour temp = item.clone();

                        temp.magnitude *= shotPortion;
                        shotBlob.behaviors.AddFirst(temp);

                        item.magnitude *= thisPortion;
                    }

                    shotBlob.team  = thisBlob.team;
                    shotBlob.color = thisBlob.color;

                    //find the new size of thisBlob baised on how much area the shotBlob took from it
                    float area = (thisBlob.scale.x * thisBlob.scale.x / 4 * Mathf.PI);
                    area -= (shotSize * shotSize / 4 * Mathf.PI);
                    float theScale = Mathf.Sqrt(area * 4 / Mathf.PI);

                    //decrease thisBlob's size, mass and health baised on how much the shotBlob took from it
                    thisBlob.scale      = new Vector2(theScale, theScale);
                    thisBlob.mass      *= thisPortion;
                    thisBlob.health    *= thisPortion;
                    thisBlob.maxHealth -= shotBlob.health;
                }
            }
        }
    }