Advertisement
Guest User

Untitled

a guest
Apr 5th, 2020
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.72 KB | None | 0 0
  1.  
  2.  
  3. #define BASE_SKILL_DELAY 7
  4.  
  5. #define SKILL_ERROR_NO_TARGET "No target."
  6. #define SKILL_ERROR_NO_CLONES "No shadow clones are summoned."
  7. #define SKILL_ERROR_NOT_ENOUGH_CLONES(a, b) "Not enough shadow clones are summoned. ([a]/[b])"
  8. #define SKILL_ERROR_NOT_CLOSE_ENOUGH(a, b) "Not close enough. ([a]/[b])"
  9. #define SKILL_ERROR_TARGET_AIRBORNED "Cannot hit an Airborne target."
  10.  
  11. var global
  12.     skills_bypassing_stuns[] = list(
  13.         GATE1, GATE2, GATE3, GATE4, GATE5,
  14.     )
  15.  
  16.     skills_bypassing_attack_stun = list(
  17.         LEAF_GREAT_WHIRLWIND,
  18.         CRUMBLING_PALM,
  19.         BODY_POINTS_DISTURBANCE,
  20.     )
  21.  
  22. var global/guard_break_skills[] = list(
  23.     "[OVERKILL]" = 1,
  24.     "[SAVAGERY]" = 1,
  25.     "[MURDEROUS_SWORD]" = 1,
  26.  
  27.     "[LEAF_HURRICANE]" = 1,
  28.     "[LEAF_STRONG_WHIRLWIND]" = 1,
  29.  
  30.     "[HORN_STYLE]" = 1,
  31.     "[LARIAT]" = 1,
  32. )
  33.  
  34. var global
  35.     GRAPPLE_SKILLS[] = list(GRAPPLE, CLAW_HOLD, SUPPLEX, POWER_BOMB)
  36.  
  37. var global/const
  38.     // main categories
  39.     SKILL_CATEGORY_NONE = 0
  40.     SKILL_CATEGORY_NINJUTSU = 1
  41.     SKILL_CATEGORY_GENJUTSU = 2
  42.     SKILL_CATEGORY_TAIJUTSU = 4
  43.     SKILL_CATEGORY_KENJUTSU = 8
  44.     SKILL_CATEGORY_SHURIKENJUTSU = 16
  45.     SKILL_CATEGORY_DOUJUTSU = 32
  46.  
  47.     // sub categories
  48.     SKILL_CATEGORY_SEALING = 1
  49.     SKILL_CATEGORY_HYUUGA = 2
  50.     SKILL_CATEGORY_KAGUYA = 3
  51.     SKILL_CATEGORY_KUMOJIN = 4
  52.     SKILL_CATEGORY_FIRE = 5
  53.     SKILL_CATEGORY_WATER = 6
  54.     SKILL_CATEGORY_EARTH = 7
  55.     SKILL_CATEGORY_WIND = 8
  56.     SKILL_CATEGORY_LIGHTNING = 9
  57.     SKILL_CATEGORY_DEMONIC_ILLUSION = 10
  58.     SKILL_CATEGORY_RASENGAN = 11
  59.     SKILL_CATEGORY_CTR = 12
  60.     SKILL_CATEGORY_CLONE = 13
  61.     SKILL_CATEGORY_NIRVANA_FIST = 14
  62.     SKILL_CATEGORY_STRONG_FIST = 15
  63.     SKILL_CATEGORY_EIGHT_GATES = 16
  64.     SKILL_CATEGORY_MEDIC = 17
  65.     SKILL_CATEGORY_EXPLOSIVE_TAG = 18
  66.     SKILL_CATEGORY_RAGING_DEMON = 19
  67.     SKILL_CATEGORY_BUSHI = 20
  68.     SKILL_CATEGORY_IRON_CLAW = 21
  69.  
  70. proc/is_combo_elements(skill/a, skill/b)
  71.     if(!a || !b) return 0
  72.     if(a.category2 == SKILL_CATEGORY_FIRE)
  73.         if(b.category2 == SKILL_CATEGORY_WIND || b.category2 == SKILL_CATEGORY_EARTH)
  74.             return 1
  75.     else if(a.category2 == SKILL_CATEGORY_WATER)
  76.         if(b.category2 == SKILL_CATEGORY_LIGHTNING)
  77.             return 1
  78.     else if(a.category2 == SKILL_CATEGORY_WIND)
  79.         if(b.category2 == SKILL_CATEGORY_FIRE)
  80.             return 1
  81.     else if(a.category2 == SKILL_CATEGORY_LIGHTNING)
  82.         if(b.category2 == SKILL_CATEGORY_WATER)
  83.             return 1
  84.     else if(a.category2 == SKILL_CATEGORY_EARTH)
  85.         if(b.category2 == SKILL_CATEGORY_FIRE)
  86.             return 1
  87.  
  88. skill
  89.     var
  90.         name
  91.         icon = 'icons/gui.dmi'
  92.         icon_state = ""
  93.         modified_state = ""
  94.         list/icon_overlays
  95.         id
  96.         category = SKILL_CATEGORY_NONE
  97.         category2 = SKILL_CATEGORY_NONE
  98.         default_chakra_cost = 0
  99.         default_stamina_cost = 0
  100.         default_supply_cost = 0
  101.         default_cooldown = 0
  102.         default_seal_time = 0
  103.         // setting of 1 stuns the user during handseals...
  104.         // setting of 2 allows movement during handseals
  105.         handseal_stun = 1
  106.         base_charge_chakra = 0
  107.         base_charge_stamina = 0
  108.         base_charge_supply = 0
  109.         charging = 0
  110.         charge_stamina = 0
  111.         charge_chakra = 0
  112.         charge_supplies = 0
  113.         max_charge_stamina = 0
  114.         max_charge_chakra = 0
  115.         max_charge_supply = 0
  116.         copyable = 1
  117.         cooldown
  118.         cooldown_start_time = 0
  119.         uses
  120.         use_time = 0
  121.         skillcards[0]
  122.         skillcard_visible = 1
  123.         skill/master
  124.         face_nearest = 0
  125.         deaccelerates = 1
  126.         deaccelerate_level = 0
  127.         mob/human/loc
  128.  
  129.     New(mob/human/user)
  130.         ..()
  131.         loc = user
  132.  
  133.     dispose_custom()
  134.         loc = null
  135.         if(skillcards)
  136.             for(var/skillcard/sc in skillcards)
  137.                 sc.dispose()
  138.             skillcards = null
  139.         master = null
  140.  
  141.     proc/get_desc(mob/user)
  142.         // TODO: The plan is to pull the information from a spreadsheet, and replace all instances of *user* with [user]'s name.
  143.         return ""
  144.  
  145. /*
  146.         get_desc(mob/user)
  147.             return {"
  148. Description...
  149. <ul>
  150. <li></li>
  151. </ul>
  152. "}
  153. */
  154.  
  155.     proc/get_damage(mob/user)
  156.  
  157.     proc/get_wounds(mob/user)
  158.  
  159.     proc/is_category(category)
  160.         return ((src.category & category) || src.category2 == category)
  161.  
  162.     proc
  163.         can_macro(mob/user)
  164.             return 1
  165.  
  166.         IsUsable(mob/user)
  167.             if(cooldown > 0)
  168.                 Error(user, "Cooldown Time ([round(cooldown)] seconds).")
  169.                 return 0
  170.             else if(user.curchakra < ChakraCost(user))
  171.                 Error(user, "Insufficient Chakra ([user.curchakra]/[ChakraCost(user)]).")
  172.                 return 0
  173.             else if(user.curstamina < StaminaCost(user))
  174.                 Error(user, "Insufficient Stamina ([user.curstamina]/[StaminaCost(user)]).")
  175.                 return 0
  176.             else if(user.supplies < SupplyCost(user))
  177.                 Error(user, "Insufficient Supplies ([user.supplies]/[SupplyCost(user)]).")
  178.                 return 0
  179.             else if(user.gate && ChakraCost(user) && !istype(src, /skill/taijutsu/gates) && !istype(src, /skill/body_replacement) && !istype(src, /skill/body_flicker))
  180.                 Error(user, "This skill cannot be used while a Gate is active.")
  181.                 return 0
  182.             else if(user.reverse_lotus && !istype(src, /skill/taijutsu/reverse_lotus))
  183.                 Error(user, "This skill cannot be used while Reverse Lotus is active.")
  184.                 return 0
  185.             /*
  186.             else if(user.chakra_leech&&!istype(src, /skill/taijutsu)&&!istype(src, /skill/body_replacement))
  187.                 Error(user, "This skill cannot be used while Chakra Leech is active.")
  188.                 return 0
  189.             */
  190.             else if(user.chidori && !istype(src, /skill/body_flicker))
  191.                 Error(user, "This skill cannot be used while Chidori is active.")
  192.                 return 0
  193.             else if(user.Size==1 && !istype(src, /skill/akimichi/size_multiplication))
  194.                 Error(user, "This skill cannot be used while Size Multiplication is active.")
  195.                 return 0
  196.             else if(user.Size==2 && !istype(src, /skill/akimichi/super_size_multiplication))
  197.                 Error(user, "This skill cannot be used while a Super Size Multiplication is active.")
  198.                 return 0
  199.             else if((user.grapple_target) && !(id in global.GRAPPLE_SKILLS))
  200.                 Error(user, "This skill cannot be used while Grapple is active.")
  201.                 return 0
  202.             return 1
  203.  
  204.  
  205.         Cooldown(mob/user)
  206.             var/cooldown = default_cooldown
  207.             if(user.gate >= 5 && category & SKILL_CATEGORY_TAIJUTSU)
  208.                 cooldown *= 0.5
  209.             if((. = user.get_passive(PASSIVE_HANDSEAL_MASTERY)))
  210.                 cooldown *= 1 - . * 0.03
  211.             if((. = user.get_passive(PASSIVE_SPEED_DEMON)))
  212.                 var/mult = (user.curstamina < user.stamina * 0.3) ? 0.015 : 0.01
  213.                 cooldown *= 1 - . * mult
  214.             return round(cooldown)
  215.  
  216.         ChakraCost(mob/user)
  217.             if(charging)
  218.                 return 0
  219.             if(base_charge_chakra && !default_chakra_cost)
  220.                 return base_charge_chakra
  221.             else if((. = user.get_passive(PASSIVE_EFFICIENCY)))
  222.                 return round(default_chakra_cost * (1 - . * 0.06))
  223.             else
  224.                 return default_chakra_cost
  225.  
  226.         StaminaCost(mob/user)
  227.             if(charging)
  228.                 return 0
  229.             if(base_charge_stamina && !default_stamina_cost)
  230.                 return base_charge_stamina
  231.             else if((. = user.get_passive(PASSIVE_VIGOR)))
  232.                 return round(default_stamina_cost * (1 - . * 0.07))
  233.             else
  234.                 return default_stamina_cost
  235.  
  236.         SupplyCost(mob/user)
  237.             return default_supply_cost
  238.  
  239.         SealTime(mob/user)
  240.             var/time = default_seal_time
  241.             if((. = user.get_passive(PASSIVE_SPEED_DEMON)))
  242.                 time *= 1 - 0.06 * .
  243.             if((. = user.get_flinch_strength()))
  244.                 var/flinch = time * 2 + (4 + .)
  245.                 if((. = user.get_passive(PASSIVE_ONE_HANDED_SEAL)))
  246.                     flinch *= 1 - user.get_ohanded_seal_mult1() * .
  247.                 time += flinch
  248.             else if((. = user.get_slow_strength()))
  249.                 var/slow = 3
  250.                 if((. = user.get_passive(PASSIVE_ONE_HANDED_SEAL)))
  251.                     slow *= 1 - user.get_ohanded_seal_mult2() * .
  252.                 time += slow
  253.             return time
  254.  
  255.         get_skill_delay(mob/user)
  256.             return BASE_SKILL_DELAY
  257.  
  258.  
  259.         AI_Use(mob/human/player/npc/user)
  260.             Use(user)
  261.  
  262.         Use(mob/user)
  263.  
  264.  
  265.         Activate(mob/human/user, modified, force)
  266.             /*
  267.             if(user.leading)
  268.                 user.on_stop_leading_all()
  269.                 return
  270.             */
  271.  
  272.             if(user.rasengan==1)
  273.                 if(id != CLONE_BODY_BLOW)
  274.                     user.Rasengan_Fail()
  275.             else if(user.rasengan==2)
  276.                 user.ORasengan_Fail()
  277.  
  278.             if(user.chakra_leech)
  279.                 user.end_chakra_leech()
  280.  
  281.             if(user.isguard)
  282.                 user.end_defend()
  283.  
  284.             /*
  285.             if(charging)
  286.                 charging = 0
  287.                 return
  288.             */
  289.  
  290.             if(user.controlmob)
  291.                 user = user.controlmob
  292.  
  293.             if(!force)
  294.                 if(user.skillusecool > world.time || !user.CanUseSkills(id) || !IsUsable(user) || (user.mane && !istype(src,/skill/nara)))
  295.                     return
  296.                 if(!user.can_trigger_event(EVENT_ON_ACTIVATE_SKILL, user, src))
  297.                     return
  298.  
  299.  
  300.             user.skillusecool = 1#INF
  301.  
  302.             user.decrease_chakra(ChakraCost(user))
  303.             if((. = user.get_passive(PASSIVE_POWERHOUSE)) && user.curchakra < user.chakra * 0.9)
  304.                 user.activate_passive_boost(PASSIVE_POWERHOUSE)
  305.             user.decrease_stamina(StaminaCost(user))
  306.             var spl_cost = SupplyCost(user)
  307.             if(spl_cost)
  308.                 user.supplies -= spl_cost
  309.                 if(user.client)
  310.                     user.refresh_inventory(1)
  311.  
  312.             if(base_charge_chakra || base_charge_stamina || base_charge_supply)
  313.                 if(charging)
  314.                     charging = 0
  315.                 else
  316.                     user.skillusecool = 0
  317.                     if(user.client)
  318.                         user.combat("<strong>[src]: Use this skill again to stop charging.</strong>")
  319.                     charge_stamina = base_charge_stamina
  320.                     charge_chakra = base_charge_chakra
  321.                     charge_supplies = base_charge_supply
  322.                     charging = 1
  323.                     spawn(BASE_SKILL_DELAY)
  324.                         if(!isinitialized(user) || !isinitialized(src)) return
  325.                         if(!charging) return
  326.                         var/stamina_charge = (charge_stamina) ? 1 : 0
  327.                         var/chakra_charge = (charge_chakra) ? 1 : 0
  328.                         var/supply_charge = (charge_supplies) ? 1 : 0
  329.                         while(charging)
  330.                             if(!isinitialized(user))
  331.                                 break
  332.                             if(!user.CanUseSkills())
  333.                                 break
  334.                             if(stamina_charge)
  335.                                 var/charge_amt = min(base_charge_stamina, user.curstamina)
  336.                                 user.curstamina -= charge_amt
  337.                                 charge_stamina += charge_amt
  338.                                 user.combat("[src]: Charged [charge_stamina] stamina.")
  339.                                 if(user.curstamina <= 0)
  340.                                     user.combat("[src]: Out of stamina. Use this skill again to finish charging.")
  341.                                     stamina_charge = 0
  342.                                 else if(max_charge_stamina && charge_stamina >= max_charge_stamina)
  343.                                     user.combat("[src]: Fully charged stamina. Use this skill again to finish charging.")
  344.                                     stamina_charge = 0
  345.                             if(chakra_charge)
  346.                                 var/charge_amt = min(base_charge_chakra, user.curchakra)
  347.                                 user.curchakra -= charge_amt
  348.                                 charge_chakra += charge_amt
  349.                                 user.combat("[src]: Charged [charge_chakra] chakra.")
  350.                                 if(user.curchakra <= 0)
  351.                                     user.combat("[src]: Out of chakra. Use this skill again to finish charging.")
  352.                                     chakra_charge = 0
  353.                                 else if(max_charge_chakra && charge_chakra >= max_charge_chakra)
  354.                                     user.combat("[src]: Fully charged chakra. Use this skill again to finish charging.")
  355.                                     chakra_charge = 0
  356.                             if(supply_charge)
  357.                                 var/charge_amt = min(base_charge_supply, user.supplies)
  358.                                 user.supplies -= charge_amt
  359.                                 charge_supplies += charge_amt
  360.                                 user.combat("[src]: Charged [charge_supplies] supplies.")
  361.                                 if(user.supplies <= 0)
  362.                                     user.combat("[src]: Out of supplies. Use this skill again to finish charging.")
  363.                                     supply_charge = 0
  364.                                 else if(max_charge_supply && charge_supplies >= max_charge_supply)
  365.                                     user.combat("[src]: Fully charged supplies. Use this skill again to finish charging.")
  366.                                     supply_charge = 0
  367.                                     chakra_charge = 0
  368.                             sleep(5)
  369.                         if(!isinitialized(user))
  370.                             return
  371.                         else if(!user.CanUseSkills(id))
  372.                             user.skillusecool = 0
  373.                             charge_stamina = 0
  374.                             charge_chakra = 0
  375.                             charge_supplies = 0
  376.                             return
  377.                     return
  378.  
  379.             if(face_nearest != -1)
  380.                 if(face_nearest)
  381.                     if(user.NearestTarget())
  382.                         user.FaceTowards(user.NearestTarget())
  383.                 else
  384.                     if(user.MainTarget())
  385.                         user.FaceTowards(user.MainTarget())
  386.  
  387.             for(var/mob/human/player/XE in oview(user, 8))
  388.                 if(XE.client)
  389.                     var/can_copy = 0
  390.                     if(copyable && XE.HasSkill(SHARINGAN_COPY) && !XE.HasSkill(id))
  391.                         can_copy = 1
  392.                         XE.lastwitnessing=id
  393.                         var/event/timed_event/timer = XE.get_event_timer("sharingan_copy_reset_timer")
  394.                         if(!timer)
  395.                             timer = new(50, "reset_sharingan_copy", XE)
  396.                             XE.add_event_timer(timer, "sharingan_copy_reset_timer")
  397.                         else
  398.                             timer.reschedule(50)
  399.                     if(XE.sharingan)
  400.                         XE.combat("<font color=#faa21b>{Sharingan} [user] used [src].[can_copy?" Press <b>Space</b> within 5 Seconds to copy this skill.":""]</font>")
  401.                     if(XE.dleafshadow)
  402.                         XE.dleafshadow_target = user
  403.                         var/event/timed_event/timer = XE.get_event_timer("dleafshadow_timer")
  404.                         if(!timer)
  405.                             timer = new(50, "reset_dancing_leaf_shadow_activation", XE)
  406.                             XE.add_event_timer(timer, "dleafshadow_timer")
  407.                         else
  408.                             timer.reschedule(50)
  409.                         XE.combat("<span class=dancing_leaf_shadow><strong>Press Space</strong> to follow [user]'s movements and reposition!</span>")
  410.                 if(XE.relbow_active)
  411.                     if(XE.MainTarget() == user)
  412.                         XE.rushing_elbow(user)
  413.  
  414.             user.lastskill = id
  415.             user.lastskilltime = world.time
  416.             user.usingmove = name
  417.             ++uses
  418.             if(user && DoSeals(user) && (force || user.CanUseSkills(id)))
  419.                 if(isai(user))
  420.                     AI_Use(user, modified)
  421.                 else
  422.                     Use(user, modified)
  423.             if(!isinitialized(user)) return
  424.  
  425.             user.skillusecool = world.time + get_skill_delay(user)
  426.             user.usingmove = null
  427.             if(deaccelerates)
  428.                 if(user.runlevel > deaccelerate_level)
  429.                     user.set_runlevel(deaccelerate_level)
  430.             use_time = world.time
  431.             // Force passive: reset combo damage boost after using a tai skill.
  432.             if(is_category(SKILL_CATEGORY_TAIJUTSU))
  433.                 user.reset_force_boost()
  434.             _DoCooldown(user)
  435.             return 1
  436.  
  437.         DoSeals(mob/human/user)
  438.             var/time = SealTime(user)
  439.             if(time)
  440.                 user.animate_seals()
  441.                 user.handseal_stun = src.handseal_stun
  442.                 user.update_move_delay()
  443.                 for(, time > 0, time -= 0.25)
  444.                     sleep(TICK_LAG)
  445.                     if(!user || user.handseal_stun == -1 || !user.CanUseSkills())
  446.                         break
  447.                 if(user)
  448.                     user.remove_animation(GET_ANIMATION(ANIMATION_HANDSEALS))
  449.                     user.handseal_stun = 0
  450.                     user.update_move_delay()
  451.             . = time > 0 ? FALSE : TRUE
  452.  
  453.         on_cooldown_start(mob/user)
  454.             cooldown_start_time = world.time
  455.             if(user.client)
  456.                 for(var/skillcard/card in skillcards)
  457.                     card.overlays += 'icons/dull.dmi'
  458.                 if(master)
  459.                     for(var/skillcard/card in master.skillcards)
  460.                         card.overlays += 'icons/dull.dmi'
  461.  
  462.         on_cooldown_ended(mob/user)
  463.             cooldown = 0
  464.             cooldown_start_time = 0
  465.             if(user.client)
  466.                 for(var/skillcard/card in skillcards)
  467.                     card.overlays -= 'icons/dull.dmi'
  468.                 if(master)
  469.                     for(var/skillcard/card in master.skillcards)
  470.                         card.overlays -= 'icons/dull.dmi'
  471.  
  472.         _DoCooldown(mob/user, resume = 0, force, time)
  473.             set waitfor = 0
  474.             DoCooldown(arglist(args))
  475.  
  476.         DoCooldown(mob/user, resume = 0, force, time)
  477.             if(isclone(user))
  478.                 var mob/human/player/npc/kage_bunshin/clone = user
  479.                 var mob/human/player/clone_user = clone.owner
  480.                 if(clone_user.controlmob == clone)
  481.                     user = clone_user
  482.             if(isai(user))
  483.                 return AI_DoCooldown(user, resume, force, time)
  484.             else
  485.                 return Client_DoCooldown(user, resume, force, time)
  486.  
  487.         AI_DoCooldown(mob/human/player/npc/user, resume = 0, force, time)
  488.             if(cooldown && !resume && !force)
  489.                 return
  490.             cooldown = 1
  491.             var/cd_time = time || Cooldown(user)
  492.             user.on_skill_cooldown_start(src, cd_time)
  493.  
  494.         Client_DoCooldown(mob/user, resume = 0, force, time)
  495.             if(cooldown && cooldown_start_time && !resume && !force)
  496.                 return
  497.  
  498.             if(!resume)
  499.                 cooldown = time || Cooldown(user)
  500.  
  501.             for(var/skillcard/card in skillcards)
  502.                 card.overlays -= 'icons/dull.dmi'
  503.             if(master)
  504.                 for(var/skillcard/card in master.skillcards)
  505.                     card.overlays -= 'icons/dull.dmi'
  506.  
  507.             if(!cooldown) return
  508.  
  509.             on_cooldown_start(user)
  510.             var/started_time = cooldown_start_time
  511.  
  512.             while(cooldown > 0)
  513.                 sleep(10)
  514.                 cooldown -= 1
  515.                 if(started_time != cooldown_start_time) break
  516.                 if(!isinitialized(src)) break
  517.             if(started_time != cooldown_start_time)
  518.                 return
  519.  
  520.             on_cooldown_ended(user)
  521.  
  522.  
  523.         Info(mob/user, message)
  524.             if(isclone(user))
  525.                 var mob/human/player/npc/kage_bunshin/clone = user
  526.                 var mob/human/player/clone_user = clone.owner
  527.                 if(clone_user.controlmob == clone)
  528.                     user = clone_user
  529.             if(!user.client)
  530.                 return
  531.             user.combat("<strong>[src]</strong>: [message]")
  532.  
  533.         Info2(mob/user, message)
  534.             if(isclone(user))
  535.                 var mob/human/player/npc/kage_bunshin/clone = user
  536.                 var mob/human/player/clone_user = clone.owner
  537.                 if(clone_user.controlmob == clone)
  538.                     user = clone_user
  539.             if(!user.client)
  540.                 return
  541.             user.combat("[message]")
  542.  
  543.         Error(mob/user, message)
  544.             if(isclone(user))
  545.                 var mob/human/player/npc/kage_bunshin/clone = user
  546.                 var mob/human/player/clone_user = clone.owner
  547.                 if(clone_user.controlmob == clone)
  548.                     user = clone_user
  549.             if(!user.client)
  550.                 return
  551.             user.combat("[src] can not be used currently: [message]")
  552.  
  553.         combat_msg(mob/user, msg)
  554.             actual_oviewers(user) << output(msg, COMBAT_OUTPUT)
  555.  
  556.  
  557.         ChangeIconState(new_state)
  558.             icon_state = new_state
  559.             for(var/skillcard/card in skillcards)
  560.                 card.icon_state = new_state
  561.             if(master)
  562.                 master.IconStateChanged(src, new_state)
  563.  
  564.         DefaultIconState()
  565.             var new_state = initial(icon_state)
  566.             icon_state = new_state
  567.             for(var/skillcard/card in skillcards)
  568.                 card.icon_state = card.default_icon_state
  569.             if(master)
  570.                 master.IconStateChanged(src, new_state)
  571.  
  572.         IconStateChanged(skill/sk, new_state)
  573.  
  574.         set_maptext(m)
  575.             for(var/skillcard/card in skillcards)
  576.                 card.maptext = m
  577.  
  578.         add_selected()
  579.             add_overlay('icons_new/skills/selected.dmi')
  580.         remove_selected()
  581.             remove_overlay('icons_new/skills/selected.dmi')
  582.  
  583.         add_cancel()
  584.             add_overlay('icons_new/skills/cancel.dmi')
  585.         remove_cancel()
  586.             remove_overlay('icons_new/skills/cancel.dmi')
  587.  
  588.         add_overlay(overlay)
  589.             for(var/skillcard/card in skillcards)
  590.                 card.overlays += overlay
  591.             if(master)
  592.                 master.overlay_added(src, overlay)
  593.  
  594.         remove_overlay(overlay)
  595.             for(var/skillcard/card in skillcards)
  596.                 card.overlays -= overlay
  597.             if(master)
  598.                 master.overlay_removed(src, overlay)
  599.  
  600.         overlay_added(skill/sk, overlay)
  601.  
  602.         overlay_removed(skill/sk, overlay)
  603.  
  604. event_receiver
  605.     proc/reset_sharingan_copy(mob/m)
  606.         if(isinitialized(m))
  607.             m.lastwitnessing = 0
  608.             m.remove_event_timer("sharingan_copy_reset_timer")
  609.  
  610.  
  611. skillcard
  612.     parent_type = /macroable
  613.     plane = PLANE_HUD
  614.     maptext_x = 2
  615.     maptext_y = 1
  616.     var
  617.         skill/skill
  618.         visible = 1
  619.         default_icon_state = ""
  620.  
  621.     New(loc, skill/sk, modified)
  622.         ..(loc)
  623.         visible = sk.skillcard_visible
  624.         skill = sk
  625.         name = sk.name
  626.         icon = sk.icon
  627.         icon_state = (modified) ? sk.modified_state : sk.icon_state
  628.         default_icon_state = icon_state
  629.         src.modified = modified
  630.         overlays = sk.icon_overlays
  631.         mouse_drag_pointer = icon('icons/guidrag.dmi', sk.icon_state)
  632.         if(sk.cooldown || (istype(sk, /skill/uchiha/sharingan_copy) && sk:copied_skill && sk:copied_skill:cooldown))
  633.             overlays += 'icons/dull.dmi'
  634.         sk.skillcards += src
  635.  
  636.     dispose_custom()
  637.         skill = null
  638.         ..()
  639.  
  640.     macro_action(mob/human/user)
  641.         skill.Activate(user, modified)
  642.  
  643.     Click()
  644.         skill.Activate(usr, modified)
  645.  
  646.  
  647. atom
  648.     MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
  649.         ..()
  650.         if(over_object)
  651.             if(isatom(over_object))
  652.                 var/atom/a = over_object
  653.                 a.on_mousedrop(src, src_location,over_location,src_control,over_control,params)
  654.  
  655.     proc/on_mousedrop(atom/dropped, src_location,over_location,src_control,over_control,params)
  656.         // React to 'dropped' being mousedropped on src
  657.  
  658.  
  659. macroable
  660.     parent_type = /obj
  661.     layer = HUD_LAYER + 0.1
  662.     var tmp
  663.         modified = 0
  664.         obj/hud/placeholder/slot/gui_slot
  665.  
  666.     dispose_custom()
  667.         if(gui_slot)
  668.             var mob/master = (loc && ismob(loc)) ? loc : null
  669.             if(master?.client)
  670.                 master.client.remove_screen_obj("macroable: [name][modified]")
  671.                 master.client?.macro_map[master.client.macro_map_id][gui_slot.slot] = null
  672.         gui_slot = null
  673.         ..()
  674.  
  675.     MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
  676.         ..()
  677.         if(!usr || !usr.client) return
  678.  
  679.         // If this was dropped from the map to another control,
  680.         // clear this slot.
  681.         if(gui_slot)
  682.             var/obj/hud/placeholder/slot/current_slot = gui_slot
  683.             if(src_control == "map_pane.map" && (over_control != "map_pane.map" || usr.client.keys["modify"]))
  684.                 var/client/user_client = usr.client
  685.                 screen_loc = null
  686.                 gui_slot = null
  687.                 user_client.remove_screen_obj("macroable: [name][modified]")
  688.                 user_client.macro_map[user_client.macro_map_id][current_slot.slot] = null
  689.                 user_client.macro_map_data[user_client.macro_map_id]["macroable: [name][modified]"] = null
  690.  
  691.     // React to dropping a skill action over another skill to replace the macro slot
  692.     on_mousedrop(macroable/m, src_location,over_location,src_control,over_control,params)
  693.         if(!ismacroable(m)) return
  694.         if(!usr || !usr.client) return
  695.         if(gui_slot)
  696.             var/obj/hud/placeholder/slot/current_slot = gui_slot
  697.             var/client/user_client = usr.client
  698.             user_client.remove_screen_obj("macroable: [name][modified]")
  699.             user_client.remove_screen_obj("macroable: [m.name][m.modified]")
  700.             user_client.macro_map[user_client.macro_map_id][current_slot.slot] = m
  701.  
  702.             if(m.gui_slot)
  703.                 user_client.macro_map[user_client.macro_map_id][m.gui_slot.slot] = null
  704.             m.screen_loc = screen_loc
  705.             m.gui_slot = gui_slot
  706.             user_client.add_screen_obj(m, "macroable: [m.name][m.modified]")
  707.             user_client.macro_map_data[user_client.macro_map_id]["macroable: [m.name][m.modified]"] = list(m.gui_slot, m.screen_loc)
  708.             screen_loc = null
  709.             gui_slot = null
  710.  
  711.     proc/macro_action(mob/human/user)
  712.  
  713.  
  714. mob
  715.     proc/dispose_skills()
  716.         if(skills)
  717.             for(var/skill/sk in skills)
  718.                 sk.dispose()
  719.             skills = null
  720.  
  721.     proc/get_meta_jutsu(amount)
  722.         . = list()
  723.         if(!skills || !skills.len)
  724.             return
  725.         if(amount <= 0)
  726.             return
  727.         var/total_cd_time = 0
  728.         for(var/skill/sk in skills)
  729.             total_cd_time += sk.uses * sk.default_cooldown
  730.         total_cd_time = max(1, total_cd_time)
  731.         var/prioritylist/sortedlist = new
  732.         for(var/skill/sk in skills)
  733.             var/use_percentage = (sk.uses * sk.default_cooldown) / total_cd_time
  734.             sortedlist.Add(sk, use_percentage)
  735.         for(var/i = sortedlist.len; i > 0; i--)
  736.             . += sortedlist.Get(i)
  737.             amount--
  738.             if(amount <= 0)
  739.                 return .
  740.  
  741.     proc
  742.         has_used_skill(id, time_window)
  743.             time_window = time_window || 10
  744.             var/skill/sk = GetSkill(id)
  745.             if(!sk)
  746.                 return 0
  747.             return world.time - sk.use_time < time_window ? 1 : 0
  748.  
  749.         AddSkill(id)
  750.             if(islist(id))
  751.                 for(var/i in id)
  752.                     AddSkill(i)
  753.                 return
  754.             if(HasSkill(id)) return
  755.             var/skill_type = SkillType(id)
  756.             var/skill/skill
  757.             if(!skill_type)
  758.                 CRASH("Could not give [src] ([key]) skill with `id` = [id].")
  759.                 return 0
  760.             else
  761.                 skill = new skill_type(src)
  762.             if(!skills)
  763.                 skills = list()
  764.             skills += skill
  765.             if(!isai(src))
  766.                 new /skillcard(src, skill)
  767.                 if(skill.modified_state)
  768.                     new /skillcard(src, skill, 1)
  769.             if(client)
  770.                 RefreshSkillList()
  771.             return skill
  772.  
  773.  
  774.         HasSkill(id)
  775.             for(var/skill/skill in skills)
  776.                 if(skill.id == id)
  777.                     return 1
  778.             return 0
  779.  
  780.  
  781.         GetSkill(id)
  782.             for(var/skill/skill in skills)
  783.                 if(skill.id == id)
  784.                     return skill
  785.  
  786.  
  787.         ControlDamageMultiplier()
  788.             var/conmult=(con + conbuff - conneg)/150
  789.             if((. = get_passive(PASSIVE_PURE_POWER)))
  790.                 conmult *= 1 + 0.05 * .
  791.             return conmult
  792.  
  793.  
  794.         CanUseSkills(inskill = 0)
  795.             if(inskill in global.skills_bypassing_attack_stun)
  796.                 return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && !kstun && !Tank && pk && !incombo && !is_freeze()
  797.             if(inskill in global.skills_bypassing_stuns)
  798.                 return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && canattack < world.time && !kstun && !Tank && pk && !incombo && !is_freeze()
  799.             return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && canattack < world.time && !kstun && !Tank && pk && !incombo && !is_stunned_all()
  800.  
  801.  
  802.         RefreshSkillList()
  803.             if(client)
  804.                 var/grid_item = 0
  805.                 for(var/skillcard/X in contents)
  806.                     if(!X.visible)
  807.                         continue
  808.                     if(client)
  809.                         src << output(X, "skills_grid:[++grid_item]")
  810.                 if(client)
  811.                     winset(src, "skills_grid", "cells=[grid_item]")
  812.  
  813.         AppearBefore(mob/human/x,effect=/obj/overfx2)
  814.             if(!x)return
  815.  
  816.             var/turf/t = get_step(x, x.dir)
  817.             var/list/dirs = list(NORTH, SOUTH, EAST, WEST)
  818.             while((!t || t.density) && dirs.len)
  819.                 var/dir = pick(dirs)
  820.                 dirs -= dir
  821.                 t = get_step(x, dir)
  822.             if(t && !t.density)
  823.                 new effect(t)
  824.                 src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
  825.                 src.Facedir(x)
  826.  
  827.         AppearBehind(mob/human/x, effect=/obj/overfx)
  828.             if(!x)return
  829.  
  830.             var/turf/t = get_step(x, turn(x.dir, 180))
  831.             var/list/dirs = list(NORTH, SOUTH, EAST, WEST)
  832.             while((!t || t.density) && dirs.len)
  833.                 var/dir = pick(dirs)
  834.                 dirs -= dir
  835.                 t = get_step(x, dir)
  836.             if(t && !t.density)
  837.                 new effect(t)
  838.                 src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
  839.                 src.Facedir(x)
  840.  
  841.         AppearMyDir(mob/human/x, effect=/obj/overfx)
  842.             if(!x)return 0
  843.  
  844.             var/turf/t = get_step(x, dir)
  845.             var/list/dirs = list(turn(dir, 45), turn(dir, -45))
  846.             while((!t || t.density) && dirs.len)
  847.                 var/dir = pick(dirs)
  848.                 dirs -= dir
  849.                 t = get_step(x, dir)
  850.             if(t && !t.density)
  851.                 new effect(t)
  852.                 src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
  853.                 src.Facedir(x)
  854.                 return 1
  855.             return 0
  856.  
  857.         AppearAt(ax,ay,az, effect=/obj/overfx)
  858.             if(isturf(args[1]))
  859.                 var/turf/t = args[1]
  860.                 ax = t.x
  861.                 ay = t.y
  862.                 az = t.z
  863.             new effect(locate(ax,ay,az))
  864.             src.force_move(locate(ax,ay,az), dir, move_flags = MOVE_FLAG_FORCE)
  865.  
  866.  
  867.  
  868. proc
  869.     SkillType(id)
  870.         for(var/skill/skill in all_skills)
  871.             if(skill.id == id)
  872.                 return skill.type
  873.  
  874.     SkillRef(id)
  875.         for(var/skill/skill in all_skills)
  876.             if(skill.id == id)
  877.                 return skill
  878.  
  879.  
  880. var
  881.     all_skills[0]
  882.  
  883.  
  884.  
  885.  
  886. proc/init_all_skills()
  887.     for(var/type in typesof(/skill))
  888.         all_skills += new type()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement