dontgetangry.txt 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. rankingtable = "dgaranks";
  2. gamename = "§cDontGetAngry";
  3. game_short = "dga";
  4. game_tab = "§cDGA";
  5. minigame.setSpecificLobbyHandling(true);
  6. minigame.setIndivStartCheck(true);
  7. air_mat = material.getAir();
  8. player_team = map.new(); //player_uuid -> team
  9. team_player = map.new(); //team -> player_uuid
  10. active_teams = list.new(); //to see which team is next in row
  11. token_no_possible_move = set.new(); //to count the amount of tokens with no possible move. if the sum is 4, it's the next players turn
  12. rule_jump_over_tokens_in_target = false;
  13. amount_ai_players = 0;
  14. resetRuleSigns();
  15. minigame.initStart();
  16. goto("simplelobby");
  17. @specificLobbyHandling
  18. if(event == "block_click") {
  19. if(block.getLocation(block) == rule_1_loc) {
  20. rule_jump_over_tokens_in_target = !rule_jump_over_tokens_in_target;
  21. if(rule_jump_over_tokens_in_target) {
  22. s = "§aTrue";
  23. } else {
  24. s = "§cFalse";
  25. }
  26. sign.setString(block, "FRONT", 3, s);
  27. return;
  28. }
  29. if(block.getLocation(block) == rule_2_loc) {
  30. amount_ai_players++;
  31. if(amount_ai_players >= minigame.getMaxPlayers()) {
  32. amount_ai_players = 0;
  33. }
  34. sign.setString(block, "FRONT", 3, string.number(amount_ai_players));
  35. if(!minigame.isStarting()) {
  36. goto("startcountdown");
  37. }
  38. }
  39. }
  40. return;
  41. function minigame.canStartIndiv() {
  42. player_list = minigame.getPlayers($script_id);
  43. p_amount = list.getSize(player_list) + $amount_ai_players;
  44. return p_amount >= minigame.getMinPlayers();
  45. }
  46. function getNextFreeTeamIndex() {
  47. for(i = 0; i < minigame.getMaxPlayers(); i++) {
  48. if(!list.contains($active_teams, i)) {
  49. return i;
  50. }
  51. }
  52. }
  53. @finalstart
  54. player_list = minigame.getPlayers(script_id);
  55. minigame.speakAll(gamename, "The game has started.");
  56. resetGameField();
  57. dice_item = read.item("{Count:1b,id:'minecraft:player_head',tag:{SkullOwner:{Id:[I;-635467755,-1356247480,-1843761069,-673139483],Properties:{textures:[{Signature:'ZVj07KMc/Ia0e34lkmfkiih1dUvgS+tfO3ciWhHv6rVOnVfeKkasYKSMi3He6kgF/q+wn7ksdvelHfjictleX8XSrAtFHPuVhZPEbJtku2w+RKHWnhkP1wnMLZZugKu44cct8nPl5StQ+UHl1IxQ9cFndC6qOhyLsW5zrySgDtyw6qacB4uNqoXCHyMxXlXntkgFCPv98CjB1GAHWvg7f+qIDbTYfZzinpePJvA1cxqX9bsO1tVkmecg9MW4HdNhptbL9UyrnON3o5hIBxNTyZ2bAqfGuuneTzMCgHbfBNS6EYXidMpBAem22nf8j16P6j1NBJV/UtekAL30BF9sdcJqEcosQZRIZ9z5S9RGQqBVr7YcWbPgJHAZDUroPeXIsJo0hyWg/5X6R1oeSgazaav/KxE/rduABhdXWp9bvJpcvUY4ivJ1m4tNggSGWX9SzYTIFhovnPFvBIGIjP3naPGUrcZc6sJuJYXT3ZLvpn+WnEQs19LMQOpmBTkeN9H5/SzZTm3PgfkZIhvWuX++Hj7wDn0FEya1dZBJgbcKQTCA6WUw0ymYdMwz86Ceau8Qo+2uxY00DFXlu9q5juybgAVU9K590Rzn3GRGF2x19jSt/uMxbrbuDUvKjATBgaAoS27iVCgEuQOcn7I9SuulL8xmhMLxDJrJZGvflF70zig=',Value:'eyJ0aW1lc3RhbXAiOjE1MTE0Njc0NDEzOTEsInByb2ZpbGVJZCI6ImRhMWY4ODE1YWYyOTRlNDg5MjFhNzA1M2Q3ZTBiNGU1IiwicHJvZmlsZU5hbWUiOiJBekJhbmRpdDIwMDAiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzFmYTk2MDUwYTQ4M2JiODhhMWVkYmVhZDRkOWMxZGIzMWY3NTY3YjA3NjVkZTQ3ODk3YzU3MjI5MmZkZDcxYjEifX19'}]}}}}");
  58. amount_players = list.getSize(player_list);
  59. for(i = 0; i < amount_players; i++) {
  60. //prepare players
  61. p = player.get(list.getIndex(player_list, i));
  62. entity.teleport(p, map.get($tploc, i));
  63. player.setFly(p, true);
  64. player.giveItem(p, dice_item);
  65. //assign team
  66. if(i == 1 && amount_players == 2) {
  67. i = math.round(minigame.getMaxPlayers() / 2);
  68. }
  69. p_uuid = player.getUuid(p);
  70. map.add(player_team, p_uuid, i);
  71. map.add(team_player, i, p_uuid);
  72. list.add(active_teams, i);
  73. color = map.get(colorcode, i);
  74. minigame.setTabName(p, game_tab, color);
  75. }
  76. if(amount_players + amount_ai_players > minigame.getMaxPlayers()) {
  77. amount_ai_players = minigame.getMaxPlayers() - amount_players;
  78. }
  79. for(h = 0; h < amount_ai_players; h++) {
  80. //assign team
  81. if(amount_players == 1 && amount_ai_players == 1) {
  82. team = math.round(minigame.getMaxPlayers() / 2);
  83. } else {
  84. team = getNextFreeTeamIndex();
  85. }
  86. map.add(team_player, team, "AI");
  87. list.add(active_teams, team);
  88. }
  89. list.sort(active_teams);
  90. /* There are two phases.
  91. Phase 0: player needs to roll the dice
  92. Phase 1: player needs to move a token
  93. */
  94. setNextTeam(false);
  95. @wait
  96. wait();
  97. if(event == "entity_damage") {
  98. if(!isPlayer(entity)) {
  99. goto("wait");
  100. }
  101. player = entity;
  102. }
  103. if(player.hasMinigameId(player, script_id)) {
  104. ignoreGoto(event);
  105. }
  106. goto("wait");
  107. @block_click
  108. if(slot.isOffHand(hand)) {
  109. goto("wait");
  110. }
  111. team = getTeamFromPlayer(player);
  112. if(action == "RIGHT_CLICK_BLOCK") {
  113. if(!isNextTeam(player)) {
  114. msgTeam(team, "It's not your turn.");
  115. goto("wait");
  116. }
  117. block_loc = block.getLocation(block);
  118. //Phase 0
  119. item = living.getHand(player);
  120. own_mat = getTokenMat(team);
  121. if((block_loc == dice_loc || item.isType(item, "PLAYER_HEAD")) && block.getType(block) != own_mat) {
  122. if(phase != 0) {
  123. msgTeam(team, "Already diced. Move a token.");
  124. goto("wait");
  125. }
  126. rollDice(team);
  127. goto("wait");
  128. }
  129. //Phase 1
  130. if(phase != 1) {
  131. msgTeam(team, "Roll the dice first. Then choose a token to move.");
  132. goto("wait");
  133. }
  134. if(!isOwnToken(team, block)) {
  135. msgTeam(team, "Choose one of your tokens to move.");
  136. goto("wait");
  137. }
  138. tokens_in_stable = getTokensInOwnStable(team);
  139. if(isOwnStartBlockedByOwnToken(team) && tokens_in_stable > 0) {
  140. start_block = getOwnStartBlock(team);
  141. if(block_loc != block.getLocation(start_block)) {
  142. msgTeam(team, "You need to move with your token at the start block.");
  143. goto("wait");
  144. }
  145. }
  146. if(isTokenInOwnStable(block_loc, team)) {
  147. if(diced_dots != 6) {
  148. msgTeam(team, "You need a 6 to move a token out of the stable.");
  149. goto("wait");
  150. }
  151. to_block = getOwnStartBlock(team);
  152. doMove(team, block, to_block);
  153. goto("wait");
  154. }
  155. if(isTokenInOwnTarget(block_loc, team)) {
  156. to_block = getTargetBlockStartingInTarget(team, block);
  157. goto("checkmove");
  158. }
  159. //token on route is clicked
  160. if(diced_dots == 6) {
  161. if(tokens_in_stable > 0 && !isOwnStartBlockedByOwnToken(team)) {
  162. msgTeam(team, "You diced 6. Choose a token from the stable.");
  163. goto("wait");
  164. }
  165. }
  166. to_block = getTargetBlockStartingOnRoute(team, block);
  167. goto("checkmove");
  168. }
  169. if(action == "RIGHT_CLICK_AIR") {
  170. item = living.getHand(player);
  171. if(item.isType(item, "PLAYER_HEAD")) {
  172. if(!isNextTeam(player)) {
  173. msgTeam(team, "It's not your turn.");
  174. goto("wait");
  175. }
  176. if(phase != 0) {
  177. msgTeam(team, "Already diced. Move a token.");
  178. goto("wait");
  179. }
  180. rollDice(team);
  181. }
  182. goto("wait");
  183. }
  184. goto("wait");
  185. @checkmove
  186. if(to_block != null) {
  187. doMove(team, block, to_block);
  188. goto("wait");
  189. }
  190. set.add(token_no_possible_move, block_loc);
  191. if(getTotalBlockedTokens() != 4) {
  192. msgTeam(team, "Move not possible. Choose another token.");
  193. goto("wait");
  194. }
  195. nomovepossible(team);
  196. goto("wait");
  197. //all 4 tokens cannot do a possible move
  198. function nomovepossible(team) {
  199. team_name = getTeamName(team);
  200. $phase = 0;
  201. if($diced_dots == 6) {
  202. $dice_count--;
  203. minigame.speakAll($gamename, string.concat("No move possible but diced a 6. Dice again ", team_name, "§r."));
  204. if(isTeamAi(team)) {
  205. rollDice(team);
  206. }
  207. return;
  208. }
  209. if($totalblocked == 4) {
  210. minigame.speakAll($gamename, string.concat("No move possible. Dice again ", team_name, "§r."));
  211. if(isTeamAi(team)) {
  212. rollDice(team);
  213. }
  214. return;
  215. }
  216. minigame.speakAll($gamename, string.concat("No move possible. Next player."));
  217. setNextTeam(false);
  218. }
  219. @block_break
  220. @block_place
  221. @entity_damage
  222. cancel = true;
  223. goto("wait");
  224. function isTeamAi(team) {
  225. return getPlayerFromTeam(team) == "AI";
  226. }
  227. function msgTeam(team, message) {
  228. if(isTeamAi(team)) {
  229. return;
  230. }
  231. player = getPlayerFromTeam(team);
  232. msg.prefix(player, $gamename, message);
  233. }
  234. function getTargetBlockStartingOnRoute(team, from_block) {
  235. from_loc = block.getLocation(from_block);
  236. route_index = array.getIndexOf($route, from_loc);
  237. new_route_index = route_index + $diced_dots;
  238. //if target index is passed, follow target route (but don't overjump in target)
  239. if(isTargetIndexPassed(team, route_index, new_route_index)) {
  240. target_index = getOwnTargetIndex(team);
  241. rest_count = $diced_dots - (target_index - route_index);
  242. to_index = rest_count - 1;
  243. if(to_index > 3) {
  244. return null;
  245. }
  246. if(isWayToTargetOverjumped(team, 0, to_index)) {
  247. return null;
  248. }
  249. target_locs = getTargetLocs(team);
  250. target_loc = target_locs[to_index];
  251. } else {
  252. route_size = array.getSize($route);
  253. if(new_route_index >= route_size) {
  254. new_route_index -= route_size;
  255. }
  256. target_loc = $route[new_route_index];
  257. }
  258. target_block = block.get(target_loc);
  259. //check if target is free
  260. if(isBlockOccupiedByOwnToken(target_block, team)) {
  261. return null;
  262. }
  263. return target_block;
  264. }
  265. function getTargetBlockStartingInTarget(team, from_block) {
  266. target_locs = getTargetLocs(team);
  267. from_loc = block.getLocation(from_block);
  268. from_index = array.getIndexOf(target_locs, from_loc);
  269. to_index = from_index + $diced_dots;
  270. if(to_index > 3) {
  271. return null;
  272. }
  273. if(isWayToTargetOverjumped(team, from_index + 1, to_index)) {
  274. return null;
  275. }
  276. target_block = block.get(target_locs[to_index]);
  277. if(isBlockOccupiedByOwnToken(target_block, team)) {
  278. return null;
  279. }
  280. return target_block;
  281. }
  282. function isWayToTargetOverjumped(team, from_index, to_index) {
  283. if(!$rule_jump_over_tokens_in_target) {
  284. return false;
  285. }
  286. target_locs = getTargetLocs(team);
  287. for(i = from_index; i < to_index; i++) {
  288. b = block.get(target_locs[i]);
  289. if(!block.isAir(b)) {
  290. return true;
  291. }
  292. }
  293. return false;
  294. }
  295. function doMove(team, from_block, to_block) {
  296. //if block is occupied, throw token out of game. the condition to check if target is occupied by own token is checked earlier
  297. if(!block.isAir(to_block)) {
  298. token_mat = block.getType(to_block);
  299. opp_team = getTeamFromToken(token_mat);
  300. free_block = getFreeBlockInStable(opp_team);
  301. block.setMaterial(free_block, token_mat);
  302. minigame.speakAll($gamename, string.concat("A token from ", getTeamName(opp_team), " §rteam was thrown."));
  303. }
  304. //do move
  305. block.setMaterial(from_block, $air_mat);
  306. own_mat = getTokenMat(team);
  307. block.setMaterial(to_block, own_mat);
  308. if(isTargetFull(team)) {
  309. list.remove($active_teams, team);
  310. finished(team);
  311. setNextTeam(true);
  312. return;
  313. }
  314. if($diced_dots == 6) {
  315. $phase = 0;
  316. $dice_count = 0;
  317. minigame.speakAll($gamename, string.concat(getTeamName(team), " §rdiced a 6 and can dice again."));
  318. if(isTeamAi(team)) {
  319. rollDice(team);
  320. }
  321. return;
  322. }
  323. setNextTeam(false);
  324. }
  325. function finished(team) {
  326. if($first_finish == null) {
  327. $first_finish = team;
  328. minigame.speakAll($gamename, string.concat(getTeamName(team), " §rhas won."));
  329. }
  330. size = list.getSize($active_teams);
  331. if(size == 1) {
  332. script = script.getFromId($script_id);
  333. for(i = 0; i < list.getSize($player_list); i++) {
  334. p = player.get(list.getIndex($player_list, i));
  335. t = getTeamFromPlayer(p);
  336. if(t == $first_finish) {
  337. showstats(p, true);
  338. } else {
  339. showstats(p, false);
  340. }
  341. player.setFly(p, false);
  342. }
  343. minigame.kickAllPlayers(script);
  344. minigame.term(script, $gamesignloc);
  345. term();
  346. }
  347. }
  348. @player_quit
  349. @player_giveup
  350. team = getTeamFromPlayer(player);
  351. if(first_finish != null && team == first_finish) {
  352. showstats(player, true);
  353. } else {
  354. showstats(player, false);
  355. }
  356. minigame.speakAll(gamename, string.concat(getTeamName(team), " §ehas left the game."));
  357. player.setFly(player, false);
  358. script = script.getFromId(script_id);
  359. minigame.kickPlayer(script, player);
  360. //comment this block out to test the game with AI. start the game, set 2 or more AI players and then leave to run the game quickly through with AI
  361. if(list.getSize(player_list) == 0) {
  362. minigame.term(script, $gamesignloc);
  363. term();
  364. }
  365. //-------
  366. removeTeam(team);
  367. goto("wait");
  368. function removeSpecificToken(team) {
  369. token_mat = getTokenMat(team);
  370. for(i = 0; i < array.getSize($route); i++) {
  371. b = block.get($route[i]);
  372. if(block.getType(b) == token_mat) {
  373. block.setMaterial(b, $air_mat);
  374. }
  375. }
  376. }
  377. function showstats(player, won) { //Player player, Boolean won
  378. player_id = player.getId(player);
  379. last_record = ranking.getPoints($rankingtable, player_id);
  380. team = getTeamFromPlayer(player);
  381. finished_tokens = getTokensInOwnTarget(team);
  382. new_record = last_record + finished_tokens;
  383. ranking.setPoints($rankingtable, player_id, new_record);
  384. won_games = minigame.getWon(player_id, $game_short);
  385. if(won) {
  386. won_games++;
  387. minigame.setWon(player_id, $game_short, won_games);
  388. }
  389. played_games = minigame.getPlayed(player_id, $game_short) + 1;
  390. minigame.setPlayed(player_id, $game_short, played_games);
  391. minigame.statsHeader(player, $gamename, "§e");
  392. minigame.statsLine(player, "§e", "Finished tokens", string.number(new_record));
  393. minigame.statsLine(player, "§e", "Won games", string.number(won_games));
  394. minigame.statsLine(player, "§e", "Played games", string.number(played_games));
  395. if(played_games != 0) {
  396. minigame.statsLine(player, "§e", "Win ratio", string.concat(string.number(math.roundComma((won_games / played_games) * 100, 2)), "%"));
  397. }
  398. }
  399. function getFreeBlockInStable(team) {
  400. stable_locs = getStableLocs(team);
  401. for(i = 0; i < array.getSize(stable_locs); i++) {
  402. b = block.get(stable_locs[i]);
  403. if(block.isAir(b)) {
  404. return b;
  405. }
  406. }
  407. return null;
  408. }
  409. function isTargetIndexPassed(team, from_route_index, to_route_index) {
  410. target_index = getOwnTargetIndex(team);
  411. if(from_route_index > target_index) {
  412. return false;
  413. }
  414. return to_route_index > target_index;
  415. }
  416. function getOwnStartBlock(team) {
  417. index = map.get($startindexes, team);
  418. return block.get($route[index]);
  419. }
  420. function getOwnStartIndex(team) {
  421. return map.get($startindexes, team);
  422. }
  423. function getOwnTargetIndex(team) {
  424. return map.get($targetindexes, team);
  425. }
  426. function isOwnToken(team, block) {
  427. own_mat = getTokenMat(team);
  428. block_mat = block.getType(block);
  429. return own_mat == block_mat;
  430. }
  431. function getStableLocs(team) {
  432. return map.get($stables, team);
  433. }
  434. function getTargetLocs(team) {
  435. return map.get($target_routes, team);
  436. }
  437. function isTargetFull(team) {
  438. target_locs = getTargetLocs(team);
  439. for(i = 0; i < array.getSize(target_locs); i++) {
  440. b = block.get(target_locs[i]);
  441. if(block.isAir(b)) {
  442. return false;
  443. }
  444. }
  445. return true;
  446. }
  447. function isTokenInOwnStable(token_loc, team) {
  448. stable_locs = getStableLocs(team);
  449. return array.contains(stable_locs, token_loc);
  450. }
  451. function isTokenInOwnTarget(token_loc, team) {
  452. target_locs = getTargetLocs(team);
  453. return array.contains(target_locs, token_loc);
  454. }
  455. function getTeamFromToken(token_mat) {
  456. return map.get($tokens_team, token_mat);
  457. }
  458. function getTeamFromPlayer(player) {
  459. return map.get($player_team, player.getUuid(player));
  460. }
  461. function getPlayerFromTeam(team) {
  462. p_uuid = map.get($team_player, team);
  463. if(p_uuid == "AI") {
  464. return p_uuid;
  465. }
  466. return player.get(p_uuid);
  467. }
  468. /* Conzept of active team list
  469. next_team_index: team x
  470. 0: team 0
  471. 1: team 1
  472. 2: team 3
  473. */
  474. function setNextTeam(bool_actual_team_removed) {
  475. $phase = 0;
  476. $dice_count = 0;
  477. amount_active_teams = list.getSize($active_teams);
  478. if($next_team == null) {
  479. //init at start
  480. $next_team_index = math.random(0, amount_active_teams - 1);
  481. $next_team = list.getIndex($active_teams, $next_team_index);
  482. } else {
  483. //set next during game
  484. if(!bool_actual_team_removed) {
  485. $next_team_index++;
  486. }
  487. if($next_team_index >= amount_active_teams) {
  488. $next_team_index = 0;
  489. }
  490. $next_team = list.getIndex($active_teams, $next_team_index);
  491. }
  492. //announce
  493. next_team_name = getTeamName($next_team);
  494. if(string.endsWith(next_team_name, "s")) {
  495. minigame.speakAll($gamename, string.concat("It's ", next_team_name, "' §rturn."));
  496. } else {
  497. minigame.speakAll($gamename, string.concat("It's ", next_team_name, "'s §rturn."));
  498. }
  499. if(isTeamAi($next_team)) {
  500. rollDice($next_team);
  501. return;
  502. }
  503. next_player = getPlayerFromTeam($next_team);
  504. sound.spawnForPlayer(next_player, $pling_sound, $sound_category_ambient);
  505. }
  506. function removeTeam(team) {
  507. list.remove($active_teams, team);
  508. size = list.getSize($active_teams);
  509. if(size == 1) {
  510. last_team = list.getIndex($active_teams, 0);
  511. finished(last_team);
  512. }
  513. removeSpecificToken(team);
  514. if(team == $next_team) {
  515. setNextTeam(true);
  516. }
  517. }
  518. function isNextTeam(player) {
  519. return getTeamFromPlayer(player) == $next_team;
  520. }
  521. function getColorCode(team) {
  522. return map.get($colorcode, team);
  523. }
  524. function resetRuleSigns() {
  525. sign.setString(block.get($rule_1_loc), "FRONT", 3, "§cFalse");
  526. sign.setString(block.get($rule_2_loc), "FRONT", 3, "0");
  527. }
  528. function resetGameField() {
  529. //reset route
  530. for(i = 0; i < array.getSize($route); i++) {
  531. b = block.get($route[i]);
  532. block.setMaterial(b, $air_mat);
  533. }
  534. for(team = 0; team < minigame.getMaxPlayers(); team++) {
  535. //reset target routes
  536. target_locs = getTargetLocs(team);
  537. for(i = 0; i < array.getSize(target_locs); i++) {
  538. b = block.get(target_locs[i]);
  539. block.setMaterial(b, $air_mat);
  540. }
  541. //reset stables
  542. stable_locs = getStableLocs(team);
  543. for(i = 0; i < array.getSize(stable_locs); i++) {
  544. b = block.get(stable_locs[i]);
  545. token = getTokenMat(team);
  546. block.setMaterial(b, token);
  547. }
  548. }
  549. }
  550. function getTeamName(team) {
  551. color = getColorCode(team);
  552. if(isTeamAi(team)) {
  553. return string.concat(color, "AI");
  554. }
  555. p_name = player.getName(getPlayerFromTeam(team));
  556. return string.concat(color, p_name);
  557. }
  558. function rollDice(team) {
  559. tokens_in_stable = getTokensInOwnStable(team);
  560. //if a token is at start block and other tokens are in the stable (there is the need to move with this token), the dice will throw only possible moves
  561. if(isOwnStartBlockedByOwnToken(team) && tokens_in_stable > 0) {
  562. poss_dots = getPossibleDots(team); //e.g. 2,3,5
  563. r = math.random(0, list.getSize(poss_dots) - 1); //e.g. 1
  564. $diced_dots = list.getIndex(poss_dots, r); //e.g. 3
  565. } else {
  566. $diced_dots = math.random(1, 6);
  567. }
  568. $dice_count++;
  569. //announce
  570. team_name = getTeamName(team);
  571. minigame.speakAll($gamename, string.concat(team_name, " §rdiced §c", string.number($diced_dots), "§r."));
  572. if(!isTeamAi(team)) {
  573. player = getPlayerFromTeam(team);
  574. title.send(player, text.new(string.concat("§c", string.number($diced_dots))));
  575. }
  576. //check if with this dice a move is possible
  577. if($diced_dots != 6) {
  578. not_movable_tokens = tokens_in_stable + getFinishedTokensInOwnTarget(team);
  579. if(not_movable_tokens == 4) {
  580. if($dice_count == 3) {
  581. minigame.speakAll($gamename, string.concat("No move possible for 3 times. Next player."));
  582. setNextTeam(false);
  583. return;
  584. }
  585. minigame.speakAll($gamename, string.concat("No move possible. Dice again ", team_name, "§r."));
  586. if(isTeamAi(team)) {
  587. rollDice(team);
  588. }
  589. return;
  590. }
  591. }
  592. $phase = 1;
  593. $totalblocked = recountTotalBlockedTokens(team);
  594. msgTeam(team, "Choose a token to move.");
  595. if(isTeamAi(team)) {
  596. a = calculateAiMove(team);
  597. if(a == null) {
  598. return;
  599. }
  600. doMove(team, a[0], a[1]);
  601. }
  602. }
  603. function calculateAiMove(team) {
  604. a = array.new(2);
  605. //zugzwang from start block
  606. tokens_in_stable = getTokensInOwnStable(team);
  607. if(isOwnStartBlockedByOwnToken(team) && tokens_in_stable > 0) {
  608. a[0] = getOwnStartBlock(team);
  609. a[1] = getTargetBlockStartingOnRoute(team, a[0]);
  610. return a;
  611. }
  612. //zugzwang from stable
  613. if($diced_dots == 6 && tokens_in_stable > 0) {
  614. stable_locs = getStableLocs(team);
  615. for(i = 0; i < array.getSize(stable_locs); i++) {
  616. loc = stable_locs[i];
  617. from_block = block.get(loc);
  618. if(!block.isAir(from_block)) {
  619. a[0] = from_block;
  620. a[1] = getOwnStartBlock(team);
  621. return a;
  622. }
  623. }
  624. }
  625. //throw other tokens if possible
  626. token_locs = getOwnTokenLocsOnRoute(team);
  627. for(i = 0; i < list.getSize(token_locs); i++) {
  628. from_block = block.get(list.getIndex(token_locs, i));
  629. target_block = getTargetBlockStartingOnRoute(team, from_block);
  630. if(target_block != null) {
  631. if(!block.isAir(target_block) && !isOwnToken(team, target_block)) {
  632. a[0] = from_block;
  633. a[1] = target_block;
  634. return a;
  635. }
  636. }
  637. }
  638. //do progress in target if possible
  639. target_locs = getTargetLocs(team);
  640. for(i = array.getSize(target_locs) - 1; i > -1; i--) {
  641. from_block = block.get(target_locs[i]);
  642. if(!block.isAir(from_block)) {
  643. target_block = getTargetBlockStartingInTarget(team, from_block);
  644. if(target_block != null) {
  645. a[0] = from_block;
  646. a[1] = target_block;
  647. return a;
  648. }
  649. }
  650. }
  651. //choose token with most progress on route
  652. for(i = list.getSize(token_locs) - 1; i > -1; i--) {
  653. from_block = block.get(list.getIndex(token_locs, i));
  654. target_block = getTargetBlockStartingOnRoute(team, from_block);
  655. if(target_block != null) {
  656. a[0] = from_block;
  657. a[1] = target_block;
  658. return a;
  659. }
  660. }
  661. nomovepossible(team);
  662. return null;
  663. }
  664. //sorted by progress ascending
  665. function getOwnTokenLocsOnRoute(team) {
  666. token_locs = list.new();
  667. start_index = getOwnStartIndex(team);
  668. target_index = getOwnTargetIndex(team);
  669. own_mat = getTokenMat(team);
  670. route_size = array.getSize($route);
  671. for(i = 0; i < route_size; i++) {
  672. route_index = start_index + i;
  673. if(route_index >= route_size) {
  674. route_index -= route_size;
  675. }
  676. loc = $route[route_index];
  677. b = block.get(loc);
  678. if(block.getType(b) == own_mat) {
  679. list.add(token_locs, loc);
  680. }
  681. }
  682. return token_locs;
  683. }
  684. function getPossibleDots(team) {
  685. poss_dots = list.new();
  686. own_mat = getTokenMat(team);
  687. s_index = getOwnStartIndex(team);
  688. for(i = 1; i < 7; i++) {
  689. b = block.get($route[s_index + i]);
  690. if(block.getType(b) != own_mat) {
  691. list.add(poss_dots, i);
  692. }
  693. }
  694. return poss_dots;
  695. }
  696. function recountTotalBlockedTokens(team) {
  697. //clear
  698. set.clear($token_no_possible_move);
  699. //stable
  700. if($diced_dots != 6) {
  701. stable_locs = getStableLocs(team);
  702. for(i = 0; i < array.getSize(stable_locs); i++) {
  703. loc = stable_locs[i];
  704. b = block.get(loc);
  705. if(!block.isAir(b)) {
  706. set.add($token_no_possible_move, loc);
  707. }
  708. }
  709. }
  710. //target
  711. target_locs = getTargetLocs(team);
  712. for(i = array.getSize(target_locs) - 1; i > -1; i--) {
  713. loc = target_locs[i];
  714. b = block.get(loc);
  715. if(!block.isAir(b)) {
  716. set.add($token_no_possible_move, loc);
  717. }
  718. }
  719. return set.getSize($token_no_possible_move);
  720. }
  721. function getTotalBlockedTokens() {
  722. return set.getSize($token_no_possible_move);
  723. }
  724. function getTokenMat(team) {
  725. return map.get($tokens, team);
  726. }
  727. function isBlockOccupiedByOwnToken(block, team) {
  728. own_mat = getTokenMat(team);
  729. mat = block.getType(block);
  730. return mat == own_mat;
  731. }
  732. function isOwnStartBlockedByOwnToken(team) {
  733. return isBlockOccupiedByOwnToken(getOwnStartBlock(team), team);
  734. }
  735. function getTokensInOwnTarget(team) {
  736. counter = 0;
  737. target_locs = getTargetLocs(team);
  738. for(i = 0; i < array.getSize(target_locs); i++) {
  739. loc = target_locs[i];
  740. b = block.get(loc);
  741. if(!block.isAir(b)) {
  742. counter++;
  743. }
  744. }
  745. return counter;
  746. }
  747. function getTokensInOwnStable(team) {
  748. counter = 0;
  749. stable_locs = getStableLocs(team);
  750. for(i = 0; i < array.getSize(stable_locs); i++) {
  751. loc = stable_locs[i];
  752. b = block.get(loc);
  753. if(!block.isAir(b)) {
  754. counter++;
  755. }
  756. }
  757. return counter;
  758. }
  759. //a finished token is a token which reached its final position in the stable
  760. function getFinishedTokensInOwnTarget(team) {
  761. counter = 0;
  762. target_locs = getTargetLocs(team);
  763. for(i = array.getSize(target_locs) - 1; i > -1; i--) {
  764. loc = target_locs[i];
  765. b = block.get(loc);
  766. if(block.isAir(b)) {
  767. break;
  768. }
  769. counter++;
  770. }
  771. return counter;
  772. }