Example #1
0
    /// <summary>
    /// DEBUG: uncomment this to test item drop logic
    /// </summary>

    /*
     * protected void Update()
     * {
     *
     *      if (Input.GetKeyUp(KeyCode.F))
     *              TryDropAmmoClip("Bullet", 19);      // try to drop a clip with 19 bullets
     *
     *      if (Input.GetKeyUp(KeyCode.G))
     *              TryDropWeapon("Pistol", 15);        // try to drop a pistol loaded with 15 bullets
     *
     *      if (Input.GetKeyUp(KeyCode.H))
     *              TryDropWeapon("Machinegun", 35);    // try to drop a machinegun loaded with 35 bullets
     *
     *      if (Input.GetKeyUp(KeyCode.J))
     *              TryDropCurrentWeapon();             // try to drop the currently wielded weapon, with its currently loaded ammo
     *
     *      if (Input.GetKeyUp(KeyCode.K))
     *              transform.root.SendMessage("Die");  // insta kill player (for testing death drop modes)
     *
     * }
     */


    /// <summary>
    /// scans the level and 'Droppables' list for item pickups and prepares hidden
    /// copies for dropping instances at runtime
    /// </summary>
    protected virtual void GenerateItemDrops()
    {
        List <vp_ItemPickup> pickups = new List <vp_ItemPickup>(FindObjectsOfType <vp_ItemPickup>());

        foreach (GameObject o in ExtraPickups)
        {
            if (o == null)
            {
                continue;
            }
            vp_ItemPickup i = (vp_ItemPickup)o.GetComponent <vp_ItemPickup>();
            if (i == null)
            {
                continue;
            }
            pickups.Add(i);
        }

        GameObject g = GameObject.Find("Droppables");

        if (g != null)
        {
            m_DroppablesGroup = g.transform;
        }
        if (m_DroppablesGroup == null)
        {
            m_DroppablesGroup = new GameObject("Droppables").transform;
        }

        foreach (vp_ItemPickup pickup in pickups)
        {
            string name = pickup.ItemTypeObject.name;
            if (pickup.ItemTypeObject is vp_UnitType)
            {
                name += "," + pickup.Amount;
            }

            if (!m_SceneDroppables.ContainsKey(name))
            {
                GameObject c = ClonePickup(name, pickup);
                if (c != null)
                {
                    m_SceneDroppables.Add(name, c);
                    if (!m_SceneItemTypesByName.ContainsKey(pickup.ItemTypeObject.name))
                    {
                        m_SceneItemTypesByName.Add(pickup.ItemTypeObject.name, pickup.ItemTypeObject);
                    }

                    if ((pickup.ItemTypeObject is vp_UnitType) && (!m_AvailableUnitAmounts.Contains(pickup.Amount)))
                    {
                        m_AvailableUnitAmounts.Add(pickup.Amount);
                        m_AvailableUnitAmounts.Sort();
                    }
                }
            }
        }

        StoreAmmoClipTypes();
    }
    /// <summary>
    /// sends RPC to remote machines telling them to reenable a pickup
    /// </summary>
    protected virtual void TransmitPickupRespawn(vp_ItemPickup pickup)
    {
        if (!PhotonNetwork.isMasterClient)
        {
            return;
        }

        //Debug.Log("Picked up: " + pickup + " with ID: " + pickup.ID);

        photonView.RPC("ReceivePickupRespawn", PhotonTargets.Others, pickup.ID);
    }
    /// <summary>
    /// sends RPC to remote machines telling them to hide a certain pickup
    /// and try to give its contents to a certain player
    /// </summary>
    protected virtual void TransmitPickup(vp_ItemPickup pickup, Transform recipient)
    {
        //Debug.Log("TransmitPickup: " + pickup.ID);
        if (!PhotonNetwork.isMasterClient)
        {
            return;
        }

        vp_MPNetworkPlayer player;

        if (!vp_MPNetworkPlayer.Players.TryGetValue(recipient.transform.root, out player))
        {
            return;
        }

        //Debug.Log(pickup + " with ID: " + pickup.ID + " was picked up on Master by player " + player.ID);

        photonView.RPC("ReceivePickup", PhotonTargets.Others, pickup.ID, player.ID);
    }
        /// <summary>
        /// registers a pickup under a position-based ID
        /// </summary>
        protected virtual void RegisterPickup(vp_ItemPickup p)
        {
            // since a single gameobject may have several vp_Pickup components
            // on them, pickups are stored in a dictionary with id keys and
            // pickup list values. (an example of a multi-pickup object is a
            // grenade, which has both a grenade thrower pickup and an ammo
            // pickup on the same object)

            if (!vp_MPPickupManager.Instance.Pickups.ContainsKey(p.ID))
            {
                // if the pickup does not exist, we add a list with a single pickup
                // under the position based ID

                List <vp_ItemPickup> ip = new List <vp_ItemPickup>();
                ip.Add(p);
                vp_MPPickupManager.Instance.Pickups.Add(p.ID, ip);
                vp_Respawner r = p.GetComponent <vp_Respawner>();
                if ((r != null) &&
                    !vp_MPPickupManager.Instance.PickupRespawners.ContainsKey(p.ID))
                {
                    vp_MPPickupManager.Instance.PickupRespawners.Add(p.ID, r);
                    r.m_SpawnMode = vp_Respawner.SpawnMode.SamePosition;
                }
                //else TODO: warn
            }
            else
            {
                // if a pickup already exists with this id, we unpack the list,
                // remove it from the dictionary, add the new pickup and re-add
                // it under the same id

                List <vp_ItemPickup> ip;
                if (vp_MPPickupManager.Instance.Pickups.TryGetValue(p.ID, out ip) && ip != null)
                {
                    vp_MPPickupManager.Instance.Pickups.Remove(p.ID);
                    ip.Add(p);
                    vp_MPPickupManager.Instance.Pickups.Add(p.ID, ip);
                }
            }
            //else TODO: warn
        }
Example #5
0
    /// <summary>
    /// logs all the various ammo pickup types available in the scene (and any
    /// components of this type's 'Droppables' list) by item type and amount.
    /// for more info, see the 'TryDropAllAmmo' comments
    /// </summary>
    protected virtual void StoreAmmoClipTypes()
    {
        foreach (vp_ItemType itemType in m_SceneItemTypesByName.Values)
        {
            if (itemType is vp_UnitType)
            {
                foreach (GameObject o in m_SceneDroppables.Values)
                {
                    if (o == null)
                    {
                        continue;
                    }
                    vp_ItemPickup ip = o.GetComponent <vp_ItemPickup>();
                    if (ip == null)
                    {
                        continue;
                    }
                    if (!(ip.ItemTypeObject is vp_UnitType))
                    {
                        continue;
                    }

                    for (int v = (m_AvailableUnitAmounts.Count - 1); v > -1; v--)
                    {
                        if (m_AvailableUnitAmounts[v] == ip.Amount)
                        {
                            if (!m_AvailableAmmoClips.Contains(new AmmoClipType(ip.ItemTypeObject.name, ip.Amount)))
                            {
                                m_AvailableAmmoClips.Add(new AmmoClipType(ip.ItemTypeObject.name, ip.Amount));
                                //Debug.Log("added AmmoClipType: " + ip.ItemTypeObject.name + ", " + ip.Amount);
                            }
                        }
                    }
                }
            }
        }
    }
 protected override void RegisterPickup(vp_ItemPickup p)
 {
     base.RegisterPickup(p);
 }
	/// <summary>
	/// sends RPC to remote machines telling them to reenable a pickup
	/// </summary>
	protected virtual void TransmitPickupRespawn(vp_ItemPickup pickup)
	{

		if (!PhotonNetwork.isMasterClient)
			return;

		//Debug.Log("Picked up: " + pickup + " with ID: " + pickup.ID);

		photonView.RPC("ReceivePickupRespawn", PhotonTargets.Others, pickup.ID);

	}
	/// <summary>
	/// sends RPC to remote machines telling them to hide a certain pickup
	/// and try to give its contents to a certain player
	/// </summary>
	protected virtual void TransmitPickup(vp_ItemPickup pickup, Transform recipient)
	{

		if (!PhotonNetwork.isMasterClient)
			return;

		vp_MPNetworkPlayer player;
		if (!vp_MPNetworkPlayer.Players.TryGetValue(recipient.transform.root, out player))
			return;

		//Debug.Log(pickup + " with ID: " + pickup.ID + " was picked up on Master by player " + player.ID);

		photonView.RPC("ReceivePickup", PhotonTargets.Others, pickup.ID, player.ID);

	}
	/// <summary>
	/// registers a pickup under a position-based ID
	/// </summary>
	protected virtual void RegisterPickup(vp_ItemPickup p)
	{

		// since a single gameobject may have several vp_Pickup components
		// on them, pickups are stored in a dictionary with id keys and
		// pickup list values. (an example of a multi-pickup object is a
		// grenade, which has both a grenade thrower pickup and an ammo
		// pickup on the same object)

		if (!Pickups.ContainsKey(p.ID))
		{
			// if the pickup does not exist, we add a list with a single pickup
			// under the position based ID

			List<vp_ItemPickup> ip = new List<vp_ItemPickup>();
			ip.Add(p);
			Pickups.Add(p.ID, ip);
			vp_Respawner r = p.GetComponent<vp_Respawner>();
			if ((r != null)
				&& !PickupRespawners.ContainsKey(p.ID))
			{
				PickupRespawners.Add(p.ID, r);
				r.m_SpawnMode = vp_Respawner.SpawnMode.SamePosition;
			}
			//else TODO: warn
		}
		else
		{
			// if a pickup already exists with this id, we unpack the list,
			// remove it from the dictionary, add the new pickup and re-add
			// it under the same id
	
			List<vp_ItemPickup> ip;
			if(Pickups.TryGetValue(p.ID, out ip) && ip != null)
			{
				Pickups.Remove(p.ID);
				ip.Add(p);
				Pickups.Add(p.ID, ip);
			}
		}
		//else TODO: warn


	}
Example #10
0
    /// <summary>
    /// internal method for handling all aspects of dropping any item type.
    /// NOTE: in multiplayer, this only gets run on the master, which in turn
    /// triggers 'MPClientDropItem' on clients
    /// </summary>
    protected virtual bool TryDropItemInternal(vp_ItemType itemType, Vector3 direction, int units = 0, int id = 0)
    {
        //Debug.Log("TryDropItemInternal: " + itemType + ", " + units);

        if (!vp_Gameplay.IsMaster)
        {
            return(false);
        }

        // fetch pickup prefab of the item type
        GameObject prefab = GetPickupPrefab(itemType, units);

        if (prefab == null)
        {
            return(false);
        }

        // try to remove item records or units from the inventory
        if (!TryRemoveItem(itemType, units, id))
        {
            return(false);
        }

        // keep track of the number of item drop attempts for circular distribution and max cap
        UpdateDropCount();

        // abort if we can't drop any more items at once
        if (m_ItemDropsThisFrame >= MaxDrops)
        {
            return(false);
        }


        // spawn a pickup
        GameObject pickup = SpawnPickup(
            prefab,
            transform.position                                  // position of inventory owner
            + (Vector3.up * SpawnHeight)                        // plus a height offset
            + (direction * SpawnDistance)                       // plus a little bit away from body of inventory holder
            );

        if (pickup == null)
        {
            return(false);
        }

        // in the UFPS multiplayer add-on, every pickup must be assigned a unique id on
        // spawn / startup (+ the id feature is reserved for the vp_MPPickupManager system)
        if (vp_Gameplay.IsMultiplayer)
        {
            id = vp_Utility.UniqueID;
        }

        // initialize the pickup with a collision timer, units, id and a toss component
        vp_Toss toss = InitPickup(pickup, units, id);

        if (toss == null)
        {
            Object.Destroy(pickup);
            return(false);
        }

        // item drop success! play drop sound
        TryPlayDropSound();

        // offset direction based on how many items we have thrown this frame, so as
        // to not throw items inside each other
        direction = GetCircleDirection(direction);

        // toss the pickup away from the owner
        // the first 8 items will be tossed to 'm_DestDistance'. after that,
        // 75% of the initial distance will be added every 8 items, causing
        // large amounts of items to be arranged in concentric rings
        float   additionalDistance = (((int)((m_ItemDropsThisFrame - 1) / 8)) * (TossDistance * 0.75f));
        float   targetYaw          = Random.Range(-180, 180);
        Vector3 finalPosition      = toss.Toss(pickup.transform.position, targetYaw, direction, (TossDistance + additionalDistance), !DisableBob, !DisableSpin);

        //Debug.Log("item drops: " + m_ItemDropsThisFrame + ", additional: " + additionalDistance);

        // notify master object
        vp_ItemPickup itemPickup = pickup.GetComponentInChildren <vp_ItemPickup>();

        if (itemPickup != null)
        {
            vp_GlobalEvent <object[]> .Send("TransmitDropItem", new object[] { itemType.name, finalPosition, targetYaw, transform.root, itemPickup.ID, itemPickup.Amount });
        }

        return(true);
    }
Example #11
0
    /// <summary>
    /// creates a deactivated clone template of a pickup object that is
    /// adapted for instantiation and dropping in the scene. templates are
    /// stored in a scene group called 'Droppables'
    /// </summary>
    protected virtual GameObject ClonePickup(string name, vp_ItemPickup i)
    {
        GameObject template = (GameObject)vp_Utility.Instantiate(i.gameObject, Vector3.zero, i.gameObject.transform.rotation);

        template.name = name;

        // if there is a remover on the pickup, override its lifetime
        // if not, add a remover with our own lifetime, even if 0
        vp_Remover rm = template.GetComponent <vp_Remover>();

        if (rm == null)
        {
            rm = template.AddComponent <vp_Remover>();
        }
        rm.LifeTime = ItemLifeTime;

        // if there is a respawner on the pickup and our lifetime is 0,
        // use the max respawn time of the respawner as lifetime.
        // however, kill the respawner afterwards
        // NOTE: this will make dropped pickups be destroyed (or pooled)
        // when picked up, unlike scene pickups that have respawners (which
        // are merely temp-deactivated)
        vp_Respawner rs = template.GetComponent <vp_Respawner>();

        if (rs != null)
        {
            if (ItemLifeTime == 0.0f)
            {
                rm.LifeTime = rs.MaxRespawnTime;
            }
            Object.Destroy(rs);
        }

        // if lifetime is 0 at this point, fallback to 10 secs
        if (rm.LifeTime == 0.0f)
        {
            rm.LifeTime = 10.0f;
        }

        // add 0-2 seconds randomly to lifetime, so clusters of pickups won't
        // pop away exactly at the same time
        vp_MathUtility.SetSeed(i.ID);
        rm.LifeTime += Random.value * 2;

        // disable rigidbodiy and colliders (trigger colliders will be reactivated later)
        Rigidbody rb = template.GetComponent <Rigidbody>();

        if (rb != null)
        {
            rb.isKinematic = true;
        }

        Collider[] cs = template.GetComponents <Collider>();
        foreach (Collider c in cs)
        {
            c.enabled = false;
        }

        // set up item pickup
        vp_ItemPickup ip = template.GetComponent <vp_ItemPickup>();

        if (ip != null)
        {
            ip.ID = 0;
        }
        ip.Amount = i.Amount;

        // disable object and child it to the 'Droppables' group
        vp_Utility.Activate(template, false);
        template.transform.parent = m_DroppablesGroup;

        return(template);
    }