You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

176 lines
3.2 KiB

  1. #include <stdlib.h>
  2. #include "types.h"
  3. #include "util.h"
  4. #include "Bill.h"
  5. #include "Computer.h"
  6. #include "Game.h"
  7. #include "Horde.h"
  8. #include "Network.h"
  9. #include "UI.h"
  10. static Bill *alive, *strays;
  11. static int counters[HORDE_COUNTER_MAX + 1];
  12. #define MAX_BILLS 100 /* max Bills per level */
  13. #define UNLINK(bill, list) \
  14. do { \
  15. if ((bill)->next != NULL) \
  16. (bill)->next->prev = (bill)->prev; \
  17. if ((bill)->prev != NULL) \
  18. (bill)->prev->next = (bill)->next; \
  19. else if ((bill) == list) \
  20. (list) = (bill)->next; \
  21. (bill)->prev = NULL; \
  22. (bill)->next = NULL; \
  23. } while (0)
  24. #define PREPEND(bill, list) \
  25. do { \
  26. (bill)->next = (list); \
  27. if ((list) != NULL) \
  28. (list)->prev = (bill); \
  29. (list) = (bill); \
  30. } while (0)
  31. static int
  32. on(unsigned int lev) {
  33. int perlevel = (int)((8 + 3 * lev) * Game_scale(2));
  34. return MIN(perlevel, MAX_BILLS);
  35. }
  36. static int
  37. max_at_once(unsigned int lev) {
  38. return MIN(2 + lev / 4, 12);
  39. }
  40. static int
  41. between(unsigned int lev) {
  42. return MAX(14 - lev / 3, 10);
  43. }
  44. /* Launches Bills whenever called */
  45. static void
  46. launch(int max) {
  47. Bill *bill;
  48. int n;
  49. int off_screen = counters[HORDE_COUNTER_OFF];
  50. if (max == 0 || off_screen == 0)
  51. return;
  52. n = RAND(1, MIN(max, off_screen));
  53. for (; n > 0; n--) {
  54. Bill_enter(&bill);
  55. PREPEND(bill, alive);
  56. }
  57. }
  58. void
  59. Horde_setup() {
  60. Bill *bill;
  61. while (alive != NULL) {
  62. bill = alive;
  63. UNLINK(bill, alive);
  64. free(bill);
  65. }
  66. while (strays != NULL) {
  67. bill = strays;
  68. UNLINK(bill, strays);
  69. free(bill);
  70. }
  71. counters[HORDE_COUNTER_OFF] = on(Game_level());
  72. counters[HORDE_COUNTER_ON] = 0;
  73. }
  74. void
  75. Horde_update(int iteration) {
  76. Bill *bill, *next;
  77. int level = Game_level();
  78. if (iteration % between(level) == 0)
  79. launch(max_at_once(level));
  80. for (bill = alive; bill != NULL; bill = next) {
  81. next = bill->next;
  82. Bill_update(bill);
  83. }
  84. }
  85. void
  86. Horde_draw() {
  87. Bill *bill;
  88. for (bill = strays; bill != NULL; bill = bill->next)
  89. Bill_draw(bill);
  90. for (bill = alive; bill != NULL; bill = bill->next)
  91. Bill_draw(bill);
  92. }
  93. void
  94. Horde_move_bill(Bill *bill) {
  95. UNLINK(bill, alive);
  96. PREPEND(bill, strays);
  97. }
  98. void
  99. Horde_remove_bill(Bill *bill) {
  100. if (bill->state == BILL_STATE_STRAY)
  101. UNLINK(bill, strays);
  102. else
  103. UNLINK(bill, alive);
  104. Network_clear_stray(bill);
  105. free(bill);
  106. }
  107. void
  108. Horde_add_bill(Bill *bill) {
  109. if (bill->state == BILL_STATE_STRAY)
  110. PREPEND(bill, strays);
  111. else
  112. PREPEND(bill, alive);
  113. }
  114. Bill *
  115. Horde_clicked_stray(int x, int y) {
  116. Bill *bill;
  117. for (bill = strays; bill != NULL; bill = bill->next) {
  118. if (!Bill_clickedstray(bill, x, y))
  119. continue;
  120. UNLINK(bill, strays);
  121. return bill;
  122. }
  123. return NULL;
  124. }
  125. int
  126. Horde_process_click(int x, int y) {
  127. Bill *bill;
  128. int counter = 0;
  129. for (bill = alive; bill != NULL; bill = bill->next) {
  130. if (bill->state == BILL_STATE_DYING ||
  131. !Bill_clicked(bill, x, y))
  132. continue;
  133. if (bill->state == BILL_STATE_AT) {
  134. Computer *comp;
  135. comp = Network_get_computer(bill->target_c);
  136. comp->busy = 0;
  137. comp->stray = bill;
  138. }
  139. Bill_set_dying(bill);
  140. counter++;
  141. }
  142. return counter;
  143. }
  144. void
  145. Horde_inc_counter(int counter, int val) {
  146. counters[counter] += val;
  147. }
  148. int
  149. Horde_get_counter(int counter) {
  150. return counters[counter];
  151. }