UPF/Assets/Game/Scripts/TradeMenu.cs

268 lines
8.7 KiB
C#

using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;
using TMPro;
public class TradeMenu : MonoBehaviour
{
public Transform tradeListParent;
public GameObject tradeListItem;
public Button refreshIndicator;
public TMP_Text coinsTxt;
public TMP_Text gemsTxt;
public List<GameObject> pooledEntries;
public List<TradeRequest> trades;
[Header("Selected Trade Data")]
public TradeRequest selectedTrade = null;
public TMP_Text sellerNameTxt;
public GameObject coinsItem;
public GameObject gemsItem;
public GameObject metalsItem;
public GameObject oxygenItem;
public Image itemImg;
public Sprite defaultFrame;
public Sprite mineFrame;
public Button acceptBtn;
void Start()
{
pooledEntries = new List<GameObject>();
//pooledEntries.Add(tradeListItem);
refreshIndicator.onClick.AddListener(Refresh);
acceptBtn.onClick.AddListener(OnAcceptClicked);
Refresh();
}
// Update is called once per frame
void Update()
{
}
public bool refreshing = false;
public async void Refresh()
{
refreshing = true;
refreshIndicator.interactable=false;
refreshIndicator.GetComponent<Rotator>().enabled = (true);
//Clean existing entries
foreach (GameObject entry in pooledEntries) { entry.SetActive(false); }
coinsTxt.text = DBmanager.Coins.ToString();
gemsTxt.text = DBmanager.Gems.ToString();
selectedTrade = null;
// if(selectedTrade==null){
coinsItem.SetActive(false);
gemsItem.SetActive(false);
metalsItem.SetActive(false);
oxygenItem.SetActive(false);
acceptBtn.interactable = false;
itemImg.sprite = null;
//}
using (UnityWebRequest www = UnityWebRequest.Get(DBmanager.phpRoot + "get_trades.php"))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text.ToLower().Contains("0 results"))
{
Debug.Log("No trade requests for now");
}
else
{
string[] splitChars = { "<td>" };
string[] data = www.downloadHandler.text.Split(splitChars, System.StringSplitOptions.RemoveEmptyEntries);
trades = new List<TradeRequest>();
foreach (string row in data)
{
try
{
TradeRequest trade = JsonConvert.DeserializeObject<TradeRequest>(row);
trades.Add(trade);
if(trade.seller == DBmanager.username){
trades[trades.Count-1] = trades[0];
trades[0] = trade;
}
}
catch
{
}
}
Debug.Log($"Added {trades.Count} trades from {data.Length} entries");
}
}
//Populate Trade Entries in list
//Fill pool if exceeds
int amountToFill = trades.Count - pooledEntries.Count;
if (amountToFill > 0)
{
for (int i = 0; i < amountToFill; i++)
{
GameObject newEntry = Instantiate(tradeListItem, tradeListParent);
newEntry.SetActive(false);
pooledEntries.Add(newEntry);
}
}
if(trades.Count > pooledEntries.Count){Debug.LogError("Somethings wrong, I can feel it");}
//Set pooled items
for (int i = 0; i < trades.Count; i++)
{
TradeRequest trade = trades[i];
InventoryItem item = Inventory.GetInventoryItem(trade.item);
if (item == null) { Debug.LogError("Couldn't find any inventory item for " + trade.item); continue; }
pooledEntries[i].SetActive(true);
pooledEntries[i].transform.GetChild(0).GetComponent<Image>().sprite = item.image;
pooledEntries[i].GetComponentInChildren<TMPro.TMP_Text>().text = trade.item;
pooledEntries[i].GetComponent<Button>().onClick.RemoveAllListeners();
pooledEntries[i].GetComponent<Button>().onClick.AddListener(() => { SelectTrade(trade.id); });
pooledEntries[i].GetComponent<Image>().sprite = (trade.seller == DBmanager.username) ? mineFrame : defaultFrame;
}
refreshIndicator.interactable=true;
refreshIndicator.GetComponentInChildren<Rotator>(true).enabled=(false);
refreshing = false;
}
public void SelectTrade(TradeRequest trade)
{
SelectTrade(trade.id);
}
public void SelectTrade(int id)
{
selectedTrade = null;
foreach (TradeRequest trade in trades)
{
if (trade.id == id)
{
selectedTrade = trade;
break;
}
}
if (selectedTrade == null) { Debug.Log("No matching trade request"); return; }
bool myTrade = selectedTrade.seller == DBmanager.username;
InventoryItem item = Inventory.GetInventoryItem(selectedTrade.item);
itemImg.sprite = item.image;
#region setResource
if (selectedTrade.coins > 0)
{
coinsItem.SetActive(true);
coinsItem.GetComponentInChildren<TMP_Text>().text = selectedTrade.coins.ToString();
}
else
{
coinsItem.SetActive(false);
}
if (selectedTrade.gems > 0)
{
gemsItem.SetActive(true);
gemsItem.GetComponentInChildren<TMP_Text>().text = selectedTrade.gems.ToString();
}
else
{
gemsItem.SetActive(false);
}
if (selectedTrade.metals > 0)
{
metalsItem.SetActive(true);
metalsItem.GetComponentInChildren<TMP_Text>().text = selectedTrade.metals.ToString();
}
else
{
metalsItem.SetActive(false);
}
if (selectedTrade.oxygen > 0)
{
oxygenItem.SetActive(true);
oxygenItem.GetComponentInChildren<TMP_Text>().text = selectedTrade.oxygen.ToString();
}
else
{
oxygenItem.SetActive(false);
}
#endregion
sellerNameTxt.text = selectedTrade.seller;
acceptBtn.interactable = !myTrade && isTradeAffordable(selectedTrade);
}
public bool isTradeAffordable(TradeRequest trade) => (DBmanager.Coins >= trade.coins) && (DBmanager.Gems >= trade.gems) && (DBmanager.Metal >= trade.metals) && (DBmanager.Trophies >= trade.oxygen);
public void OnAcceptClicked(){
if(selectedTrade==null){Debug.Log("No offer is selected to accept"); return;}
if(selectedTrade.seller == DBmanager.username){Debug.LogError("Cannot accept my own offer, This is illegal"); return;}
if(!isTradeAffordable(selectedTrade)){Debug.Log("Insufficient resources to complete the trade (LC)");return;}
//Good to go
StartCoroutine(acceptOffer(selectedTrade));
}
IEnumerator acceptOffer(TradeRequest trade){
acceptBtn.interactable=false;
WWWForm form = new WWWForm();
form.AddField("name", DBmanager.username);
form.AddField("id", trade.id);
WWW www = new WWW(DBmanager.phpRoot+"accept_trade.php", form);
yield return www;
if(www.text=="0"){
Debug.Log("Trade success");
//change local stuff
DBmanager.SetCoins(DBmanager.Coins - trade.coins,true);
DBmanager.SetGems(DBmanager.Gems - trade.gems,true);
DBmanager.SetTrophies(DBmanager.Trophies - trade.oxygen,true);
DBmanager.SetMetal(DBmanager.Metal - trade.metals, true);
DBmanager.AddInventoryItem(Inventory.GetInventoryItem(trade.item));
Refresh();
}else{
Debug.Log($"I wanted to trade, but server said :{www.text}");
}
acceptBtn.interactable=true;
}
public void Show()
{
gameObject.SetActive(true);
Refresh();
}
public void Close()
{
gameObject.SetActive(false);
}
}
[System.Serializable]
public class TradeRequest
{
public int id;
public string seller;
public string item;
public int coins;
public int gems;
public int metals;
public int oxygen;
}