Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define BASE_SKILL_DELAY 7
- #define SKILL_ERROR_NO_TARGET "No target."
- #define SKILL_ERROR_NO_CLONES "No shadow clones are summoned."
- #define SKILL_ERROR_NOT_ENOUGH_CLONES(a, b) "Not enough shadow clones are summoned. ([a]/[b])"
- #define SKILL_ERROR_NOT_CLOSE_ENOUGH(a, b) "Not close enough. ([a]/[b])"
- #define SKILL_ERROR_TARGET_AIRBORNED "Cannot hit an Airborne target."
- var global
- skills_bypassing_stuns[] = list(
- GATE1, GATE2, GATE3, GATE4, GATE5,
- )
- skills_bypassing_attack_stun = list(
- LEAF_GREAT_WHIRLWIND,
- CRUMBLING_PALM,
- BODY_POINTS_DISTURBANCE,
- )
- var global/guard_break_skills[] = list(
- "[OVERKILL]" = 1,
- "[SAVAGERY]" = 1,
- "[MURDEROUS_SWORD]" = 1,
- "[LEAF_HURRICANE]" = 1,
- "[LEAF_STRONG_WHIRLWIND]" = 1,
- "[HORN_STYLE]" = 1,
- "[LARIAT]" = 1,
- )
- var global
- GRAPPLE_SKILLS[] = list(GRAPPLE, CLAW_HOLD, SUPPLEX, POWER_BOMB)
- var global/const
- // main categories
- SKILL_CATEGORY_NONE = 0
- SKILL_CATEGORY_NINJUTSU = 1
- SKILL_CATEGORY_GENJUTSU = 2
- SKILL_CATEGORY_TAIJUTSU = 4
- SKILL_CATEGORY_KENJUTSU = 8
- SKILL_CATEGORY_SHURIKENJUTSU = 16
- SKILL_CATEGORY_DOUJUTSU = 32
- // sub categories
- SKILL_CATEGORY_SEALING = 1
- SKILL_CATEGORY_HYUUGA = 2
- SKILL_CATEGORY_KAGUYA = 3
- SKILL_CATEGORY_KUMOJIN = 4
- SKILL_CATEGORY_FIRE = 5
- SKILL_CATEGORY_WATER = 6
- SKILL_CATEGORY_EARTH = 7
- SKILL_CATEGORY_WIND = 8
- SKILL_CATEGORY_LIGHTNING = 9
- SKILL_CATEGORY_DEMONIC_ILLUSION = 10
- SKILL_CATEGORY_RASENGAN = 11
- SKILL_CATEGORY_CTR = 12
- SKILL_CATEGORY_CLONE = 13
- SKILL_CATEGORY_NIRVANA_FIST = 14
- SKILL_CATEGORY_STRONG_FIST = 15
- SKILL_CATEGORY_EIGHT_GATES = 16
- SKILL_CATEGORY_MEDIC = 17
- SKILL_CATEGORY_EXPLOSIVE_TAG = 18
- SKILL_CATEGORY_RAGING_DEMON = 19
- SKILL_CATEGORY_BUSHI = 20
- SKILL_CATEGORY_IRON_CLAW = 21
- proc/is_combo_elements(skill/a, skill/b)
- if(!a || !b) return 0
- if(a.category2 == SKILL_CATEGORY_FIRE)
- if(b.category2 == SKILL_CATEGORY_WIND || b.category2 == SKILL_CATEGORY_EARTH)
- return 1
- else if(a.category2 == SKILL_CATEGORY_WATER)
- if(b.category2 == SKILL_CATEGORY_LIGHTNING)
- return 1
- else if(a.category2 == SKILL_CATEGORY_WIND)
- if(b.category2 == SKILL_CATEGORY_FIRE)
- return 1
- else if(a.category2 == SKILL_CATEGORY_LIGHTNING)
- if(b.category2 == SKILL_CATEGORY_WATER)
- return 1
- else if(a.category2 == SKILL_CATEGORY_EARTH)
- if(b.category2 == SKILL_CATEGORY_FIRE)
- return 1
- skill
- var
- name
- icon = 'icons/gui.dmi'
- icon_state = ""
- modified_state = ""
- list/icon_overlays
- id
- category = SKILL_CATEGORY_NONE
- category2 = SKILL_CATEGORY_NONE
- default_chakra_cost = 0
- default_stamina_cost = 0
- default_supply_cost = 0
- default_cooldown = 0
- default_seal_time = 0
- // setting of 1 stuns the user during handseals...
- // setting of 2 allows movement during handseals
- handseal_stun = 1
- base_charge_chakra = 0
- base_charge_stamina = 0
- base_charge_supply = 0
- charging = 0
- charge_stamina = 0
- charge_chakra = 0
- charge_supplies = 0
- max_charge_stamina = 0
- max_charge_chakra = 0
- max_charge_supply = 0
- copyable = 1
- cooldown
- cooldown_start_time = 0
- uses
- use_time = 0
- skillcards[0]
- skillcard_visible = 1
- skill/master
- face_nearest = 0
- deaccelerates = 1
- deaccelerate_level = 0
- mob/human/loc
- New(mob/human/user)
- ..()
- loc = user
- dispose_custom()
- loc = null
- if(skillcards)
- for(var/skillcard/sc in skillcards)
- sc.dispose()
- skillcards = null
- master = null
- proc/get_desc(mob/user)
- // TODO: The plan is to pull the information from a spreadsheet, and replace all instances of *user* with [user]'s name.
- return ""
- /*
- get_desc(mob/user)
- return {"
- Description...
- <ul>
- <li></li>
- </ul>
- "}
- */
- proc/get_damage(mob/user)
- proc/get_wounds(mob/user)
- proc/is_category(category)
- return ((src.category & category) || src.category2 == category)
- proc
- can_macro(mob/user)
- return 1
- IsUsable(mob/user)
- if(cooldown > 0)
- Error(user, "Cooldown Time ([round(cooldown)] seconds).")
- return 0
- else if(user.curchakra < ChakraCost(user))
- Error(user, "Insufficient Chakra ([user.curchakra]/[ChakraCost(user)]).")
- return 0
- else if(user.curstamina < StaminaCost(user))
- Error(user, "Insufficient Stamina ([user.curstamina]/[StaminaCost(user)]).")
- return 0
- else if(user.supplies < SupplyCost(user))
- Error(user, "Insufficient Supplies ([user.supplies]/[SupplyCost(user)]).")
- return 0
- else if(user.gate && ChakraCost(user) && !istype(src, /skill/taijutsu/gates) && !istype(src, /skill/body_replacement) && !istype(src, /skill/body_flicker))
- Error(user, "This skill cannot be used while a Gate is active.")
- return 0
- else if(user.reverse_lotus && !istype(src, /skill/taijutsu/reverse_lotus))
- Error(user, "This skill cannot be used while Reverse Lotus is active.")
- return 0
- /*
- else if(user.chakra_leech&&!istype(src, /skill/taijutsu)&&!istype(src, /skill/body_replacement))
- Error(user, "This skill cannot be used while Chakra Leech is active.")
- return 0
- */
- else if(user.chidori && !istype(src, /skill/body_flicker))
- Error(user, "This skill cannot be used while Chidori is active.")
- return 0
- else if(user.Size==1 && !istype(src, /skill/akimichi/size_multiplication))
- Error(user, "This skill cannot be used while Size Multiplication is active.")
- return 0
- else if(user.Size==2 && !istype(src, /skill/akimichi/super_size_multiplication))
- Error(user, "This skill cannot be used while a Super Size Multiplication is active.")
- return 0
- else if((user.grapple_target) && !(id in global.GRAPPLE_SKILLS))
- Error(user, "This skill cannot be used while Grapple is active.")
- return 0
- return 1
- Cooldown(mob/user)
- var/cooldown = default_cooldown
- if(user.gate >= 5 && category & SKILL_CATEGORY_TAIJUTSU)
- cooldown *= 0.5
- if((. = user.get_passive(PASSIVE_HANDSEAL_MASTERY)))
- cooldown *= 1 - . * 0.03
- if((. = user.get_passive(PASSIVE_SPEED_DEMON)))
- var/mult = (user.curstamina < user.stamina * 0.3) ? 0.015 : 0.01
- cooldown *= 1 - . * mult
- return round(cooldown)
- ChakraCost(mob/user)
- if(charging)
- return 0
- if(base_charge_chakra && !default_chakra_cost)
- return base_charge_chakra
- else if((. = user.get_passive(PASSIVE_EFFICIENCY)))
- return round(default_chakra_cost * (1 - . * 0.06))
- else
- return default_chakra_cost
- StaminaCost(mob/user)
- if(charging)
- return 0
- if(base_charge_stamina && !default_stamina_cost)
- return base_charge_stamina
- else if((. = user.get_passive(PASSIVE_VIGOR)))
- return round(default_stamina_cost * (1 - . * 0.07))
- else
- return default_stamina_cost
- SupplyCost(mob/user)
- return default_supply_cost
- SealTime(mob/user)
- var/time = default_seal_time
- if((. = user.get_passive(PASSIVE_SPEED_DEMON)))
- time *= 1 - 0.06 * .
- if((. = user.get_flinch_strength()))
- var/flinch = time * 2 + (4 + .)
- if((. = user.get_passive(PASSIVE_ONE_HANDED_SEAL)))
- flinch *= 1 - user.get_ohanded_seal_mult1() * .
- time += flinch
- else if((. = user.get_slow_strength()))
- var/slow = 3
- if((. = user.get_passive(PASSIVE_ONE_HANDED_SEAL)))
- slow *= 1 - user.get_ohanded_seal_mult2() * .
- time += slow
- return time
- get_skill_delay(mob/user)
- return BASE_SKILL_DELAY
- AI_Use(mob/human/player/npc/user)
- Use(user)
- Use(mob/user)
- Activate(mob/human/user, modified, force)
- /*
- if(user.leading)
- user.on_stop_leading_all()
- return
- */
- if(user.rasengan==1)
- if(id != CLONE_BODY_BLOW)
- user.Rasengan_Fail()
- else if(user.rasengan==2)
- user.ORasengan_Fail()
- if(user.chakra_leech)
- user.end_chakra_leech()
- if(user.isguard)
- user.end_defend()
- /*
- if(charging)
- charging = 0
- return
- */
- if(user.controlmob)
- user = user.controlmob
- if(!force)
- if(user.skillusecool > world.time || !user.CanUseSkills(id) || !IsUsable(user) || (user.mane && !istype(src,/skill/nara)))
- return
- if(!user.can_trigger_event(EVENT_ON_ACTIVATE_SKILL, user, src))
- return
- user.skillusecool = 1#INF
- user.decrease_chakra(ChakraCost(user))
- if((. = user.get_passive(PASSIVE_POWERHOUSE)) && user.curchakra < user.chakra * 0.9)
- user.activate_passive_boost(PASSIVE_POWERHOUSE)
- user.decrease_stamina(StaminaCost(user))
- var spl_cost = SupplyCost(user)
- if(spl_cost)
- user.supplies -= spl_cost
- if(user.client)
- user.refresh_inventory(1)
- if(base_charge_chakra || base_charge_stamina || base_charge_supply)
- if(charging)
- charging = 0
- else
- user.skillusecool = 0
- if(user.client)
- user.combat("<strong>[src]: Use this skill again to stop charging.</strong>")
- charge_stamina = base_charge_stamina
- charge_chakra = base_charge_chakra
- charge_supplies = base_charge_supply
- charging = 1
- spawn(BASE_SKILL_DELAY)
- if(!isinitialized(user) || !isinitialized(src)) return
- if(!charging) return
- var/stamina_charge = (charge_stamina) ? 1 : 0
- var/chakra_charge = (charge_chakra) ? 1 : 0
- var/supply_charge = (charge_supplies) ? 1 : 0
- while(charging)
- if(!isinitialized(user))
- break
- if(!user.CanUseSkills())
- break
- if(stamina_charge)
- var/charge_amt = min(base_charge_stamina, user.curstamina)
- user.curstamina -= charge_amt
- charge_stamina += charge_amt
- user.combat("[src]: Charged [charge_stamina] stamina.")
- if(user.curstamina <= 0)
- user.combat("[src]: Out of stamina. Use this skill again to finish charging.")
- stamina_charge = 0
- else if(max_charge_stamina && charge_stamina >= max_charge_stamina)
- user.combat("[src]: Fully charged stamina. Use this skill again to finish charging.")
- stamina_charge = 0
- if(chakra_charge)
- var/charge_amt = min(base_charge_chakra, user.curchakra)
- user.curchakra -= charge_amt
- charge_chakra += charge_amt
- user.combat("[src]: Charged [charge_chakra] chakra.")
- if(user.curchakra <= 0)
- user.combat("[src]: Out of chakra. Use this skill again to finish charging.")
- chakra_charge = 0
- else if(max_charge_chakra && charge_chakra >= max_charge_chakra)
- user.combat("[src]: Fully charged chakra. Use this skill again to finish charging.")
- chakra_charge = 0
- if(supply_charge)
- var/charge_amt = min(base_charge_supply, user.supplies)
- user.supplies -= charge_amt
- charge_supplies += charge_amt
- user.combat("[src]: Charged [charge_supplies] supplies.")
- if(user.supplies <= 0)
- user.combat("[src]: Out of supplies. Use this skill again to finish charging.")
- supply_charge = 0
- else if(max_charge_supply && charge_supplies >= max_charge_supply)
- user.combat("[src]: Fully charged supplies. Use this skill again to finish charging.")
- supply_charge = 0
- chakra_charge = 0
- sleep(5)
- if(!isinitialized(user))
- return
- else if(!user.CanUseSkills(id))
- user.skillusecool = 0
- charge_stamina = 0
- charge_chakra = 0
- charge_supplies = 0
- return
- return
- if(face_nearest != -1)
- if(face_nearest)
- if(user.NearestTarget())
- user.FaceTowards(user.NearestTarget())
- else
- if(user.MainTarget())
- user.FaceTowards(user.MainTarget())
- for(var/mob/human/player/XE in oview(user, 8))
- if(XE.client)
- var/can_copy = 0
- if(copyable && XE.HasSkill(SHARINGAN_COPY) && !XE.HasSkill(id))
- can_copy = 1
- XE.lastwitnessing=id
- var/event/timed_event/timer = XE.get_event_timer("sharingan_copy_reset_timer")
- if(!timer)
- timer = new(50, "reset_sharingan_copy", XE)
- XE.add_event_timer(timer, "sharingan_copy_reset_timer")
- else
- timer.reschedule(50)
- if(XE.sharingan)
- XE.combat("<font color=#faa21b>{Sharingan} [user] used [src].[can_copy?" Press <b>Space</b> within 5 Seconds to copy this skill.":""]</font>")
- if(XE.dleafshadow)
- XE.dleafshadow_target = user
- var/event/timed_event/timer = XE.get_event_timer("dleafshadow_timer")
- if(!timer)
- timer = new(50, "reset_dancing_leaf_shadow_activation", XE)
- XE.add_event_timer(timer, "dleafshadow_timer")
- else
- timer.reschedule(50)
- XE.combat("<span class=dancing_leaf_shadow><strong>Press Space</strong> to follow [user]'s movements and reposition!</span>")
- if(XE.relbow_active)
- if(XE.MainTarget() == user)
- XE.rushing_elbow(user)
- user.lastskill = id
- user.lastskilltime = world.time
- user.usingmove = name
- ++uses
- if(user && DoSeals(user) && (force || user.CanUseSkills(id)))
- if(isai(user))
- AI_Use(user, modified)
- else
- Use(user, modified)
- if(!isinitialized(user)) return
- user.skillusecool = world.time + get_skill_delay(user)
- user.usingmove = null
- if(deaccelerates)
- if(user.runlevel > deaccelerate_level)
- user.set_runlevel(deaccelerate_level)
- use_time = world.time
- // Force passive: reset combo damage boost after using a tai skill.
- if(is_category(SKILL_CATEGORY_TAIJUTSU))
- user.reset_force_boost()
- _DoCooldown(user)
- return 1
- DoSeals(mob/human/user)
- var/time = SealTime(user)
- if(time)
- user.animate_seals()
- user.handseal_stun = src.handseal_stun
- user.update_move_delay()
- for(, time > 0, time -= 0.25)
- sleep(TICK_LAG)
- if(!user || user.handseal_stun == -1 || !user.CanUseSkills())
- break
- if(user)
- user.remove_animation(GET_ANIMATION(ANIMATION_HANDSEALS))
- user.handseal_stun = 0
- user.update_move_delay()
- . = time > 0 ? FALSE : TRUE
- on_cooldown_start(mob/user)
- cooldown_start_time = world.time
- if(user.client)
- for(var/skillcard/card in skillcards)
- card.overlays += 'icons/dull.dmi'
- if(master)
- for(var/skillcard/card in master.skillcards)
- card.overlays += 'icons/dull.dmi'
- on_cooldown_ended(mob/user)
- cooldown = 0
- cooldown_start_time = 0
- if(user.client)
- for(var/skillcard/card in skillcards)
- card.overlays -= 'icons/dull.dmi'
- if(master)
- for(var/skillcard/card in master.skillcards)
- card.overlays -= 'icons/dull.dmi'
- _DoCooldown(mob/user, resume = 0, force, time)
- set waitfor = 0
- DoCooldown(arglist(args))
- DoCooldown(mob/user, resume = 0, force, time)
- if(isclone(user))
- var mob/human/player/npc/kage_bunshin/clone = user
- var mob/human/player/clone_user = clone.owner
- if(clone_user.controlmob == clone)
- user = clone_user
- if(isai(user))
- return AI_DoCooldown(user, resume, force, time)
- else
- return Client_DoCooldown(user, resume, force, time)
- AI_DoCooldown(mob/human/player/npc/user, resume = 0, force, time)
- if(cooldown && !resume && !force)
- return
- cooldown = 1
- var/cd_time = time || Cooldown(user)
- user.on_skill_cooldown_start(src, cd_time)
- Client_DoCooldown(mob/user, resume = 0, force, time)
- if(cooldown && cooldown_start_time && !resume && !force)
- return
- if(!resume)
- cooldown = time || Cooldown(user)
- for(var/skillcard/card in skillcards)
- card.overlays -= 'icons/dull.dmi'
- if(master)
- for(var/skillcard/card in master.skillcards)
- card.overlays -= 'icons/dull.dmi'
- if(!cooldown) return
- on_cooldown_start(user)
- var/started_time = cooldown_start_time
- while(cooldown > 0)
- sleep(10)
- cooldown -= 1
- if(started_time != cooldown_start_time) break
- if(!isinitialized(src)) break
- if(started_time != cooldown_start_time)
- return
- on_cooldown_ended(user)
- Info(mob/user, message)
- if(isclone(user))
- var mob/human/player/npc/kage_bunshin/clone = user
- var mob/human/player/clone_user = clone.owner
- if(clone_user.controlmob == clone)
- user = clone_user
- if(!user.client)
- return
- user.combat("<strong>[src]</strong>: [message]")
- Info2(mob/user, message)
- if(isclone(user))
- var mob/human/player/npc/kage_bunshin/clone = user
- var mob/human/player/clone_user = clone.owner
- if(clone_user.controlmob == clone)
- user = clone_user
- if(!user.client)
- return
- user.combat("[message]")
- Error(mob/user, message)
- if(isclone(user))
- var mob/human/player/npc/kage_bunshin/clone = user
- var mob/human/player/clone_user = clone.owner
- if(clone_user.controlmob == clone)
- user = clone_user
- if(!user.client)
- return
- user.combat("[src] can not be used currently: [message]")
- combat_msg(mob/user, msg)
- actual_oviewers(user) << output(msg, COMBAT_OUTPUT)
- ChangeIconState(new_state)
- icon_state = new_state
- for(var/skillcard/card in skillcards)
- card.icon_state = new_state
- if(master)
- master.IconStateChanged(src, new_state)
- DefaultIconState()
- var new_state = initial(icon_state)
- icon_state = new_state
- for(var/skillcard/card in skillcards)
- card.icon_state = card.default_icon_state
- if(master)
- master.IconStateChanged(src, new_state)
- IconStateChanged(skill/sk, new_state)
- set_maptext(m)
- for(var/skillcard/card in skillcards)
- card.maptext = m
- add_selected()
- add_overlay('icons_new/skills/selected.dmi')
- remove_selected()
- remove_overlay('icons_new/skills/selected.dmi')
- add_cancel()
- add_overlay('icons_new/skills/cancel.dmi')
- remove_cancel()
- remove_overlay('icons_new/skills/cancel.dmi')
- add_overlay(overlay)
- for(var/skillcard/card in skillcards)
- card.overlays += overlay
- if(master)
- master.overlay_added(src, overlay)
- remove_overlay(overlay)
- for(var/skillcard/card in skillcards)
- card.overlays -= overlay
- if(master)
- master.overlay_removed(src, overlay)
- overlay_added(skill/sk, overlay)
- overlay_removed(skill/sk, overlay)
- event_receiver
- proc/reset_sharingan_copy(mob/m)
- if(isinitialized(m))
- m.lastwitnessing = 0
- m.remove_event_timer("sharingan_copy_reset_timer")
- skillcard
- parent_type = /macroable
- plane = PLANE_HUD
- maptext_x = 2
- maptext_y = 1
- var
- skill/skill
- visible = 1
- default_icon_state = ""
- New(loc, skill/sk, modified)
- ..(loc)
- visible = sk.skillcard_visible
- skill = sk
- name = sk.name
- icon = sk.icon
- icon_state = (modified) ? sk.modified_state : sk.icon_state
- default_icon_state = icon_state
- src.modified = modified
- overlays = sk.icon_overlays
- mouse_drag_pointer = icon('icons/guidrag.dmi', sk.icon_state)
- if(sk.cooldown || (istype(sk, /skill/uchiha/sharingan_copy) && sk:copied_skill && sk:copied_skill:cooldown))
- overlays += 'icons/dull.dmi'
- sk.skillcards += src
- dispose_custom()
- skill = null
- ..()
- macro_action(mob/human/user)
- skill.Activate(user, modified)
- Click()
- skill.Activate(usr, modified)
- atom
- MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
- ..()
- if(over_object)
- if(isatom(over_object))
- var/atom/a = over_object
- a.on_mousedrop(src, src_location,over_location,src_control,over_control,params)
- proc/on_mousedrop(atom/dropped, src_location,over_location,src_control,over_control,params)
- // React to 'dropped' being mousedropped on src
- macroable
- parent_type = /obj
- layer = HUD_LAYER + 0.1
- var tmp
- modified = 0
- obj/hud/placeholder/slot/gui_slot
- dispose_custom()
- if(gui_slot)
- var mob/master = (loc && ismob(loc)) ? loc : null
- if(master?.client)
- master.client.remove_screen_obj("macroable: [name][modified]")
- master.client?.macro_map[master.client.macro_map_id][gui_slot.slot] = null
- gui_slot = null
- ..()
- MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
- ..()
- if(!usr || !usr.client) return
- // If this was dropped from the map to another control,
- // clear this slot.
- if(gui_slot)
- var/obj/hud/placeholder/slot/current_slot = gui_slot
- if(src_control == "map_pane.map" && (over_control != "map_pane.map" || usr.client.keys["modify"]))
- var/client/user_client = usr.client
- screen_loc = null
- gui_slot = null
- user_client.remove_screen_obj("macroable: [name][modified]")
- user_client.macro_map[user_client.macro_map_id][current_slot.slot] = null
- user_client.macro_map_data[user_client.macro_map_id]["macroable: [name][modified]"] = null
- // React to dropping a skill action over another skill to replace the macro slot
- on_mousedrop(macroable/m, src_location,over_location,src_control,over_control,params)
- if(!ismacroable(m)) return
- if(!usr || !usr.client) return
- if(gui_slot)
- var/obj/hud/placeholder/slot/current_slot = gui_slot
- var/client/user_client = usr.client
- user_client.remove_screen_obj("macroable: [name][modified]")
- user_client.remove_screen_obj("macroable: [m.name][m.modified]")
- user_client.macro_map[user_client.macro_map_id][current_slot.slot] = m
- if(m.gui_slot)
- user_client.macro_map[user_client.macro_map_id][m.gui_slot.slot] = null
- m.screen_loc = screen_loc
- m.gui_slot = gui_slot
- user_client.add_screen_obj(m, "macroable: [m.name][m.modified]")
- user_client.macro_map_data[user_client.macro_map_id]["macroable: [m.name][m.modified]"] = list(m.gui_slot, m.screen_loc)
- screen_loc = null
- gui_slot = null
- proc/macro_action(mob/human/user)
- mob
- proc/dispose_skills()
- if(skills)
- for(var/skill/sk in skills)
- sk.dispose()
- skills = null
- proc/get_meta_jutsu(amount)
- . = list()
- if(!skills || !skills.len)
- return
- if(amount <= 0)
- return
- var/total_cd_time = 0
- for(var/skill/sk in skills)
- total_cd_time += sk.uses * sk.default_cooldown
- total_cd_time = max(1, total_cd_time)
- var/prioritylist/sortedlist = new
- for(var/skill/sk in skills)
- var/use_percentage = (sk.uses * sk.default_cooldown) / total_cd_time
- sortedlist.Add(sk, use_percentage)
- for(var/i = sortedlist.len; i > 0; i--)
- . += sortedlist.Get(i)
- amount--
- if(amount <= 0)
- return .
- proc
- has_used_skill(id, time_window)
- time_window = time_window || 10
- var/skill/sk = GetSkill(id)
- if(!sk)
- return 0
- return world.time - sk.use_time < time_window ? 1 : 0
- AddSkill(id)
- if(islist(id))
- for(var/i in id)
- AddSkill(i)
- return
- if(HasSkill(id)) return
- var/skill_type = SkillType(id)
- var/skill/skill
- if(!skill_type)
- CRASH("Could not give [src] ([key]) skill with `id` = [id].")
- return 0
- else
- skill = new skill_type(src)
- if(!skills)
- skills = list()
- skills += skill
- if(!isai(src))
- new /skillcard(src, skill)
- if(skill.modified_state)
- new /skillcard(src, skill, 1)
- if(client)
- RefreshSkillList()
- return skill
- HasSkill(id)
- for(var/skill/skill in skills)
- if(skill.id == id)
- return 1
- return 0
- GetSkill(id)
- for(var/skill/skill in skills)
- if(skill.id == id)
- return skill
- ControlDamageMultiplier()
- var/conmult=(con + conbuff - conneg)/150
- if((. = get_passive(PASSIVE_PURE_POWER)))
- conmult *= 1 + 0.05 * .
- return conmult
- CanUseSkills(inskill = 0)
- if(inskill in global.skills_bypassing_attack_stun)
- return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && !kstun && !Tank && pk && !incombo && !is_freeze()
- if(inskill in global.skills_bypassing_stuns)
- return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && canattack < world.time && !kstun && !Tank && pk && !incombo && !is_freeze()
- return !cantreact && cantreact_time < world.time && !spectate && !larch && !frozen && !sleeping && !ko && canattack < world.time && !kstun && !Tank && pk && !incombo && !is_stunned_all()
- RefreshSkillList()
- if(client)
- var/grid_item = 0
- for(var/skillcard/X in contents)
- if(!X.visible)
- continue
- if(client)
- src << output(X, "skills_grid:[++grid_item]")
- if(client)
- winset(src, "skills_grid", "cells=[grid_item]")
- AppearBefore(mob/human/x,effect=/obj/overfx2)
- if(!x)return
- var/turf/t = get_step(x, x.dir)
- var/list/dirs = list(NORTH, SOUTH, EAST, WEST)
- while((!t || t.density) && dirs.len)
- var/dir = pick(dirs)
- dirs -= dir
- t = get_step(x, dir)
- if(t && !t.density)
- new effect(t)
- src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
- src.Facedir(x)
- AppearBehind(mob/human/x, effect=/obj/overfx)
- if(!x)return
- var/turf/t = get_step(x, turn(x.dir, 180))
- var/list/dirs = list(NORTH, SOUTH, EAST, WEST)
- while((!t || t.density) && dirs.len)
- var/dir = pick(dirs)
- dirs -= dir
- t = get_step(x, dir)
- if(t && !t.density)
- new effect(t)
- src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
- src.Facedir(x)
- AppearMyDir(mob/human/x, effect=/obj/overfx)
- if(!x)return 0
- var/turf/t = get_step(x, dir)
- var/list/dirs = list(turn(dir, 45), turn(dir, -45))
- while((!t || t.density) && dirs.len)
- var/dir = pick(dirs)
- dirs -= dir
- t = get_step(x, dir)
- if(t && !t.density)
- new effect(t)
- src.force_move(t, dir, move_flags = MOVE_FLAG_FORCE)
- src.Facedir(x)
- return 1
- return 0
- AppearAt(ax,ay,az, effect=/obj/overfx)
- if(isturf(args[1]))
- var/turf/t = args[1]
- ax = t.x
- ay = t.y
- az = t.z
- new effect(locate(ax,ay,az))
- src.force_move(locate(ax,ay,az), dir, move_flags = MOVE_FLAG_FORCE)
- proc
- SkillType(id)
- for(var/skill/skill in all_skills)
- if(skill.id == id)
- return skill.type
- SkillRef(id)
- for(var/skill/skill in all_skills)
- if(skill.id == id)
- return skill
- var
- all_skills[0]
- proc/init_all_skills()
- for(var/type in typesof(/skill))
- all_skills += new type()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement