コード例 #1
0
    // Use this for initialization

    /*
     * void Start () {
     *  //this.currentMaxPrice = this.initialMaxPrice;
     *  //this.currentOffer = this.initialOffer;
     *  if (DataTransfer.shonkyIndex >= 0) {
     *      ItemInstance tmp;
     *      if (ShonkyInventory.Instance.GetItem(DataTransfer.shonkyIndex, out tmp)) {
     *          shonky = tmp;
     *          manager.shonkyInstance = shonky;
     *      }
     *  } else {
     *      Debug.Log("No shonky found, using default value.");
     *      manager.SetBasePrice(150);
     *  }
     *
     *  if (DataTransfer.currentPersonality) {
     *      this.personality = Instantiate(DataTransfer.currentPersonality);
     *      // TODO: messy code.
     *      manager.SetBasePrice((shonky.item as Shonky).basePrice);
     *      this.personality.InfluencePersonality(shonky.quality, (shonky.item as Shonky).basePrice);
     *      LoadPersonality();
     *  } else {
     *      Debug.Log("No personality found, using default values.");
     *      this.personality = Instantiate(this.personality);
     *      this.personality.InfluencePersonality(Quality.QualityGrade.Sturdy, 150);
     *      LoadPersonality();
     *  }
     *  }
     */

    // Consider the player's offer and offer a counter.  Returns true if bidding should continue, or false if not.
    // Counter offer is stored in "counter" parameter.  If the counter offer is 0, then the NPC is fed up.
    private bool CounterOffer(float offer, out float counter)
    {
        // Bidding should terminate if the current max price is lower than the amount the NPCs last offer.
        // AKA, bidding has gone on too long.
        if (this.currentMaxPrice < this.currentOffer)
        {
            counter = 0f;
            manager.WizardPunch(1f, 1.2f);
            manager.WizardSpeak(personality.TalkReject(1f));
            return(false);
        }

        //Debug.Log("offer: " + offer);
        // Calculate chance of accepting the players offer.
        float acceptRange  = this.currentMaxPrice - this.wantsItem;
        float acceptRatio  = (offer - this.wantsItem) / acceptRange;
        float acceptLerp   = Mathf.Clamp01(acceptRatio);
        float acceptChance = 1f - this.acceptGradient.Evaluate(acceptLerp);
        //Debug.Log("Evaluated an acceptance chance of: " + acceptChance*100f + "%");

        float rejectRange  = this.absoluteMaxPrice - this.currentMaxPrice;
        float rejectRatio  = (this.absoluteMaxPrice - offer) / rejectRange;
        float rejectLerp   = Mathf.Clamp01(rejectRatio);
        float rejectChance = 1f - this.acceptGradient.Evaluate(rejectLerp);
        //Debug.Log("Evaluated a rejectance chance of: " + rejectChance*100f + "%");


        float rand = Random.value;

        // Chance is kind, we accept the offer.
        if (rand <= acceptChance)
        {
            // TODO: use variables to guide this.
            // TODO: use DenyOffer() or something like that?
            manager.WizardPunch(1.1f - acceptChance, 0.5f);
            manager.WizardSpeak(personality.TalkAccept(acceptChance));
            counter = offer;
            return(false);
        }
        else if (rand <= rejectChance)
        {
            manager.WizardPunch(1 - acceptChance, 1.2f);
            manager.WizardSpeak(personality.TalkReject(rejectChance));
            counter = 0f;
            return(false);
        }
        else
        {
            // Approximate change based on ratio -- not very AI-like.
            float change = (offerMultiplier * acceptRatio);
            // Never exceed player's offer.
            if (this.currentOffer + change > offer)
            {
                change = (this.currentOffer / offer) * (offer - this.currentOffer);
            }

            //Debug.Log("Change (offer increasing by:): " + change);
            this.currentOffer     += change;
            this.currentMaxPrice  -= this.overflowStep;
            this.absoluteMaxPrice -= this.absoluteOverflowStep;

            manager.WizardPunch(change * 0.1f, 1f);
            manager.WizardSpeak(personality.TalkCounter(acceptChance));

            // Shove the slider to give some feedback on the offer.
            //Debug.Log("Should shove the slider back " + (manager.fPrice - this.currentOffer) + " points.");
            manager.MoveSliderBack(manager.fPrice - this.currentOffer);
            counter = this.currentOffer;

            this.acceptButton.interactable = true;
            return(true);
        }
    }