Guest User

Untitled

a guest
Dec 14th, 2019
80
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. using TMPro;
  6. using System.Linq;
  7. using Pixelplacement;
  8.  
  9. public class DrinkData
  10. {
  11. public int icecubes = 0;
  12. public Color color;
  13. }
  14.  
  15. public class Customer : MonoBehaviour
  16. {
  17. public DrinkData drink;
  18. public List<Order> potentialOrders;
  19. public AudioClip screamClip;
  20. public AudioClip victoryClip;
  21. public float currentPatience = 0f;
  22. public float basePatience = 10f;
  23. public GameObject receiverPrefab;
  24. public Transform lineForward;
  25. public NavMeshAgent agent;
  26. public Vector3 currentPosition;
  27. public int numberOfPizza = 2;
  28. public PizzaData pizzaOrder;
  29. public Transform patienceBar;
  30. MeshRenderer patienceBarRenderer;
  31. public Transform exitPosition;
  32. public NavMeshObstacle obstacle;
  33. public GameObject ratingPrefab;
  34. public Transform counterHeight;
  35. public Animator animator;
  36.  
  37. public Transform bodyModels;
  38. public void InitCustomerData(CustomerData customerData)
  39. {
  40. // print(customerData.basePatience);
  41. potentialOrders = customerData.potentialOrders;
  42. basePatience = customerData.basePatience;
  43. }
  44. // Start is called before the first frame update
  45. void Start()
  46. {
  47. Transform bodyModel = bodyModels.GetChild(Random.Range(0, bodyModels.childCount));
  48. bodyModel.gameObject.SetActive(true);
  49. animator = bodyModel.GetComponent<Animator>();
  50. counterHeight = GameObject.FindWithTag("CounterHeight").transform;
  51. obstacle = GetComponent<NavMeshObstacle>();
  52. exitPosition = GameObject.FindWithTag("ExitPosition").transform;
  53. patienceBarRenderer = patienceBar.GetComponent<MeshRenderer>();
  54. patienceBarRenderer.material.EnableKeyword("_EMISSION");
  55. //basePatience -= UniversalData.gameManager.day * UniversalData.gameManager.patienceDecreaseRate;
  56. currentPatience = basePatience;
  57. lineForward = GameObject.FindWithTag("LineForward").transform;
  58. agent = GetComponent<NavMeshAgent>();
  59. UniversalData.lineManager.FindPosition(this);
  60. DecideOrder();
  61. }
  62.  
  63. Dictionary<string, int> AggregateOrder(List<string> order)
  64. {
  65. Dictionary<string, int> aggregatedOrder = new Dictionary<string, int>();
  66. foreach (string topping in order)
  67. {
  68. if (aggregatedOrder.ContainsKey(topping))
  69. {
  70. aggregatedOrder[topping]++;
  71. }
  72. else
  73. {
  74. aggregatedOrder[topping] = 1;
  75. }
  76. }
  77. return aggregatedOrder;
  78. }
  79. protected bool pathComplete()
  80. {
  81. if (Vector3.Distance(agent.destination, agent.transform.position) <= agent.stoppingDistance)
  82. {
  83. if (!agent.hasPath || agent.velocity.sqrMagnitude == 0f)
  84. {
  85. return true;
  86. }
  87. }
  88.  
  89. return false;
  90. }
  91. public void MoveTo(Vector3 pos)
  92. {
  93. reachedDestination = false;
  94. agent.SetDestination(pos);
  95. currentPosition = pos;
  96. fullyInLine = false;
  97. }
  98.  
  99. List<int> Shuffle(List<int> list)
  100. {
  101. int listCount = list.Count;
  102. //print(listCount);
  103. List<int> newList = new List<int>();
  104. for (int i = 0; i < listCount; i++)
  105. {
  106. int index = Random.Range(0, list.Count);
  107. newList.Add(list[index]);
  108. list.RemoveAt(index);
  109. }
  110. return newList;
  111. }
  112.  
  113. public DrinkData DecideDrink()
  114. {
  115. DrinkData drinkData;
  116. drinkData = new DrinkData();
  117. drinkData.icecubes = Random.Range(1, 5);
  118. drinkData.color = UniversalData.drinkData[Random.Range(0, UniversalData.drinkData.Count)].color;
  119. return drinkData;
  120. }
  121. public void DecideOrder()
  122. {
  123. PizzaData order;
  124. List<Order> orderDistribution = new List<Order>();
  125. foreach (Order potentialOrder in potentialOrders)
  126. {
  127. for (int i = 0; i < potentialOrder.weight; i++)
  128. {
  129. orderDistribution.Add(potentialOrder);
  130. }
  131. }
  132. order = ScriptableObject.CreateInstance<PizzaData>();
  133. Order orderData = orderDistribution[Random.Range(0, orderDistribution.Count)];
  134. if (orderData.hasCheese)
  135. {
  136. order.toppings.Add("Cheese");
  137. }
  138. if (orderData.hasTomato)
  139. {
  140. order.toppings.Add("Tomato");
  141. }
  142. foreach (IngredientData topping in orderData.toppings)
  143. {
  144. int quantity = Random.Range(topping.minQuantity, topping.maxQuantity);
  145. for (int i = 0; i < quantity; i++)
  146. {
  147. order.toppings.Add(topping.name);
  148. }
  149.  
  150. }
  151. pizzaOrder = order;
  152. if (orderData.hasDrink)
  153. {
  154. drink = DecideDrink();
  155. }
  156. else
  157. {
  158. drink = null;
  159. }
  160. }
  161. public GameObject currentReceiver;
  162. IEnumerator Leave()
  163. {
  164. print("Leave");
  165. if (currentReceiver != null)
  166. {
  167. Destroy(currentReceiver.transform.gameObject);
  168. }
  169. print("leave");
  170. pizzaOrderBubble.gameObject.SetActive(false);
  171. drinkBubble.gameObject.SetActive(false);
  172. expressionBubbleTemplate.SetActive(false);
  173. MoveTo(exitPosition.position);
  174. yield return new WaitForSeconds(1f);
  175. UniversalData.lineManager.Remove(this);
  176. }
  177.  
  178. float CheckSimilarity(List<string> pizzaToppings, List<string> orderToppings)
  179. {
  180. int current = 0;
  181. int total = 0;
  182. float similarity = 1f;
  183. foreach (string topping in pizzaToppings)
  184. {
  185. print("i: " + topping);
  186. }
  187. Dictionary<string, int> aggregatedPizzaData = AggregateOrder(pizzaToppings);
  188. Dictionary<string, int> aggregatedOrderData = AggregateOrder(orderToppings);
  189. List<string> keys = new List<string>(aggregatedOrderData.Keys);
  190. foreach (string key in keys)
  191. {
  192. total += aggregatedOrderData[key];
  193. current += aggregatedOrderData[key];
  194. int difference = 0;
  195. if (aggregatedPizzaData.ContainsKey(key))
  196. {
  197. difference = Mathf.Abs(aggregatedPizzaData[key] - aggregatedOrderData[key]);
  198. }
  199. else
  200. {
  201. difference = aggregatedOrderData[key];
  202. }
  203. current -= difference;
  204. }
  205. if (current < 0)
  206. {
  207. current = 0;
  208. }
  209. print("total: " + total + "current: " + current);
  210. similarity = (float)current / (float)total;
  211. return similarity;
  212. }
  213. public float moneyConstant = 2.5f;
  214. public float repPatienceConstant = 1f;
  215. public float repSimilarityConstant = 2.5f;
  216.  
  217. public Transform pizzaOrderBubble;
  218. public GameObject drinkExpressionBubbleTemplate;
  219. public GameObject expressionBubbleTemplate;
  220. public Transform drinkBubble;
  221.  
  222. public void ReceiveDrink(DrinkType drinkType, int cubes)
  223. {
  224. float similarity = 0f;
  225. if (drinkType.color == drink.color)
  226. {
  227. similarity = cubes / drink.icecubes;
  228. }
  229. drink = null;
  230. float reputation = 0f;
  231. float money = similarity * moneyConstant + similarity * moneyConstant * currentPatience / basePatience;
  232. if (similarity == 0f)
  233. {
  234. reputation = -1f;
  235. }
  236. else if (similarity < 0.5f)
  237. {
  238. reputation = 1f;
  239. }
  240. else
  241. {
  242. reputation = 0.25f;
  243. }
  244. // add money
  245. UniversalData.playerManager.AddMoney(money);
  246. UniversalData.playerManager.AddReputation(reputation);
  247. drinkBubble.gameObject.SetActive(false);
  248. drink = null;
  249. CreateExpression(drinkExpressionBubbleTemplate, reputation);
  250. StartCoroutine(ReceiveItemRoutine());
  251. }
  252.  
  253. void CreateLabels(float money, float reputation)
  254. {
  255. var moneyLabel = Instantiate(ratingPrefab);
  256. moneyLabel.transform.position = transform.position + new Vector3(0f, 1f, -0.3f);
  257. moneyLabel.transform.Find("Text").GetComponent<TextMeshPro>().text = "+$" + money;
  258. var repLabel = Instantiate(ratingPrefab);
  259. repLabel.transform.position = transform.position + new Vector3(0f, 0.8f, -0.3f);
  260. repLabel.transform.Find("Text").GetComponent<TextMeshPro>().text = "+R" + reputation;
  261. }
  262.  
  263. void CreateExpression(GameObject expression, float reputation)
  264. {
  265. expression.gameObject.SetActive(true);
  266. expression.transform.localScale = Vector3.zero;
  267.  
  268.  
  269. if (reputation < 0f)
  270. {
  271. animator.SetTrigger("angry");
  272. expression.transform.Find("Sprite").GetComponent<SpriteRenderer>().sprite = UniversalData.expressionIcons["angry"];
  273. }
  274. else
  275. {
  276. UniversalData.soundManager.PlaySound(victoryClip);
  277. animator.SetTrigger("happy");
  278. expression.transform.Find("Sprite").GetComponent<SpriteRenderer>().sprite = UniversalData.expressionIcons["happy"];
  279. }
  280. Tween.LocalScale(expression.transform, new Vector3(0.08001078f, 0.08001078f, 0.08001078f), 0.3f, 0f, Tween.EaseSpring, Tween.LoopType.None);
  281. }
  282. public void ReceiveItem(PizzaData pizzaData)
  283. {
  284.  
  285. float similarity = CheckSimilarity(pizzaData.toppings, new List<string>(pizzaOrder.toppings));
  286.  
  287. bool cooked = false;
  288. if (pizzaData.cookProgress > pizzaOrder.progressNeeded && pizzaData.cookProgress < pizzaOrder.burntProgress)
  289. {
  290. cooked = true;
  291. }
  292.  
  293. // similarity
  294. //
  295. float money = similarity * moneyConstant + similarity * moneyConstant * currentPatience / basePatience;
  296. //
  297. float reputation = 0f;
  298. if (similarity == 1f && currentPatience / basePatience > 0.7f)
  299. {
  300. reputation = 0.5f;
  301. }
  302. if (!cooked)
  303. {
  304. money = 0f;
  305. reputation = -1f;
  306. }
  307. if (similarity < 0.5f)
  308. {
  309. reputation -= 1f;
  310. }
  311. // bubble
  312. pizzaOrderBubble.gameObject.SetActive(false);
  313. CreateExpression(expressionBubbleTemplate, reputation);
  314.  
  315. CreateLabels(money, reputation);
  316. // add money
  317. UniversalData.playerManager.AddMoney(money);
  318. UniversalData.playerManager.AddReputation(reputation);
  319. pizzaOrder = null;
  320. StartCoroutine(ReceiveItemRoutine());
  321.  
  322. }
  323.  
  324. IEnumerator ReceiveItemRoutine()
  325. {
  326. yield return new WaitForSeconds(1.5f);
  327. if (pizzaOrder == null)
  328. {
  329. Tween.LocalScale(expressionBubbleTemplate.transform, Vector3.zero, 0.1f, 0f, Tween.EaseLinear, Tween.LoopType.None);
  330. }
  331. else
  332. {
  333. Tween.LocalScale(drinkExpressionBubbleTemplate.transform, Vector3.zero, 0.1f, 0f, Tween.EaseLinear, Tween.LoopType.None);
  334. }
  335. if (pizzaOrder == null && drink == null)
  336. {
  337. StartCoroutine(Leave());
  338. }
  339. }
  340.  
  341. void StatePizza()
  342. {
  343. // rename this
  344. pizzaOrderBubble.gameObject.SetActive(true);
  345. Transform top = pizzaOrderBubble.Find("Top");
  346. Dictionary<string, int> aggregatedOrder = AggregateOrder(pizzaOrder.toppings);
  347. var templatePrefab = pizzaOrderBubble.Find("Template");
  348. templatePrefab.gameObject.SetActive(false);
  349. //1.0633
  350. List<string> keys = new List<string>(aggregatedOrder.Keys);
  351. int i = 0;
  352. foreach (string key in keys)
  353. {
  354. // get icon
  355. Sprite newIcon = UniversalData.materialIcons.FirstOrDefault(x => x.name == key);
  356. int quantity = aggregatedOrder[key];
  357.  
  358. var template = Instantiate(templatePrefab, pizzaOrderBubble.transform);
  359. template.Find("Image").GetComponent<SpriteRenderer>().sprite = newIcon;
  360. template.Find("Quantity").GetComponent<TextMeshPro>().text = "" + quantity;
  361. Transform startPos = pizzaOrderBubble.transform.Find("StartPos");
  362. template.gameObject.SetActive(true);
  363. template.transform.name = key;
  364. template.transform.localPosition = new Vector3(-2.942f, startPos.localPosition.y + 1.51f * i, 0f);
  365. if (i + 1 == keys.Count)
  366. {
  367. top.transform.localPosition = new Vector3(-2.942f, template.transform.localPosition.y + 1.0633f, 0f);
  368. }
  369. i++;
  370. }
  371. pizzaOrderBubble.transform.localScale = new Vector3(0f, 0f, 0f);
  372. Tween.LocalScale(pizzaOrderBubble.transform, new Vector3(0.08001078f, 0.08001078f, 0.08001078f), 0.1f, 0f, Tween.EaseLinear, Tween.LoopType.None);
  373. }
  374. void StateDrink()
  375. {
  376. if (drink == null)
  377. {
  378. return;
  379. }
  380. // rename this
  381. drinkBubble.gameObject.SetActive(true);
  382. Transform top = pizzaOrderBubble.Find("Top");
  383. Dictionary<string, int> aggregatedOrder = AggregateOrder(pizzaOrder.toppings);
  384. drinkBubble.transform.Find("IceCube").Find("Quantity").GetComponent<TextMeshPro>().text = "" + drink.icecubes;
  385. drinkBubble.transform.Find("Drink").Find("Fill").GetComponent<SpriteRenderer>().color = drink.color;
  386. var templatePrefab = pizzaOrderBubble.Find("Template");
  387. templatePrefab.gameObject.SetActive(false);
  388. drinkBubble.transform.localScale = new Vector3(0f, 0f, 0f);
  389. Tween.LocalScale(drinkBubble.transform, new Vector3(0.08001078f, 0.08001078f, 0.08001078f), 0.1f, 0f, Tween.EaseLinear, Tween.LoopType.None);
  390. }
  391. void StateOrder()
  392. {
  393. patienceBar.gameObject.SetActive(false);
  394. firstInLine = true;
  395. var receiver = Instantiate(receiverPrefab);
  396. receiver.transform.position = new Vector3(transform.position.x, counterHeight.transform.position.y, counterHeight.position.z);
  397. receiver.GetComponent<Receiver>().customer = this;
  398. currentReceiver = receiver;
  399. StatePizza();
  400. StateDrink();
  401. }
  402.  
  403. bool fullyInLine = false;
  404. bool reachedDestination = false;
  405. bool lostPatience = false;
  406. bool firstInLine = false;
  407. // Update is called once per frame
  408. void Update()
  409. {
  410. if (agent.enabled)
  411. {
  412. animator.SetFloat("speed", agent.velocity.magnitude);
  413. }
  414.  
  415.  
  416. if (currentPatience <= 0 && !lostPatience)
  417. {
  418. lostPatience = true;
  419. StartCoroutine(Leave());
  420. }
  421. if (!reachedDestination && currentPosition != null && currentPosition != Vector3.zero)
  422. {
  423. if (pathComplete())
  424. {
  425. reachedDestination = true;
  426. }
  427. }
  428. if (reachedDestination)
  429. {
  430. transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.LookRotation(lineForward.forward), Time.deltaTime * 5f);
  431. }
  432. if (reachedDestination && !fullyInLine && Vector3.Dot(transform.forward, lineForward.forward) >= 0.99f)
  433. {
  434. // we've faced the right position
  435. fullyInLine = true;
  436. if (UniversalData.lineManager.IsFirstInLine(this))
  437. {
  438. StateOrder();
  439. }
  440. else
  441. {
  442. patienceBar.gameObject.SetActive(true);
  443. }
  444. }
  445. if (fullyInLine && firstInLine)
  446. {
  447. if (currentPatience > 0f)
  448. {
  449. currentPatience -= Time.deltaTime;
  450. }
  451. }
  452.  
  453. Color newColor = Color.Lerp(Color.red, Color.green, currentPatience / basePatience);
  454. //patienceBarRenderer.material.color = newColor;
  455. patienceBarRenderer.material.color = newColor;
  456. patienceBarRenderer.material.SetColor("_EmissionColor", newColor);
  457. }
  458.  
  459. private void OnCollisionEnter(Collision collision)
  460. {
  461. Rigidbody rb = collision.transform.GetComponent<Rigidbody>();
  462. if (rb != null && rb.velocity.magnitude > 0.1f)
  463. {
  464. UniversalData.soundManager.PlaySound(screamClip);
  465. UniversalData.playerManager.AddReputation(-10f);
  466. animator.applyRootMotion = true;
  467. agent.enabled = false;
  468. animator.SetTrigger("fallover");
  469. UniversalData.lineManager.Remove(this);
  470. Destroy(gameObject, 2f);
  471. }
  472. }
  473. }
RAW Paste Data