Advertisement
hugmeir

Untitled

Dec 18th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.56 KB | None | 0 0
  1. // hugmeir's combat script. WIP forever.
  2. import <zlib.ash>
  3.  
  4. boolean [string] mm;
  5. boolean monster_modifiers_may_stop_actions() {
  6. if ( mm["annoying"] || mm["phase-shifting"] || mm["restless"] )
  7. return true;
  8. return false;
  9. }
  10.  
  11. int get_property_int(string prop) {
  12. return get_property(prop).to_int();
  13. }
  14.  
  15. boolean can_use_skill(skill this_skill) {
  16. if ( !have_skill(this_skill) )
  17. return false;
  18.  
  19. if ( !this_skill.is_unrestricted() )
  20. return false;
  21.  
  22. boolean can_use_skill = true;
  23. switch ( this_skill ) {
  24. case $skill[KGB tranquilizer dart]:
  25. if ( get_property_int("_kgbTranquilizerDartUses") >= 3 )
  26. return false;
  27. break;
  28. case $skill[Snokebomb]:
  29. if ( get_property_int("_snokebombUsed") >= 3 )
  30. return false;
  31. break;
  32. case $skill[Shattering Punch]:
  33. if ( get_property_int("_shatteringPunchUsed") >= 3 )
  34. return false;
  35. break;
  36. case $skill[Macrometeorite]:
  37. if ( get_property_int("_macrometeoriteUses") >= 10 )
  38. return false;
  39. break;
  40. }
  41.  
  42. if ( mp_cost(this_skill) > my_mp() )
  43. return false;
  44.  
  45. return true;
  46. }
  47.  
  48. string [int] macro_list;
  49. void push_turnless_macro(string elem) {
  50. int idx = macro_list.count();
  51. macro_list[idx] = elem;
  52. return;
  53. }
  54.  
  55. int rounds_so_far = 0;
  56. void push_action(string elem) {
  57. push_turnless_macro(elem);
  58. rounds_so_far += 1;
  59. return;
  60. }
  61.  
  62. void push_blockable_action(string action) {
  63. push_action(action);
  64. if ( monster_modifiers_may_stop_actions() ) {
  65. string [int] bullshit;
  66. if ( mm["phase-shifting"] )
  67. bullshit[bullshit.count()] = "blinks out of existence";
  68. if ( mm["annoying"] )
  69. bullshit[bullshit.count()] = "stopping you in your tracks";
  70. if ( mm["restless"] )
  71. bullshit[bullshit.count()] = "moves out of the way before you can";
  72. bullshit[bullshit.count()] = "moved by the time you can finish";
  73. if ( mm["cartwheeling"] )
  74. bullshit[bullshit.count()] = "cartwheels out of the way";
  75.  
  76. buffer repeat_macro;
  77. repeat_macro.append("repeat ");
  78. foreach idx, match_string in bullshit {
  79. if ( idx != 0 )
  80. repeat_macro.append(" || ");
  81. repeat_macro.append("match \"" + match_string +"\"");
  82. }
  83.  
  84. push_turnless_macro(repeat_macro.to_string());
  85. }
  86. }
  87.  
  88. string compose_combat_macro() {
  89. buffer result;
  90.  
  91. foreach idx, macro in macro_list {
  92. if ( idx == 0 ) {
  93. result.append(macro);
  94. }
  95. else {
  96. result.append(";");
  97. result.append(macro);
  98. }
  99. }
  100. return result.to_string();
  101. }
  102.  
  103. void push_item_multiuse_if_possible(item this_item) {
  104. int item_amount = this_item.available_amount();
  105. if ( item_amount > 0) {
  106. if ( item_amount == 1 ) {
  107. push_blockable_action("use " + this_item.to_string());
  108. }
  109. else {
  110. push_blockable_action("use " + this_item.to_string() + ", " + this_item.to_string());
  111. }
  112. }
  113. }
  114.  
  115. void push_skill (skill this_skill) {
  116. push_blockable_action("skill " + this_skill.to_string());
  117. }
  118. void push_skill (string skill_as_string) {
  119. push_blockable_action("skill " + skill_as_string);
  120. }
  121.  
  122. void instakill_macro() {
  123. foreach this_item in $items[exploding cigar] {
  124. push_item_multiuse_if_possible(this_item);
  125. }
  126.  
  127. foreach this_skill in $skills[shattering punch, macrometeorite, cleesh] {
  128. if ( can_use_skill( this_skill ) )
  129. push_skill(this_skill);
  130. }
  131.  
  132. push_turnless_macro("abort \"I bring bad news\"");
  133. }
  134.  
  135. void get_stun_macro() {
  136. if ( can_use_skill($skill[noodles of fire]) ) {
  137. push_skill($skill[noodles of fire]);
  138. return;
  139. }
  140.  
  141. switch ( my_class() ) {
  142. case $class[pastamancer]:
  143. push_skill($skill[entangling noodles]);
  144. return;
  145. case $class[seal clubber]:
  146. // todo if club is equipped
  147. if (
  148. $slot[weapon].equipped_item().item_type() == "club"
  149. &&
  150. my_fury() > 1
  151. &&
  152. can_use_skill($skill[club foot])
  153. ) {
  154. push_skill($skill[club foot]);
  155. return;
  156. }
  157. break;
  158. case $class[sauceror]:
  159. if ( my_soulsauce() > 5 && can_use_skill($skill[soul bubble]) ) {
  160. push_skill($skill[soul bubble]);
  161. return;
  162. }
  163. break;
  164. case $class[accordion thief]:
  165. if (
  166. $slot[weapon].equipped_item().item_type() == "accordion"
  167. &&
  168. can_use_skill($skill[accordion bash])
  169. ) {
  170. push_skill($skill[accordion bash]);
  171. return;
  172. }
  173. break;
  174. // TODO TT love.
  175. // case $class[turtle tamer]:
  176. // if hasskill shell up && (haseffect 1422 || haseffect 1423 || haseffect 1424)
  177. // if ( can_use_skill($skill[shell up]) && )
  178. // break;
  179. default:
  180. break;
  181. }
  182.  
  183. if ( can_use_skill($skill[shadow noodles]) ) {
  184. push_skill($skill[shadow noodles]);
  185. return;
  186. }
  187. return;
  188. }
  189.  
  190. void nosy_nose_olfact_macro() {
  191. if ( my_familiar() == $familiar[Nosy Nose] ) {
  192. push_blockable_action("skill 7166");
  193. }
  194. }
  195.  
  196. void micrometeorite_macro () {
  197. push_skill("micrometeorite");
  198. }
  199.  
  200. int _expected_damage(monster foe, stat this_stat) {
  201. int player_stat = my_buffedstat(this_stat);
  202. float attack_type_multiplier = 1.0; // no lunging permed yet
  203. float weapon_type_multiplier = 0.75;
  204.  
  205. int initial_damage = floor(
  206. player_stat * attack_type_multiplier * weapon_type_multiplier
  207. );
  208.  
  209. if ( initial_damage < 0 )
  210. initial_damage = 0;
  211.  
  212. int damage_minus_def = initial_damage - foe.base_defense;
  213.  
  214. // TODO fists?
  215. item weapon = $slot[weapon].equipped_item();
  216. int weapon_damage = weapon.get_power();
  217.  
  218. int crit_multiplier = 1; // eh
  219. int weapon_damage_total = weapon_damage * crit_multiplier * attack_type_multiplier;
  220.  
  221. int bonus_weapon_damage = numeric_modifier("Weapon Damage").to_int();
  222.  
  223. int bonus_prism = numeric_modifier("Prismatic Damage");
  224.  
  225. int total = damage_minus_def + weapon_damage_total + bonus_weapon_damage + bonus_prism;
  226.  
  227. // wiki formula stops at total, but that gives results almost twice
  228. // as high as the actual damage dealt. I probably have one of
  229. // the inputs wrong. In any case, let's just go very conservative
  230. // and just return half of the damage the formula gave us.
  231. return floor(total / 2);
  232. }
  233.  
  234. int expected_ranged_damage(monster foe) {
  235. int ranged_damage = _expected_damage(foe, $stat[moxie]);
  236. int bonus_ranged_damage = numeric_modifier("Ranged Damage").to_int();
  237.  
  238. return ranged_damage + bonus_ranged_damage;
  239. }
  240.  
  241. int expected_weapon_damage(monster foe) {
  242. return _expected_damage(foe, $stat[muscle]);
  243. }
  244.  
  245. void default_fight_macro(monster foe) {
  246. boolean immune_to_physical = false;
  247.  
  248. switch (foe) {
  249. case $monster[mouthless murmur]:
  250. immune_to_physical = true;
  251. break;
  252. default:
  253. immune_to_physical = foe.physical_resistance >= 90;
  254. }
  255.  
  256. push_turnless_macro("while !pastround 26"); // 28 aborts all
  257. if ( mm["untouchable"] || immune_to_physical ) {
  258. // rainbow damage. Or well, this because it's all I got
  259. push_action("skill saucestorm");
  260. }
  261. else {
  262. item equipped_weapon = $slot[weapon].equipped_item();
  263. string equipped_weapon_type = weapon_type(equipped_weapon);
  264. int expected_attack_damage = 0;
  265. if ( equipped_weapon_type == $stat[moxie] ) {
  266. expected_attack_damage = expected_ranged_damage(foe);
  267. }
  268. else if ( equipped_weapon_type == $stat[muscle] ) {
  269. expected_attack_damage = expected_weapon_damage(foe);
  270. }
  271.  
  272. if ( expected_attack_damage > 80 ) {
  273. push_action("attack");
  274. }
  275. else {
  276. push_action("skill saucestorm");
  277. }
  278. if ( $item[gauze garter].available_amount() > 1 ) {
  279. // TODO moar
  280. push_turnless_macro("if hppercentbelow 50 && pastround 10");
  281. push_item_multiuse_if_possible($item[gauze garter]);
  282. push_turnless_macro("endif");
  283. }
  284. }
  285. push_turnless_macro("endwhile");
  286.  
  287. if ( mm["untouchable"] ) {
  288. // Instakill anything that got this far.
  289. instakill_macro();
  290. }
  291. }
  292.  
  293. boolean ticking_and_needs_instakill(monster foe) {
  294. if ( !mm["ticking"] )
  295. return false;
  296.  
  297. if ( mm["frozen"] )
  298. return false;
  299.  
  300. if ( mm["fragile"] && !mm["unlucky"] )
  301. return false;
  302.  
  303. if ( mm["untouchable"] ) {
  304. if ( mm["unlucky"] )
  305. return false; // we'll see.
  306. return true;
  307. }
  308.  
  309. if ( monster_modifiers_may_stop_actions() && foe.raw_hp > 90 )
  310. return true;
  311.  
  312. return false;
  313. }
  314.  
  315. boolean foe_should_be_nosy_nose_olfacted (monster foe) {
  316. switch (foe) {
  317. case $monster[drunk pygmy]: return true;
  318. case $monster[pygmy witch surgeon]: return true;
  319. case $monster[pygmy shaman]: return true;
  320. case $monster[gaudy pirate]: return true;
  321. case $monster[dirty old lihc]: return true;
  322. case $monster[tomb rat]: return true;
  323. case $monster[pygmy witch accountant]:
  324. if (my_location() == $location[The Hidden Office Building])
  325. return true;
  326. return false;
  327. }
  328. return false;
  329. }
  330.  
  331. boolean will_survive_n_rounds(monster foe, int rounds) {
  332. int damage_in_one_turn = 0;
  333.  
  334. if ( mm["cowardly"] )
  335. return true;
  336.  
  337. foreach monster_modifier, has_modifier in mm {
  338. if ( has_modifier == true ) {
  339. switch ( monster_modifier ) {
  340. case "electrified":
  341. damage_in_one_turn += my_maxhp() * 0.2;
  342. break;
  343. case "filthy":
  344. case "foul-mouthed":
  345. case "haunted":
  346. case "hot":
  347. case "wet":
  348. damage_in_one_turn += 30; // eh
  349. break;
  350. }
  351. }
  352. }
  353.  
  354. int plain_attack_damage = expected_damage(foe);
  355.  
  356. if ( plain_attack_damage < 0 ) // unspaded monster
  357. plain_attack_damage = 10;
  358.  
  359. if ( mm["shaky"] ) {
  360. plain_attack_damage = plain_attack_damage * 3;
  361. }
  362. else if ( mm["cloned"] ) {
  363. plain_attack_damage = plain_attack_damage * 2;
  364. }
  365.  
  366. print_html("plain dmg: " + plain_attack_damage + " | from mods: " + damage_in_one_turn);
  367. damage_in_one_turn += plain_attack_damage;
  368.  
  369. int total_damage = damage_in_one_turn * rounds;
  370.  
  371. return total_damage < my_hp();
  372. }
  373. boolean will_survive_round(monster foe) { // shortcut
  374. return will_survive_n_rounds(foe, 1);
  375. }
  376.  
  377. string gremlin_stasis_macro(monster foe) {
  378. // TODO
  379. return "abort \"Do gremlins on your own, you lazy fuck!\"";
  380. }
  381.  
  382. void rave_macro_generic(string which_combo) {
  383. string rave_combo = get_property("raveCombo1");
  384. if ( rave_combo == "" )
  385. return;
  386.  
  387. string [int] skill_order = rave_combo.split_string(",");
  388. foreach rave_skill in skill_order {
  389. push_skill(skill_order[rave_skill]);
  390. }
  391. }
  392.  
  393. void rave_plus_item_macro() {
  394. rave_macro_generic("raveCombo1");
  395. }
  396.  
  397. void rave_plus_meat_macro() {
  398. rave_macro_generic("raveCombo2");
  399. }
  400.  
  401. void rave_stun_macro() {
  402. rave_macro_generic("raveCombo3");
  403. }
  404.  
  405. boolean rave_steal_macro() {
  406. string rave_steal = get_property("raveCombo5");
  407. if ( rave_steal == "" )
  408. return false;
  409.  
  410. int steals_count = get_property("_raveStealCount").to_int();
  411. int steals_left = 30 - steals_count;
  412. if ( steals_left <= 0 )
  413. return false;
  414.  
  415. string [int] skill_order = rave_steal.split_string(",");
  416. foreach rave_skill in skill_order {
  417. push_skill(skill_order[rave_skill]);
  418. }
  419. return true;
  420. }
  421.  
  422. void pickpocket_macro(int num_items_dropped) {
  423. if ( num_items_dropped < 1 )
  424. return;
  425.  
  426. // no PP
  427. if ( !($classes[disco bandit,accordion thief] contains my_class()) )
  428. return;
  429.  
  430. // pp if we got the jump
  431. push_turnless_macro("if gotjump");
  432. push_action("pickpocket");
  433. push_turnless_macro("endif");
  434.  
  435. boolean have_second_pp = have_equipped($item[Bling of the New Wave]);
  436. if ( !have_second_pp )
  437. return;
  438.  
  439. // Second PP; only do it if the first attempt failed, OR
  440. // if the monster drops more than one item
  441. if ( num_items_dropped > 1 ) {
  442. push_action("pickpocket");
  443. }
  444. else {
  445. // Only drops one item. So only do the second PP
  446. // if the first one failed. This will also trigger if
  447. // we did not get the jump.
  448. push_turnless_macro("if !match \"You deftly slip your fingers\"");
  449. push_action("pickpocket");
  450. push_turnless_macro("endif");
  451. }
  452.  
  453. // match at this point will show whether we final pickpocket
  454. // succeeded
  455.  
  456. return;
  457. }
  458.  
  459. void disco_dance_macro() {
  460. push_skill("disco dance of doom");
  461. push_skill("disco dance ii");
  462. push_skill("disco dance 3");
  463. }
  464.  
  465. void add_goto_runaway_function(monster foe) {
  466. push_turnless_macro("sub try_goto_runaway");
  467. if ( mm["ticking"] ) {
  468. push_turnless_macro("if pastround 2");
  469. instakill_macro();
  470. push_turnless_macro("endif");
  471. }
  472.  
  473. push_turnless_macro("while hascombatitem 4948");
  474. push_action("use 4948"); // hurmph.
  475. push_turnless_macro("endwhile");
  476.  
  477. // Stole the goto, tried to do a free runaway, but failed.
  478. // So just kill it.
  479. default_fight_macro(foe);
  480. push_turnless_macro("endsub");
  481. }
  482.  
  483. void banish_pool_one_macro() {
  484. foreach this_skill in $skills[snokebomb, KGB tranquilizer dart] {
  485. if ( can_use_skill(this_skill) )
  486. push_skill(this_skill);
  487. }
  488.  
  489. if ( have_equipped($item[mafia thumb ring]) ) {
  490. int current_mp = my_mp();
  491. if ( current_mp >= 15 ) {
  492. push_turnless_macro("if hasskill Show them your ring");
  493. push_skill("Show them your ring");
  494. push_turnless_macro("endif");
  495. }
  496. }
  497.  
  498. foreach this_item in $items[louder than bomb, tennis ball, crystal skull] {
  499. push_item_multiuse_if_possible(this_item);
  500. }
  501.  
  502. push_turnless_macro("abort \"Cannot banish?!\"");
  503. }
  504.  
  505. boolean delevel_is_useful(monster foe) {
  506. int monster_attack = foe.base_attack + 20; // to be on the safe side
  507.  
  508. if ( my_buffedstat($stat[moxie]) > monster_attack )
  509. return false;
  510.  
  511. return true;
  512. }
  513.  
  514. boolean in_aftercore() {
  515. return !in_hardcore() && can_interact();
  516. }
  517.  
  518. void main(int initround, monster foe, string pg) {
  519. mm = foe.random_modifiers;
  520.  
  521. // Step up the base macro:
  522. push_turnless_macro("scrollwhendone");
  523. push_turnless_macro("abort hppercentbelow 25 || hpbelow 20 || pastround 28");
  524.  
  525. boolean disco_bandit = my_class() == $class[disco bandit];
  526.  
  527. int pickpocketable_items = 0;
  528. boolean consider_pickpocket = false;
  529.  
  530. boolean ran_combat = false;
  531. boolean stagger_immune = false;
  532.  
  533. foreach item_id, record_value in foe.item_drops_array() {
  534. if ( record_value.type == "c" ) { // conditional
  535. if ( item_type( record_value.drop ) != "shirt" )
  536. continue;
  537. }
  538. if ( record_value.rate == 0 ) // < 1% conditional
  539. continue;
  540.  
  541. pickpocketable_items += 1;
  542. }
  543.  
  544. if ( ticking_and_needs_instakill(foe) ) {
  545. instakill_macro();
  546. }
  547. else {
  548. if ( mm["unstoppable"] ) {
  549. stagger_immune = true;
  550. if ( mm["electrified"] && monster_modifiers_may_stop_actions() ) {
  551. // TODO check if we can survive long enough, otherwise
  552. // instakill
  553. if ( foe.raw_hp > 100 ) {
  554. // eh, no chance. Just instakill it.
  555. instakill_macro();
  556. }
  557. }
  558. }
  559. if ( pickpocketable_items > 0 ) {
  560. consider_pickpocket = true;
  561. }
  562. }
  563.  
  564. if ( foe == $monster[Eldritch Tentacle] ) {
  565. stagger_immune = true;
  566. }
  567.  
  568. location where = my_location();
  569. if ( in_aftercore() ) {
  570. boolean do_weaksauce = false;
  571.  
  572. switch ( where ) {
  573. case $location[Hobopolis Town Square]:
  574. do_weaksauce = true;
  575. pickpocket_macro(pickpocketable_items);
  576. break;
  577. case $location[Cobb's Knob Menagerie\, Level 1]:
  578. // aftercore UR farming
  579. if ( mm["solid gold"] ) { // just kill solid gold monsters
  580. pickpocket_macro(pickpocketable_items);
  581. }
  582. else {
  583. switch (foe) {
  584. case $monster[Fruit Golem]:
  585. pickpocket_macro(pickpocketable_items);
  586. banish_pool_one_macro();
  587. break;
  588. case $monster[BASIC Elemental]:
  589. add_goto_runaway_function(foe);
  590. pickpocket_macro(pickpocketable_items);
  591. push_turnless_macro("if match \"You deftly slip your fingers\"; call try_goto_runaway; endif;");
  592.  
  593. // Rave real
  594. if ( !mm["ticking"] && rave_steal_macro() ) {
  595. push_turnless_macro("if match \"Your savage beatdown seems to have knocked loose some treasure\"");
  596. push_turnless_macro("call try_goto_runaway");
  597. push_turnless_macro("endif");
  598. }
  599. break;
  600. default:
  601. push_turnless_macro("abort \"what\"");
  602. break;
  603. }
  604. }
  605. break;
  606. case $location[the red zeppelin]:
  607. if ( $item[glark cable].available_amount() > 0 && get_property("_glarkCableUses").to_int() < 5 )
  608. push_item_multiuse_if_possible($item[glark cable]);
  609. break;
  610. case $location[the hidden bowling alley]:
  611. if ( foe != $monster[drunk pygmy] && $item[short writ of habeas corpus].available_amount() > 0) {
  612. pickpocket_macro(pickpocketable_items);
  613. push_item_multiuse_if_possible($item[short writ of habeas corpus]);
  614. }
  615. default:
  616. if ( consider_pickpocket )
  617. pickpocket_macro(pickpocketable_items);
  618. break;
  619. }
  620.  
  621. boolean should_delevel = delevel_is_useful(foe);
  622. if ( !stagger_immune ) {
  623. if ( should_delevel )
  624. micrometeorite_macro();
  625. get_stun_macro();
  626. }
  627.  
  628. if ( do_weaksauce && should_delevel && !mm["ticking"] )
  629. push_skill("curse of weaksauce");
  630.  
  631. if ( disco_bandit && !mm["ticking"] ) { // can deal with ticking if we keep up a stun.
  632. int rounds_spent = 0;
  633.  
  634. if ( mm["solid gold"] ) {
  635. // +50% meat from rave
  636. if ( will_survive_n_rounds(foe, 2 + rounds_spent) ) {
  637. rounds_spent += 2;
  638. rave_plus_meat_macro();
  639. }
  640. }
  641.  
  642. if ( pickpocketable_items > 0 ) {
  643. // +30% item from discosity
  644. if ( will_survive_n_rounds(foe, 1 + rounds_spent) ) {
  645. disco_dance_macro();
  646. rounds_spent += 1;
  647. }
  648.  
  649. // +30% item from rave
  650. if ( will_survive_n_rounds(foe, 2 + rounds_spent) ) {
  651. rave_plus_item_macro();
  652. rounds_spent += 2;
  653. }
  654. }
  655.  
  656. if ( !mm["solid gold"] && foe.min_meat > 80 ) {
  657. // eh, sure.
  658. if ( will_survive_n_rounds(foe, 2 + rounds_spent) ) {
  659. rave_plus_meat_macro();
  660. rounds_spent += 2;
  661. }
  662. }
  663. }
  664. }
  665. else { // in-run
  666. // TODO actually write this out. Have not been in-run since I
  667. // started writing this...
  668. if ( foe_should_be_nosy_nose_olfacted(foe) )
  669. nosy_nose_olfact_macro();
  670.  
  671. // in-run
  672. if (
  673. where == $location[Barrrney's Barrr]
  674. &&
  675. foe.phylum == $phylum[pirate]
  676. ) {
  677. push_blockable_action("use big book of pirate insults");
  678. }
  679.  
  680. if (
  681. $item[rock band flyers].available_amount() > 0
  682. &&
  683. get_property("flyeredML").to_int() < 10000
  684. &&
  685. will_survive_round(foe)
  686. ) {
  687. // TODO heal in case we pickpocketed
  688. push_blockable_action("use rock band flyers");
  689. }
  690.  
  691. if ( contains_text(foe.manuel_name, "gremlin") ) {
  692. //string gremlin_stasis_macro = gremlin_stasis_macro(foe);
  693. //combat_macro = combat_macro + gremlin_stasis_macro;
  694. }
  695. }
  696.  
  697. default_fight_macro(foe);
  698.  
  699. // Show the macro, just in case...
  700. string full_combat_macro = compose_combat_macro();
  701. print_html(full_combat_macro);
  702. run_combat(full_combat_macro);
  703.  
  704. if ( in_aftercore() ) {
  705. if (
  706. where == $location[Hobopolis Town Square]
  707. &&
  708. my_familiar() == $familiar[slimeling]
  709. ) {
  710. int max_mp = my_maxmp();
  711. int threshold = max_mp * 0.4;
  712. if ( my_mp() < threshold ) {
  713. float slimeling_fullness = get_property("slimelingFullness").to_float();
  714. if ( slimeling_fullness < 5.0 ) {
  715. cli_execute("slimeling 1 ring of aggravate");
  716. }
  717. }
  718. }
  719.  
  720. if ( my_hp() < ( my_maxhp() * 0.6 ) ) {
  721. cli_execute("cast cannelloni cocoon");
  722. }
  723. }
  724.  
  725. return;
  726. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement