From 2e0513bb502d3e8452e5e1544745a3351dfd2e9a Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 1 Oct 2017 18:51:53 +1300 Subject: [PATCH 1/9] Fixes master --- code/game/gamemodes/cult/cult_structures.dm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index c1ccf9a368..ef51a2e01a 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -107,8 +107,19 @@ pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield if("Flagellant's Robe") pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker +<<<<<<< HEAD if("Nar-Sien Hardsuit") pickedtype = /obj/item/clothing/suit/space/hardsuit/cult +======= + if("Bastard Sword") + if((world.time - SSticker.round_start_time) >= 12000) + pickedtype = /obj/item/twohanded/required/cult_bastard + else + cooldowntime = 12000 - (world.time - SSticker.round_start_time) + to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime)].") + cooldowntime = 0 + return +>>>>>>> e997bc4... Merge pull request #31198 from Jordie0608/apparentlythisbuildcompletedthefirsttimeidkhow if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) cooldowntime = world.time + 2400 var/obj/item/N = new pickedtype(get_turf(src)) From 4e648765db9f674127f1546037f14d71df28ed41 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 3 Oct 2017 18:10:39 -0500 Subject: [PATCH 2/9] Ports dash weapons to the dash datum --- code/datums/action.dm | 4 + code/datums/dash_weapon.dm | 50 ++++++ code/game/gamemodes/cult/cult_items.dm | 167 ++++++++++++++++++ code/modules/mining/equipment/survival_pod.dm | 2 +- code/modules/ninja/energy_katana.dm | 100 ++++------- code/modules/ninja/outfit.dm | 2 +- code/modules/ninja/suit/suit.dm | 2 +- tgstation.dme | 1 + 8 files changed, 257 insertions(+), 71 deletions(-) create mode 100644 code/datums/dash_weapon.dm diff --git a/code/datums/action.dm b/code/datums/action.dm index a65294fa40..b0ee243978 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -591,3 +591,7 @@ var/mob/M = owner var/datum/language_holder/H = M.get_language_holder() H.open_language_menu(usr) +<<<<<<< HEAD +======= + +>>>>>>> 380413f... Ports dash weapons to the dash datum (#31222) diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm new file mode 100644 index 0000000000..1637655d18 --- /dev/null +++ b/code/datums/dash_weapon.dm @@ -0,0 +1,50 @@ +/datum/action/innate/dash + name = "Dash" + desc = "Teleport to the targeted location." + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "jetboot" + var/current_charges = 1 + var/max_charges = 1 + var/charge_rate = 250 + var/mob/living/carbon/human/holder + var/obj/item/dashing_item + var/dash_sound = 'sound/magic/blink.ogg' + var/recharge_sound = 'sound/magic/charge.ogg' + var/beam_effect = "blur" + var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase + var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out + +/datum/action/innate/dash/Grant(mob/user, obj/dasher) + . = ..() + dashing_item = dasher + holder = user + +/datum/action/innate/dash/IsAvailable() + if(current_charges > 0) + return TRUE + else + return FALSE + +/datum/action/innate/dash/Activate() + dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item + +/datum/action/innate/dash/proc/Teleport(mob/user, atom/target) + if(!IsAvailable()) + return + var/turf/T = get_turf(target) + if(target in view(user.client.view, get_turf(user))) + var/obj/spot1 = new phaseout(get_turf(user), user.dir) + user.forceMove(T) + playsound(T, dash_sound, 25, 1) + var/obj/spot2 = new phasein(get_turf(user), user.dir) + spot1.Beam(spot2,beam_effect,time=20) + current_charges-- + holder.update_action_buttons_icon() + addtimer(CALLBACK(src, .proc/charge), charge_rate) + +/datum/action/innate/dash/proc/charge() + current_charges = Clamp(current_charges + 1, 0, max_charges) + holder.update_action_buttons_icon() + if(recharge_sound) + playsound(dashing_item, recharge_sound, 50, 1) + to_chat(holder, "[src] now has [current_charges]/[max_charges] charges.") \ No newline at end of file diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 55f8ece5e6..b6f25fc746 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -72,6 +72,173 @@ if(is_servant_of_ratvar(C) && C.reagents) C.reagents.add_reagent("heparin", 1) +<<<<<<< HEAD +======= +/obj/item/twohanded/required/cult_bastard + name = "bloody bastard sword" + desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers." + w_class = WEIGHT_CLASS_HUGE + block_chance = 50 + throwforce = 20 + force = 35 + armour_penetration = 45 + throw_speed = 1 + throw_range = 3 + sharpness = IS_SHARP + light_color = "#ff0000" + attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved") + icon_state = "cultbastard" + item_state = "cultbastard" + hitsound = 'sound/weapons/bladeslice.ogg' + lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' + righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 + actions_types = list() + flags_2 = SLOWS_WHILE_IN_HAND_2 + var/datum/action/innate/dash/cult/jaunt + var/datum/action/innate/cult/spin2win/linked_action + var/spinning = FALSE + var/spin_cooldown = 250 + var/list/shards = list() + var/dash_toggled = TRUE + +/obj/item/twohanded/required/cult_bastard/Initialize() + . = ..() + set_light(4) + jaunt = new(src) + linked_action = new(src) + +/obj/item/twohanded/required/cult_bastard/can_be_pulled(user) + return FALSE + +/obj/item/twohanded/required/cult_bastard/attack_self(mob/user) + dash_toggled = !dash_toggled + if(dash_toggled) + to_chat(loc, "You raise the [src] and prepare to jaunt with it.") + else + to_chat(loc, "You lower the [src] and prepare to swing it normally.") + +/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user) + . = ..() + if(!iscultist(user)) + if(!is_servant_of_ratvar(user)) + to_chat(user, "\"I wouldn't advise that.\"") + to_chat(user, "An overwhelming sense of nausea overpowers you!") + user.Dizzy(80) + user.Knockdown(30) + return + else + to_chat(user, "\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"") + to_chat(user, "A horrible force yanks at your arm!") + user.emote("scream") + user.apply_damage(30, BRUTE, pick("l_arm", "r_arm")) + user.Knockdown(50) + return + jaunt.Grant(user, src) + linked_action.Grant(user, src) + user.update_icons() + +/obj/item/twohanded/required/cult_bastard/dropped(mob/user) + . = ..() + linked_action.Remove(user) + jaunt.Remove(user) + user.update_icons() + +/obj/item/twohanded/required/cult_bastard/IsReflect() + if(spinning) + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) + return TRUE + else + ..() + +/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(prob(final_block_chance)) + if(attack_type == PROJECTILE_ATTACK) + owner.visible_message("[owner] deflects [attack_text] with [src]!") + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1) + return TRUE + else + playsound(src, 'sound/weapons/parry.ogg', 75, 1) + owner.visible_message("[owner] parries [attack_text] with [src]!") + return TRUE + return FALSE + +/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters) + . = ..() + if(dash_toggled) + jaunt.Teleport(user, target) + return + if(!proximity) + return + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.stat != CONSCIOUS) + var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src) + SS.attack(H, user) + shards += SS + return + if(istype(target, /obj/structure/constructshell) && contents.len) + var/obj/item/device/soulstone/SS = contents[1] + if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user)) + qdel(SS) + +/datum/action/innate/dash/cult + name = "Rend the Veil" + desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target." + icon_icon = 'icons/mob/actions/actions_cult.dmi' + button_icon_state = "phaseshift" + dash_sound = 'sound/magic/enter_blood.ogg' + recharge_sound = 'sound/magic/exit_blood.ogg' + beam_effect = "sendbeam" + phasein = /obj/effect/temp_visual/dir_setting/cult/phase + phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out + +/datum/action/innate/dash/cult/IsAvailable() + if(iscultist(holder) && current_charges) + return TRUE + else + return FALSE + + + +/datum/action/innate/cult/spin2win + name = "Geometer's Fury" + desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks." + background_icon_state = "bg_demon" + button_icon_state = "sintouch" + var/cooldown = 0 + var/mob/living/carbon/human/holder + var/obj/item/twohanded/required/cult_bastard/sword + +/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard) + . = ..() + sword = bastard + holder = user + +/datum/action/innate/cult/spin2win/IsAvailable() + if(iscultist(holder) && cooldown <= world.time) + return TRUE + else + return FALSE + +/datum/action/innate/cult/spin2win/Activate() + cooldown = world.time + sword.spin_cooldown + holder.changeNext_move(50) + holder.apply_status_effect(/datum/status_effect/sword_spin) + sword.spinning = TRUE + sword.block_chance = 100 + sword.slowdown += 1.5 + addtimer(CALLBACK(src, .proc/stop_spinning), 50) + holder.update_action_buttons_icon() + +/datum/action/innate/cult/spin2win/proc/stop_spinning() + sword.spinning = FALSE + sword.block_chance = 50 + sword.slowdown -= 1.5 + sleep(sword.spin_cooldown) + holder.update_action_buttons_icon() +>>>>>>> 380413f... Ports dash weapons to the dash datum (#31222) /obj/item/restraints/legcuffs/bola/cult name = "nar'sien bola" diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 5b8c40a976..bb44f22752 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -307,7 +307,7 @@ /obj/item/melee/supermatter_sword, /obj/item/shield/changeling, /obj/item/lava_staff, - /obj/item/dash/energy_katana, + /obj/item/energy_katana, /obj/item/hierophant_club, /obj/item/his_grace, /obj/item/gun/ballistic/minigun, diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm index 8901c1b9fa..33283db352 100644 --- a/code/modules/ninja/energy_katana.dm +++ b/code/modules/ninja/energy_katana.dm @@ -1,60 +1,4 @@ -/obj/item/dash - name = "abstract dash weapon" - var/max_charges = 3 - var/current_charges = 3 - var/charge_rate = 30 //In deciseconds - var/dash_toggled = TRUE - - var/bypass_density = FALSE //Can we beam past windows/airlocks/etc - - var/start_effect_type = /obj/effect/temp_visual/dir_setting/ninja/phase/out - var/end_effect_type = /obj/effect/temp_visual/dir_setting/ninja/phase - var/beam_icon_state = "blur" - var/dash_beam_type = /obj/effect/ebeam - -/obj/item/dash/proc/charge() - current_charges = Clamp(current_charges + 1, 0, max_charges) - if(istype(loc, /mob/living)) - to_chat(loc, "[src] now has [current_charges]/[max_charges] charges.") - -/obj/item/dash/attack_self(mob/user) - dash_toggled = !dash_toggled - to_chat(user, "You [dash_toggled ? "enable" : "disable"] the dash function on [src].") - -/obj/item/dash/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(dash_toggled) - dash(user, target) - return - -/obj/item/dash/proc/dash(mob/user, atom/target) - if(!current_charges) - return - - if(Adjacent(target)) - return - - if(target.density) - return - - var/turf/T = get_turf(target) - - if(!bypass_density) - for(var/turf/turf in getline(get_turf(user),T)) - for(var/atom/A in turf) - if(A.density) - return - - if(target in view(user.client.view, get_turf(user))) - var/obj/spot1 = new start_effect_type(T, user.dir) - user.forceMove(T) - playsound(T, 'sound/magic/blink.ogg', 25, 1) - playsound(T, "sparks", 50, 1) - var/obj/spot2 = new end_effect_type(get_turf(user), user.dir) - spot1.Beam(spot2, beam_icon_state,time = 2, maxdistance = 20, beam_type = dash_beam_type) - current_charges-- - addtimer(CALLBACK(src, .proc/charge), charge_rate) - -/obj/item/dash/energy_katana +/obj/item/energy_katana name = "energy katana" desc = "A katana infused with strong energy." icon_state = "energy_katana" @@ -73,23 +17,40 @@ sharpness = IS_SHARP max_integrity = 200 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - bypass_density = TRUE var/datum/effect_system/spark_spread/spark_system + var/datum/action/innate/dash/ninja/jaunt + var/dash_toggled = TRUE -/obj/item/dash/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters) +/obj/item/energy_katana/Initialize() + . = ..() + jaunt = new(src) + spark_system = new /datum/effect_system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + +/obj/item/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters) if(dash_toggled) - return ..() + jaunt.Teleport(user, target) if(proximity_flag && (isobj(target) || issilicon(target))) spark_system.start() playsound(user, "sparks", 50, 1) playsound(user, 'sound/weapons/blade1.ogg', 50, 1) target.emag_act(user) +/obj/item/energy_katana/pickup(mob/living/user) + . = ..() + jaunt.Grant(user, src) + user.update_icons() + +/obj/item/energy_katana/dropped(mob/user) + . = ..() + jaunt.Remove(user) + user.update_icons() //If we hit the Ninja who owns this Katana, they catch it. //Works for if the Ninja throws it or it throws itself or someone tries //To throw it at the ninja -/obj/item/dash/energy_katana/throw_impact(atom/hit_atom) +/obj/item/energy_katana/throw_impact(atom/hit_atom) if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) @@ -100,7 +61,7 @@ ..() -/obj/item/dash/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) +/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0) if(!istype(user)) return forceMove(get_turf(user)) @@ -127,12 +88,15 @@ if(msg) to_chat(user, "[msg]") -/obj/item/dash/energy_katana/Initialize() - . = ..() - spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(5, 0, src) - spark_system.attach(src) -/obj/item/dash/energy_katana/Destroy() +/obj/item/energy_katana/Destroy() QDEL_NULL(spark_system) return ..() + +/datum/action/innate/dash/ninja + current_charges = 3 + max_charges = 3 + charge_rate = 30 + recharge_sound = null + + diff --git a/code/modules/ninja/outfit.dm b/code/modules/ninja/outfit.dm index 4ec9cde23c..2fd732f0ce 100644 --- a/code/modules/ninja/outfit.dm +++ b/code/modules/ninja/outfit.dm @@ -12,7 +12,7 @@ l_pocket = /obj/item/grenade/plastic/x4 r_pocket = /obj/item/tank/internals/emergency_oxygen internals_slot = slot_r_store - belt = /obj/item/dash/energy_katana + belt = /obj/item/energy_katana implants = list(/obj/item/implant/explosive) diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 40d18951e6..1dcfed99c0 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -30,7 +30,7 @@ Contents: var/datum/effect_system/spark_spread/spark_system var/list/stored_research = list()//For stealing station research. var/obj/item/disk/tech_disk/t_disk//To copy design onto disk. - var/obj/item/dash/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) + var/obj/item/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) //Other articles of ninja gear worn together, used to easily reference them after initializing. var/obj/item/clothing/head/helmet/space/space_ninja/n_hood diff --git a/tgstation.dme b/tgstation.dme index 1d878fc78b..2dba779e78 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -257,6 +257,7 @@ #include "code\datums\browser.dm" #include "code\datums\callback.dm" #include "code\datums\cinematic.dm" +#include "code\datums\dash_weapon.dm" #include "code\datums\datacore.dm" #include "code\datums\datum.dm" #include "code\datums\datumvars.dm" From 460fea66c86b0277bf2e5f3e805fcbd987cbad7f Mon Sep 17 00:00:00 2001 From: bawhoppen Date: Wed, 4 Oct 2017 11:59:27 -0500 Subject: [PATCH 3/9] Moves all stack object sprites from items_and_weapons.dmi to their own file --- code/game/objects/items/stacks/medical.dm | 2 +- .../game/objects/items/stacks/sheets/mineral.dm | 2 +- code/game/objects/items/stacks/stack.dm | 1 + icons/obj/stack_objects.dmi | Bin 0 -> 27430 bytes 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 icons/obj/stack_objects.dmi diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 02d835da16..6c073f4b69 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -1,7 +1,7 @@ /obj/item/stack/medical name = "medical pack" singular_name = "medical pack" - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' amount = 6 max_amount = 6 w_class = WEIGHT_CLASS_TINY diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 8056674074..2bb5d110fc 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ /obj/item/stack/sheet/mineral/sandbags name = "sandbags" - icon = 'icons/obj/items_and_weapons.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "sandbags" singular_name = "sandbag" layer = LOW_ITEM_LAYER diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 3a79ce23db..6e7ffddeb3 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -8,6 +8,7 @@ * Stacks */ /obj/item/stack + icon = 'icons/obj/stack_objects.dmi' origin_tech = "materials=1" gender = PLURAL var/list/datum/stack_recipe/recipes diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f21c6c75797bf7f4c9307f0715e384c1fb8c849a GIT binary patch literal 27430 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�(YybZ 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 literal 0 HcmV?d00001 From 441514937e15c78bc7cc204663af25eecb67b459 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 4 Oct 2017 13:19:18 -0400 Subject: [PATCH 4/9] Moves laughter to the emote --- code/modules/mob/living/emote.dm | 347 ++++++++++++++++++ .../chemistry/reagents/drink_reagents.dm | 13 +- 2 files changed, 348 insertions(+), 12 deletions(-) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index db47d43bd5..3912f68955 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //The code execution of the emote datum is located at code/datums/emotes.dm /mob/living/emote(act, m_type = null, message = null) act = lowertext(act) @@ -326,6 +327,352 @@ /datum/emote/living/surrender key = "surrender" key_third_person = "surrenders" +======= +//The code execution of the emote datum is located at code/datums/emotes.dm +/mob/living/emote(act, m_type = null, message = null) + act = lowertext(act) + var/param = message + var/custom_param = findchar(act, " ") + if(custom_param) + param = copytext(act, custom_param + 1, length(act) + 1) + act = copytext(act, 1, custom_param) + + var/datum/emote/E + E = E.emote_list[act] + if(!E) + to_chat(src, "Unusable emote '[act]'. Say *help for a list.") + return + E.run_emote(src, param, m_type) + +/* EMOTE DATUMS */ +/datum/emote/living + mob_type_allowed_typecache = list(/mob/living) + mob_type_blacklist_typecache = list(/mob/living/simple_animal/slime, /mob/living/brain) + +/datum/emote/living/blush + key = "blush" + key_third_person = "blushes" + message = "blushes." + +/datum/emote/living/bow + key = "bow" + key_third_person = "bows" + message = "bows." + message_param = "bows to %t." + +/datum/emote/living/burp + key = "burp" + key_third_person = "burps" + message = "burps." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/choke + key = "choke" + key_third_person = "chokes" + message = "chokes!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/cross + key = "cross" + key_third_person = "crosses" + message = "crosses their arms." + restraint_check = TRUE + +/datum/emote/living/chuckle + key = "chuckle" + key_third_person = "chuckles" + message = "chuckles." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/collapse + key = "collapse" + key_third_person = "collapses" + message = "collapses!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/collapse/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.Unconscious(40) + +/datum/emote/living/cough + key = "cough" + key_third_person = "coughs" + message = "coughs!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/dance + key = "dance" + key_third_person = "dances" + message = "dances around happily." + restraint_check = TRUE + +/datum/emote/living/deathgasp + key = "deathgasp" + key_third_person = "deathgasps" + message = "seizes up and falls limp, their eyes dead and lifeless..." + message_robot = "shudders violently for a moment before falling still, its eyes slowly darkening." + message_AI = "lets out a flurry of sparks, its screen flickering as its systems slowly halt." + message_alien = "lets out a waning guttural screech, green blood bubbling from its maw..." + message_larva = "lets out a sickly hiss of air and falls limply to the floor..." + message_monkey = "lets out a faint chimper as it collapses and stops moving..." + message_simple = "stops moving..." + stat_allowed = UNCONSCIOUS + +/datum/emote/living/deathgasp/run_emote(mob/user, params) + var/mob/living/simple_animal/S = user + if(istype(S) && S.deathmessage) + message_simple = S.deathmessage + . = ..() + message_simple = initial(message_simple) + if(. && isalienadult(user)) + playsound(user.loc, 'sound/voice/hiss6.ogg', 80, 1, 1) + +/datum/emote/living/drool + key = "drool" + key_third_person = "drools" + message = "drools." + +/datum/emote/living/faint + key = "faint" + key_third_person = "faints" + message = "faints." + +/datum/emote/living/faint/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.SetSleeping(200) + +/datum/emote/living/flap + key = "flap" + key_third_person = "flaps" + message = "flaps their wings." + var/wing_time = 20 + +/datum/emote/living/flap/run_emote(mob/user, params) + . = ..() + if(. && ishuman(user)) + var/mob/living/carbon/human/H = user + var/open = FALSE + if(H.dna.features["wings"] != "None") + if("wingsopen" in H.dna.species.mutant_bodyparts) + open = TRUE + H.CloseWings() + else + H.OpenWings() + addtimer(CALLBACK(H, open ? /mob/living/carbon/human.proc/OpenWings : /mob/living/carbon/human.proc/CloseWings), wing_time) + +/datum/emote/living/flap/aflap + key = "aflap" + key_third_person = "aflaps" + message = "flaps their wings ANGRILY!" + wing_time = 10 + +/datum/emote/living/flip + key = "flip" + key_third_person = "flips" + restraint_check = TRUE + +/datum/emote/living/flip/run_emote(mob/user, params) + . = ..() + if(!.) + user.SpinAnimation(7,1) + +/datum/emote/living/frown + key = "frown" + key_third_person = "frowns" + message = "frowns." + +/datum/emote/living/gag + key = "gag" + key_third_person = "gags" + message = "gags." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/gasp + key = "gasp" + key_third_person = "gasps" + message = "gasps!" + emote_type = EMOTE_AUDIBLE + stat_allowed = UNCONSCIOUS + +/datum/emote/living/giggle + key = "giggle" + key_third_person = "giggles" + message = "giggles." + message_mime = "giggles silently!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/glare + key = "glare" + key_third_person = "glares" + message = "glares." + message_param = "glares at %t." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/grin + key = "grin" + key_third_person = "grins" + message = "grins." + +/datum/emote/living/groan + key = "groan" + key_third_person = "groans" + message = "groans!" + message_mime = "appears to groan!" + +/datum/emote/living/grimace + key = "grimace" + key_third_person = "grimaces" + message = "grimaces." + +/datum/emote/living/jump + key = "jump" + key_third_person = "jumps" + message = "jumps!" + restraint_check = TRUE + +/datum/emote/living/kiss + key = "kiss" + key_third_person = "kisses" + message = "blows a kiss." + message_param = "blows a kiss to %t." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/laugh + key = "laugh" + key_third_person = "laughs" + message = "laughs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/laugh/can_run_emote(mob/living/user) + . = ..() + if(. && iscarbon(user)) + var/mob/living/carbon/C = user + return !C.silent + +/datum/emote/living/laugh/run_emote(mob/user, params) + . = ..() + if(. && ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.dna.species.id == "human") + if(user.gender == FEMALE) + playsound(H, 'sound/voice/human/womanlaugh.ogg', 50, 1) + else + playsound(H, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) + +/datum/emote/living/look + key = "look" + key_third_person = "looks" + message = "looks." + message_param = "looks at %t." + +/datum/emote/living/nod + key = "nod" + key_third_person = "nods" + message = "nods." + message_param = "nods at %t." + +/datum/emote/living/point + key = "point" + key_third_person = "points" + message = "points." + message_param = "points at %t." + restraint_check = TRUE + +/datum/emote/living/pout + key = "pout" + key_third_person = "pouts" + message = "pouts." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/scream + key = "scream" + key_third_person = "screams" + message = "screams." + message_mime = "acts out a scream!" + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/scowl + key = "scowl" + key_third_person = "scowls" + message = "scowls." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/shake + key = "shake" + key_third_person = "shakes" + message = "shakes their head." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/shiver + key = "shiver" + key_third_person = "shiver" + message = "shivers." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/sigh + key = "sigh" + key_third_person = "sighs" + message = "sighs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/sit + key = "sit" + key_third_person = "sits" + message = "sits down." + +/datum/emote/living/smile + key = "smile" + key_third_person = "smiles" + message = "smiles." + +/datum/emote/living/sneeze + key = "sneeze" + key_third_person = "sneezes" + message = "sneezes." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/smug + key = "smug" + key_third_person = "smugs" + message = "grins smugly." + +/datum/emote/living/sniff + key = "sniff" + key_third_person = "sniffs" + message = "sniffs." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/snore + key = "snore" + key_third_person = "snores" + message = "snores." + message_mime = "sleeps soundly." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/stare + key = "stare" + key_third_person = "stares" + message = "stares." + message_param = "stares at %t." + +/datum/emote/living/strech + key = "stretch" + key_third_person = "stretches" + message = "stretches their arms." + +/datum/emote/living/sulk + key = "sulk" + key_third_person = "sulks" + message = "sulks down sadly." + +/datum/emote/living/surrender + key = "surrender" + key_third_person = "surrenders" +>>>>>>> 32050be... Moves laughter to the emote (#31276) message = "puts their hands on their head and falls to the ground, they surrender!" emote_type = EMOTE_AUDIBLE diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index a3db8f7bc2..308fd47a16 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -169,18 +169,7 @@ /datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/M) if(!iscarbon(M)) return - if(!M.silent)//cant laugh if you're mute - M.emote("laugh") - var/laughnum = rand(1,2) - if(M.gender == MALE) - if(laughnum == 1) - playsound(get_turf(M), 'sound/voice/human/manlaugh1.ogg', 50, 1) - if(laughnum == 2) - playsound(get_turf(M), 'sound/voice/human/manlaugh2.ogg', 50, 1) - else if(M.gender == FEMALE) - playsound(get_turf(M), 'sound/voice/human/womanlaugh.ogg', 65, 1) - else//non-binary gender just sounds like a man - playsound(get_turf(M), 'sound/voice/human/manlaugh1.ogg', 50, 1) + M.emote("laugh") ..() /datum/reagent/consumable/potato_juice From 77c422d01148a31f8951a901525a79c73bcc3cdf Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 4 Oct 2017 16:11:24 -0500 Subject: [PATCH 5/9] Update emote.dm --- code/modules/mob/living/emote.dm | 660 ++++++++----------------------- 1 file changed, 165 insertions(+), 495 deletions(-) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 3912f68955..3e1724150a 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -1,333 +1,4 @@ -<<<<<<< HEAD -//The code execution of the emote datum is located at code/datums/emotes.dm -/mob/living/emote(act, m_type = null, message = null) - act = lowertext(act) - var/param = message - var/custom_param = findchar(act, " ") - if(custom_param) - param = copytext(act, custom_param + 1, length(act) + 1) - act = copytext(act, 1, custom_param) - - var/datum/emote/E - E = E.emote_list[act] - if(!E) - to_chat(src, "Unusable emote '[act]'. Say *help for a list.") - return - E.run_emote(src, param, m_type) - -/* EMOTE DATUMS */ -/datum/emote/living - mob_type_allowed_typecache = list(/mob/living) - mob_type_blacklist_typecache = list(/mob/living/simple_animal/slime, /mob/living/brain) - -/datum/emote/living/blush - key = "blush" - key_third_person = "blushes" - message = "blushes." - -/datum/emote/living/bow - key = "bow" - key_third_person = "bows" - message = "bows." - message_param = "bows to %t." - -/datum/emote/living/burp - key = "burp" - key_third_person = "burps" - message = "burps." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/choke - key = "choke" - key_third_person = "chokes" - message = "chokes!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/cross - key = "cross" - key_third_person = "crosses" - message = "crosses their arms." - restraint_check = TRUE - -/datum/emote/living/chuckle - key = "chuckle" - key_third_person = "chuckles" - message = "chuckles." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/collapse - key = "collapse" - key_third_person = "collapses" - message = "collapses!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/collapse/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.Unconscious(40) - -/datum/emote/living/cough - key = "cough" - key_third_person = "coughs" - message = "coughs!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/dance - key = "dance" - key_third_person = "dances" - message = "dances around happily." - restraint_check = TRUE - -/datum/emote/living/deathgasp - key = "deathgasp" - key_third_person = "deathgasps" - message = "seizes up and falls limp, their eyes dead and lifeless..." - message_robot = "shudders violently for a moment before falling still, its eyes slowly darkening." - message_AI = "lets out a flurry of sparks, its screen flickering as its systems slowly halt." - message_alien = "lets out a waning guttural screech, green blood bubbling from its maw..." - message_larva = "lets out a sickly hiss of air and falls limply to the floor..." - message_monkey = "lets out a faint chimper as it collapses and stops moving..." - message_simple = "stops moving..." - stat_allowed = UNCONSCIOUS - -/datum/emote/living/deathgasp/run_emote(mob/user, params) - var/mob/living/simple_animal/S = user - if(istype(S) && S.deathmessage) - message_simple = S.deathmessage - . = ..() - message_simple = initial(message_simple) - if(. && isalienadult(user)) - playsound(user.loc, 'sound/voice/hiss6.ogg', 80, 1, 1) - -/datum/emote/living/drool - key = "drool" - key_third_person = "drools" - message = "drools." - -/datum/emote/living/faint - key = "faint" - key_third_person = "faints" - message = "faints." - -/datum/emote/living/faint/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.SetSleeping(200) - -/datum/emote/living/flap - key = "flap" - key_third_person = "flaps" - message = "flaps their wings." - var/wing_time = 20 - -/datum/emote/living/flap/run_emote(mob/user, params) - . = ..() - if(. && ishuman(user)) - var/mob/living/carbon/human/H = user - var/open = FALSE - if(H.dna.features["wings"] != "None") - if("wingsopen" in H.dna.species.mutant_bodyparts) - open = TRUE - H.CloseWings() - else - H.OpenWings() - addtimer(CALLBACK(H, open ? /mob/living/carbon/human.proc/OpenWings : /mob/living/carbon/human.proc/CloseWings), wing_time) - -/datum/emote/living/flap/aflap - key = "aflap" - key_third_person = "aflaps" - message = "flaps their wings ANGRILY!" - wing_time = 10 - -/datum/emote/living/flip - key = "flip" - key_third_person = "flips" - restraint_check = TRUE - -/datum/emote/living/flip/run_emote(mob/user, params) - . = ..() - if(!.) - user.SpinAnimation(7,1) - -/datum/emote/living/frown - key = "frown" - key_third_person = "frowns" - message = "frowns." - -/datum/emote/living/gag - key = "gag" - key_third_person = "gags" - message = "gags." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/gasp - key = "gasp" - key_third_person = "gasps" - message = "gasps!" - emote_type = EMOTE_AUDIBLE - stat_allowed = UNCONSCIOUS - -/datum/emote/living/giggle - key = "giggle" - key_third_person = "giggles" - message = "giggles." - message_mime = "giggles silently!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/glare - key = "glare" - key_third_person = "glares" - message = "glares." - message_param = "glares at %t." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/grin - key = "grin" - key_third_person = "grins" - message = "grins." - -/datum/emote/living/groan - key = "groan" - key_third_person = "groans" - message = "groans!" - message_mime = "appears to groan!" - -/datum/emote/living/grimace - key = "grimace" - key_third_person = "grimaces" - message = "grimaces." - -/datum/emote/living/jump - key = "jump" - key_third_person = "jumps" - message = "jumps!" - restraint_check = TRUE - -/datum/emote/living/kiss - key = "kiss" - key_third_person = "kisses" - message = "blows a kiss." - message_param = "blows a kiss to %t." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/laugh - key = "laugh" - key_third_person = "laughs" - message = "laughs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/look - key = "look" - key_third_person = "looks" - message = "looks." - message_param = "looks at %t." - -/datum/emote/living/nod - key = "nod" - key_third_person = "nods" - message = "nods." - message_param = "nods at %t." - -/datum/emote/living/point - key = "point" - key_third_person = "points" - message = "points." - message_param = "points at %t." - restraint_check = TRUE - -/datum/emote/living/pout - key = "pout" - key_third_person = "pouts" - message = "pouts." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/scream - key = "scream" - key_third_person = "screams" - message = "screams." - message_mime = "acts out a scream!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/scowl - key = "scowl" - key_third_person = "scowls" - message = "scowls." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/shake - key = "shake" - key_third_person = "shakes" - message = "shakes their head." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/shiver - key = "shiver" - key_third_person = "shiver" - message = "shivers." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/sigh - key = "sigh" - key_third_person = "sighs" - message = "sighs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/sit - key = "sit" - key_third_person = "sits" - message = "sits down." - -/datum/emote/living/smile - key = "smile" - key_third_person = "smiles" - message = "smiles." - -/datum/emote/living/sneeze - key = "sneeze" - key_third_person = "sneezes" - message = "sneezes." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/smug - key = "smug" - key_third_person = "smugs" - message = "grins smugly." - -/datum/emote/living/sniff - key = "sniff" - key_third_person = "sniffs" - message = "sniffs." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/snore - key = "snore" - key_third_person = "snores" - message = "snores." - message_mime = "sleeps soundly." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/stare - key = "stare" - key_third_person = "stares" - message = "stares." - message_param = "stares at %t." - -/datum/emote/living/strech - key = "stretch" - key_third_person = "stretches" - message = "stretches their arms." - -/datum/emote/living/sulk - key = "sulk" - key_third_person = "sulks" - message = "sulks down sadly." - -/datum/emote/living/surrender - key = "surrender" - key_third_person = "surrenders" -======= +<<<<<<< HEAD //The code execution of the emote datum is located at code/datums/emotes.dm /mob/living/emote(act, m_type = null, message = null) act = lowertext(act) @@ -672,169 +343,168 @@ /datum/emote/living/surrender key = "surrender" key_third_person = "surrenders" ->>>>>>> 32050be... Moves laughter to the emote (#31276) message = "puts their hands on their head and falls to the ground, they surrender!" - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/surrender/run_emote(mob/user, params) - . = ..() - if(. && isliving(user)) - var/mob/living/L = user - L.Knockdown(200) - -/datum/emote/living/sway - key = "sway" - key_third_person = "sways" - message = "sways around dizzily." - -/datum/emote/living/tremble - key = "tremble" - key_third_person = "trembles" - message = "trembles in fear!" - -/datum/emote/living/twitch - key = "twitch" - key_third_person = "twitches" - message = "twitches violently." - -/datum/emote/living/twitch_s - key = "twitch_s" - message = "twitches." - -/datum/emote/living/wave - key = "wave" - key_third_person = "waves" - message = "waves." - -/datum/emote/living/whimper - key = "whimper" - key_third_person = "whimpers" - message = "whimpers." - message_mime = "appears hurt." - -/datum/emote/living/wsmile - key = "wsmile" - key_third_person = "wsmiles" - message = "smiles weakly." - -/datum/emote/living/yawn - key = "yawn" - key_third_person = "yawns" - message = "yawns." - emote_type = EMOTE_AUDIBLE - -/datum/emote/living/custom - key = "me" - key_third_person = "custom" - message = null - -/datum/emote/living/custom/proc/check_invalid(mob/user, input) - . = TRUE - if(copytext(input,1,5) == "says") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,9) == "exclaims") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,6) == "yells") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,5) == "asks") - to_chat(user, "Invalid emote.") - else - . = FALSE - -/datum/emote/living/custom/run_emote(mob/user, params, type_override = null) - if(jobban_isbanned(user, "emote")) - to_chat(user, "You cannot send custom emotes (banned).") - return FALSE - else if(user.client && user.client.prefs.muted & MUTE_IC) - to_chat(user, "You cannot send IC messages (muted).") - return FALSE - else if(!params) - var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN) - if(custom_emote && !check_invalid(user, custom_emote)) - var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") - switch(type) - if("Visible") - emote_type = EMOTE_VISIBLE - if("Hearable") - emote_type = EMOTE_AUDIBLE - else - alert("Unable to use this emote, must be either hearable or visible.") - return - message = custom_emote - else - message = params - if(type_override) - emote_type = type_override - . = ..() - message = null - emote_type = EMOTE_VISIBLE - -/datum/emote/living/custom/replace_pronoun(mob/user, message) - return message - -/datum/emote/living/help - key = "help" - -/datum/emote/living/help/run_emote(mob/user, params) - var/list/keys = list() - var/list/message = list("Available emotes, you can use them with say \"*emote\": ") - - var/datum/emote/E - var/list/emote_list = E.emote_list - for(var/e in emote_list) - if(e in keys) - continue - E = emote_list[e] - if(E.can_run_emote(user, TRUE)) - keys += E.key - - keys = sortList(keys) - - for(var/emote in keys) - if(LAZYLEN(message) > 1) - message += ", [emote]" - else - message += "[emote]" - - message += "." - - message = jointext(message, "") - - to_chat(user, message) - -/datum/emote/sound/beep - key = "beep" - key_third_person = "beeps" - message = "beeps." - message_param = "beeps at %t." - sound = 'sound/machines/twobeep.ogg' - -/datum/emote/living/spin - key = "spin" - key_third_person = "spins" - -/datum/emote/living/spin/run_emote(mob/user) - user.spin(20, 1) - if(iscyborg(user)) - var/mob/living/silicon/robot/R = user - if(R.buckled_mobs) - for(var/mob/M in R.buckled_mobs) - if(R.riding_datum) - R.riding_datum.force_dismount(M) - else - R.unbuckle_all_mobs() - ..() - -/datum/emote/living/circle - key = "circle" - key_third_person = "circles" - restraint_check = TRUE - -/datum/emote/living/circle/run_emote(mob/user, params) - . = ..() - var/obj/item/circlegame/N = new(user) - if(user.put_in_hands(N)) - to_chat(user, "You make a circle with your hand.") - else - qdel(N) - to_chat(user, "You don't have any free hands to make a circle with.") + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/surrender/run_emote(mob/user, params) + . = ..() + if(. && isliving(user)) + var/mob/living/L = user + L.Knockdown(200) + +/datum/emote/living/sway + key = "sway" + key_third_person = "sways" + message = "sways around dizzily." + +/datum/emote/living/tremble + key = "tremble" + key_third_person = "trembles" + message = "trembles in fear!" + +/datum/emote/living/twitch + key = "twitch" + key_third_person = "twitches" + message = "twitches violently." + +/datum/emote/living/twitch_s + key = "twitch_s" + message = "twitches." + +/datum/emote/living/wave + key = "wave" + key_third_person = "waves" + message = "waves." + +/datum/emote/living/whimper + key = "whimper" + key_third_person = "whimpers" + message = "whimpers." + message_mime = "appears hurt." + +/datum/emote/living/wsmile + key = "wsmile" + key_third_person = "wsmiles" + message = "smiles weakly." + +/datum/emote/living/yawn + key = "yawn" + key_third_person = "yawns" + message = "yawns." + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/custom + key = "me" + key_third_person = "custom" + message = null + +/datum/emote/living/custom/proc/check_invalid(mob/user, input) + . = TRUE + if(copytext(input,1,5) == "says") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,9) == "exclaims") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,6) == "yells") + to_chat(user, "Invalid emote.") + else if(copytext(input,1,5) == "asks") + to_chat(user, "Invalid emote.") + else + . = FALSE + +/datum/emote/living/custom/run_emote(mob/user, params, type_override = null) + if(jobban_isbanned(user, "emote")) + to_chat(user, "You cannot send custom emotes (banned).") + return FALSE + else if(user.client && user.client.prefs.muted & MUTE_IC) + to_chat(user, "You cannot send IC messages (muted).") + return FALSE + else if(!params) + var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN) + if(custom_emote && !check_invalid(user, custom_emote)) + var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") + switch(type) + if("Visible") + emote_type = EMOTE_VISIBLE + if("Hearable") + emote_type = EMOTE_AUDIBLE + else + alert("Unable to use this emote, must be either hearable or visible.") + return + message = custom_emote + else + message = params + if(type_override) + emote_type = type_override + . = ..() + message = null + emote_type = EMOTE_VISIBLE + +/datum/emote/living/custom/replace_pronoun(mob/user, message) + return message + +/datum/emote/living/help + key = "help" + +/datum/emote/living/help/run_emote(mob/user, params) + var/list/keys = list() + var/list/message = list("Available emotes, you can use them with say \"*emote\": ") + + var/datum/emote/E + var/list/emote_list = E.emote_list + for(var/e in emote_list) + if(e in keys) + continue + E = emote_list[e] + if(E.can_run_emote(user, TRUE)) + keys += E.key + + keys = sortList(keys) + + for(var/emote in keys) + if(LAZYLEN(message) > 1) + message += ", [emote]" + else + message += "[emote]" + + message += "." + + message = jointext(message, "") + + to_chat(user, message) + +/datum/emote/sound/beep + key = "beep" + key_third_person = "beeps" + message = "beeps." + message_param = "beeps at %t." + sound = 'sound/machines/twobeep.ogg' + +/datum/emote/living/spin + key = "spin" + key_third_person = "spins" + +/datum/emote/living/spin/run_emote(mob/user) + user.spin(20, 1) + if(iscyborg(user)) + var/mob/living/silicon/robot/R = user + if(R.buckled_mobs) + for(var/mob/M in R.buckled_mobs) + if(R.riding_datum) + R.riding_datum.force_dismount(M) + else + R.unbuckle_all_mobs() + ..() + +/datum/emote/living/circle + key = "circle" + key_third_person = "circles" + restraint_check = TRUE + +/datum/emote/living/circle/run_emote(mob/user, params) + . = ..() + var/obj/item/circlegame/N = new(user) + if(user.put_in_hands(N)) + to_chat(user, "You make a circle with your hand.") + else + qdel(N) + to_chat(user, "You don't have any free hands to make a circle with.") From cfd98caf9801a875004443dd13933e7d7523034b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 4 Oct 2017 17:42:38 -0500 Subject: [PATCH 6/9] Update emote.dm --- code/modules/mob/living/emote.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 3e1724150a..9f31c5b055 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD //The code execution of the emote datum is located at code/datums/emotes.dm /mob/living/emote(act, m_type = null, message = null) act = lowertext(act) From f57929b26c008f478a28dd9606f8c178fef3fd21 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 4 Oct 2017 21:14:25 -0500 Subject: [PATCH 7/9] Update book.dm --- code/game/objects/items/storage/book.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 28856e17d8..c0c861f4c4 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1) if(do_after(user, 40, target = sword)) playsound(src,'sound/effects/pray_chaplain.ogg',60,1) - for(var/obj/item/device/soulstone/SS in sword.shards) + for(var/obj/item/device/soulstone/SS in sword.contents) SS.usability = TRUE for(var/mob/living/simple_animal/shade/EX in SS) SSticker.mode.remove_cultist(EX.mind, 1, 0) From 7c4373c1fe257c32237ecda756bc7a6241ef23f4 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 4 Oct 2017 21:15:11 -0500 Subject: [PATCH 8/9] Update cult_items.dm --- code/game/gamemodes/cult/cult_items.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 62fe64ecee..2780598d06 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -163,7 +163,7 @@ /obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters) . = ..() - if(dash_toggled) + if(dash_toggled && jaunt.IsAvailable()) jaunt.Teleport(user, target) return if(!proximity) @@ -193,7 +193,7 @@ phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out /datum/action/innate/dash/cult/IsAvailable() - if(iscultist(holder) && current_charges) + if(iscultist(holder) && charged) return TRUE else return FALSE From c2d8f048f864a2bf1e0246f9f453bef8814f6481 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Wed, 4 Oct 2017 21:49:46 -0500 Subject: [PATCH 9/9] Update cult_items.dm --- code/game/gamemodes/cult/cult_items.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 2780598d06..a3da1c6cbe 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -193,7 +193,7 @@ phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out /datum/action/innate/dash/cult/IsAvailable() - if(iscultist(holder) && charged) + if(iscultist(holder) && current_charges) return TRUE else return FALSE