Merge branch 'master' into spike-loot-differentces

This commit is contained in:
Trilbyspaceclone
2020-08-12 15:10:37 -04:00
committed by GitHub
760 changed files with 27169 additions and 10617 deletions
@@ -791,6 +791,10 @@
name = "Volaju"
icon_state = "hair_volaju"
/datum/sprite_accessory/hair/volajupompless
name = "Volaju (Alt)"
icon_state = "hair_volajupompless"
/datum/sprite_accessory/hair/wisp
name = "Wisp"
icon_state = "hair_wisp"
@@ -184,6 +184,12 @@
extra = TRUE
extra_color_src = MUTCOLORS3
/datum/sprite_accessory/mam_snouts/skulldog
name = "Skulldog"
icon_state = "skulldog"
extra = TRUE
extra_color_src = MATRIXED
/datum/sprite_accessory/mam_snouts/lcanid
name = "Mammal, Long"
icon_state = "lcanid"
@@ -3,12 +3,10 @@
set name = "Notification preferences"
set desc = "Notification preferences"
var/datum/notificationpanel/panel = new(usr)
var/datum/notificationpanel/panel = new(usr)
panel.ui_interact(usr)
/datum/notificationpanel
var/client/user
@@ -21,10 +19,13 @@
else
src.user = user
/datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/datum/notificationpanel/ui_state(mob/user)
return GLOB.observer_state
/datum/notificationpanel/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "NotificationPreferences", "Notification Preferences", 270, 360, master_ui, state)
ui = new(user, src, "NotificationPreferences")
ui.open()
/datum/notificationpanel/ui_data(mob/user)
@@ -35,8 +36,7 @@
"key" = key,
"enabled" = (user.ckey in GLOB.poll_ignore[key]),
"desc" = GLOB.poll_ignore_desc[key]
))
))
/datum/notificationpanel/ui_act(action, params)
if(..())
@@ -905,6 +905,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
to_chat(usr, "Can't become a pAI candidate while not dead!")
/mob/dead/observer/verb/mafia_game_signup()
set category = "Ghost"
set name = "Signup for Mafia"
set desc = "Sign up for a game of Mafia to pass the time while dead."
mafia_signup()
/mob/dead/observer/proc/mafia_signup()
if(!client)
return
if(!isobserver(src))
to_chat(usr, "<span class='warning'>You must be a ghost to join mafia!</span>")
return
var/datum/mafia_controller/game = GLOB.mafia_game //this needs to change if you want multiple mafia games up at once.
if(!game)
game = create_mafia_game("mafia")
game.ui_interact(usr)
/mob/dead/observer/CtrlShiftClick(mob/user)
if(isobserver(user) && check_rights(R_SPAWN))
change_mob_type( /mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering
+9 -5
View File
@@ -6,9 +6,12 @@
qdel(src)
owner = new_owner
/datum/orbit_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
/datum/orbit_menu/ui_state(mob/user)
return GLOB.observer_state
/datum/orbit_menu/ui_interact(mob/user, datum/tgui/ui)
if (!ui)
ui = new(user, src, ui_key, "Orbit", "Orbit", 350, 700, master_ui, state)
ui = new(user, src, "Orbit")
ui.open()
/datum/orbit_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
@@ -16,11 +19,10 @@
return
if (action == "orbit")
var/list/pois = getpois(skip_mindless = 1)
var/atom/movable/poi = pois[params["name"]]
var/ref = params["ref"]
var/atom/movable/poi = (locate(ref) in GLOB.mob_list) || (locate(ref) in GLOB.poi_list)
if (poi != null)
owner.ManualFollow(poi)
ui.close()
/datum/orbit_menu/ui_data(mob/user)
var/list/data = list()
@@ -39,6 +41,8 @@
var/poi = pois[name]
serialized["ref"] = REF(poi)
var/mob/M = poi
if (istype(M))
if (isobserver(M))
-4
View File
@@ -62,10 +62,6 @@
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
switch(blood_volume)
if(BLOOD_VOLUME_EXCESS to BLOOD_VOLUME_MAX_LETHAL)
if(prob(15))
to_chat(src, "<span class='userdanger'>Blood starts to tear your skin apart. You're going to burst!</span>")
gib()
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
if(prob(10))
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
@@ -1042,7 +1042,7 @@
/mob/living/carbon/human/updatehealth()
. = ..()
dna?.species.spec_updatehealth(src)
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN)) //if we want to ignore slowdown from damage and equipment
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
@@ -1199,6 +1199,9 @@
/mob/living/carbon/human/species/lizard
race = /datum/species/lizard
/mob/living/carbon/human/species/ethereal
race = /datum/species/ethereal
/mob/living/carbon/human/species/lizard/ashwalker
race = /datum/species/lizard/ashwalker
@@ -336,7 +336,8 @@
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(30, 120)
Unconscious(20) //short amount of time for follow up attacks against elusive enemies like wizards
Knockdown(200 - (bomb_armor * 1.6)) //between ~4 and ~20 seconds of knockdown depending on bomb armor
Knockdown((200 - (bomb_armor * 1.6)) / 4) //between ~1 and ~5 seconds of knockdown depending on bomb armor
adjustStaminaLoss(brute_loss)
if(EXPLODE_LIGHT)
brute_loss = 30
@@ -345,7 +346,8 @@
damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb")
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(15,60)
Knockdown(160 - (bomb_armor * 1.6)) //100 bomb armor will prevent knockdown altogether
Knockdown((160 - (bomb_armor * 1.6)) / 4) //100 bomb armor will prevent knockdown altogether
adjustStaminaLoss(brute_loss)
take_overall_damage(brute_loss,burn_loss)
@@ -169,7 +169,7 @@
//Item is handled and in slot, valid to call callback, for this proc should always be true
if(!not_handled)
I.equipped(src, slot)
update_genitals()
return not_handled //For future deeper overrides
/mob/living/carbon/human/equipped_speed_mods()
@@ -257,6 +257,7 @@
s_store = null
if(!QDELETED(src))
update_inv_s_store()
update_genitals()
/mob/living/carbon/human/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR)))
@@ -56,6 +56,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/list/mutant_organs = list() //Internal organs that are unique to this race.
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
var/armor = 0 // overall defense for the race... or less defense, if it's negative.
var/attack_type = BRUTE // the type of damage unarmed attacks from this species do
var/brutemod = 1 // multiplier for brute damage
var/burnmod = 1 // multiplier for burn damage
var/coldmod = 1 // multiplier for cold damage
@@ -1364,6 +1365,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
if(hungry >= 70)
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50))
else if(isethereal(H))
var/datum/species/ethereal/E = H.dna.species
if(E.get_charge(H) <= ETHEREAL_CHARGE_NORMAL)
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (1.5 * (1 - E.get_charge(H) / 100)))
else
H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger)
@@ -1420,6 +1425,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
// ATTACK PROCS //
//////////////////
/datum/species/proc/spec_updatehealth(mob/living/carbon/human/H)
return
/datum/species/proc/spec_fully_heal(mob/living/carbon/human/H)
return
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.health >= 0 && !HAS_TRAIT(target, TRAIT_FAKEDEATH))
target.help_shake_act(user)
@@ -1538,11 +1549,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.dismembering_strike(user, affecting.body_zone)
if(atk_verb == ATTACK_EFFECT_KICK)//kicks deal 1.5x raw damage + 0.5x stamina damage
target.apply_damage(damage*1.5, BRUTE, affecting, armor_block)
target.apply_damage(damage*1.5, attack_type, affecting, armor_block)
target.apply_damage(damage*0.5, STAMINA, affecting, armor_block)
log_combat(user, target, "kicked")
else//other attacks deal full raw damage + 2x in stamina damage
target.apply_damage(damage, BRUTE, affecting, armor_block)
target.apply_damage(damage, attack_type, affecting, armor_block)
target.apply_damage(damage*2, STAMINA, affecting, armor_block)
log_combat(user, target, "punched")
@@ -0,0 +1,182 @@
#define ETHEREAL_COLORS list("#00ffff", "#ffc0cb", "#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000")
/datum/species/ethereal
name = "Ethereal"
id = "ethereal"
attack_verb = "burn"
attack_sound = 'sound/weapons/etherealhit.ogg'
miss_sound = 'sound/weapons/etherealmiss.ogg'
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ethereal
mutantstomach = /obj/item/organ/stomach/ethereal
mutanttongue = /obj/item/organ/tongue/ethereal
exotic_blood = /datum/reagent/consumable/liquidelectricity //Liquid Electricity. fuck you think of something better gamer
siemens_coeff = 0.5 //They thrive on energy
brutemod = 1.25 //They're weak to punches
attack_type = BURN //burn bish
damage_overlay_type = "" //We are too cool for regular damage overlays
species_traits = list(MUTCOLORS, NO_UNDERWEAR, HAIR, HAS_FLESH, HAS_BONE) // i mean i guess they have blood so they can have wounds too
species_language_holder = /datum/language_holder/ethereal
inherent_traits = list(TRAIT_NOHUNGER)
sexes = FALSE
toxic_food = NONE
/*
citadel doesn't have per-species temperatures, yet
// Body temperature for ethereals is much higher then humans as they like hotter environments
bodytemp_normal = (BODYTEMP_NORMAL + 50)
bodytemp_heat_damage_limit = FIRE_MINIMUM_TEMPERATURE_TO_SPREAD // about 150C
// Cold temperatures hurt faster as it is harder to move with out the heat energy
bodytemp_cold_damage_limit = (T20C - 10) // about 10c
*/
hair_color = "fixedmutcolor"
hair_alpha = 140
var/current_color
var/EMPeffect = FALSE
var/emageffect = FALSE
var/r1
var/g1
var/b1
var/static/r2 = 237
var/static/g2 = 164
var/static/b2 = 149
//this is shit but how do i fix it? no clue.
var/drain_time = 0 //used to keep ethereals from spam draining power sources
/datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
.=..()
if(ishuman(C))
var/mob/living/carbon/human/H = C
default_color = "#" + H.dna.features["mcolor"]
r1 = GETREDPART(default_color)
g1 = GETGREENPART(default_color)
b1 = GETBLUEPART(default_color)
spec_updatehealth(H)
RegisterSignal(C, COMSIG_ATOM_EMAG_ACT, .proc/on_emag_act)
RegisterSignal(C, COMSIG_ATOM_EMP_ACT, .proc/on_emp_act)
/datum/species/ethereal/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
.=..()
C.set_light(0)
UnregisterSignal(C, COMSIG_ATOM_EMAG_ACT)
UnregisterSignal(C, COMSIG_ATOM_EMP_ACT)
/datum/species/ethereal/random_name(gender,unique,lastname)
if(unique)
return random_unique_ethereal_name()
var/randname = ethereal_name()
return randname
/datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/H)
.=..()
if(H.stat != DEAD && !EMPeffect)
var/healthpercent = max(H.health, 0) / 100
if(!emageffect)
current_color = rgb(r2 + ((r1-r2)*healthpercent), g2 + ((g1-g2)*healthpercent), b2 + ((b1-b2)*healthpercent))
H.set_light(1 + (2 * healthpercent), 1 + (1 * healthpercent), current_color)
fixed_mut_color = copytext_char(current_color, 2)
else
H.set_light(0)
fixed_mut_color = rgb(128,128,128)
H.update_body()
/datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/H, severity)
EMPeffect = TRUE
spec_updatehealth(H)
to_chat(H, "<span class='notice'>You feel the light of your body leave you.</span>")
switch(severity)
if(EMP_LIGHT)
addtimer(CALLBACK(src, .proc/stop_emp, H), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds
if(EMP_HEAVY)
addtimer(CALLBACK(src, .proc/stop_emp, H), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user)
if(emageffect)
return
emageffect = TRUE
if(user)
to_chat(user, "<span class='notice'>You tap [H] on the back with your card.</span>")
H.visible_message("<span class='danger'>[H] starts flickering in an array of colors!</span>")
handle_emag(H)
addtimer(CALLBACK(src, .proc/stop_emag, H), 30 SECONDS) //Disco mode for 30 seconds! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass.
/datum/species/ethereal/spec_life(mob/living/carbon/human/H)
.=..()
handle_charge(H)
/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H)
EMPeffect = FALSE
spec_updatehealth(H)
to_chat(H, "<span class='notice'>You feel more energized as your shine comes back.</span>")
/datum/species/ethereal/proc/handle_emag(mob/living/carbon/human/H)
if(!emageffect)
return
current_color = pick(ETHEREAL_COLORS)
spec_updatehealth(H)
addtimer(CALLBACK(src, .proc/handle_emag, H), 5) //Call ourselves every 0.5 seconds to change color
/datum/species/ethereal/proc/stop_emag(mob/living/carbon/human/H)
emageffect = FALSE
spec_updatehealth(H)
H.visible_message("<span class='danger'>[H] stops flickering and goes back to their normal state!</span>")
/datum/species/ethereal/proc/handle_charge(mob/living/carbon/human/H)
brutemod = 1.25
switch(get_charge(H))
if(ETHEREAL_CHARGE_NONE)
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 3)
if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 2)
if(H.health > 10.5)
apply_damage(0.65, TOX, null, null, H)
brutemod = 1.75
if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 1)
brutemod = 1.5
if(ETHEREAL_CHARGE_FULL to ETHEREAL_CHARGE_OVERLOAD)
H.throw_alert("ethereal_overcharge", /obj/screen/alert/ethereal_overcharge, 1)
apply_damage(0.2, TOX, null, null, H)
brutemod = 1.5
if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS)
H.throw_alert("ethereal_overcharge", /obj/screen/alert/ethereal_overcharge, 2)
apply_damage(0.65, TOX, null, null, H)
brutemod = 1.75
if(prob(10)) //10% each tick for ethereals to explosively release excess energy if it reaches dangerous levels
discharge_process(H)
else
H.clear_alert("ethereal_charge")
H.clear_alert("ethereal_overcharge")
/datum/species/ethereal/proc/discharge_process(mob/living/carbon/human/H)
to_chat(H, "<span class='warning'>You begin to lose control over your charge!</span>")
H.visible_message("<span class='danger'>[H] begins to spark violently!</span>")
var/static/mutable_appearance/overcharge //shameless copycode from lightning spell
overcharge = overcharge || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER)
H.add_overlay(overcharge)
if(do_mob(H, H, 50, 1))
H.flash_lighting_fx(5, 7, current_color)
var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH)
playsound(H, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
H.cut_overlay(overcharge)
tesla_zap(H, 2, stomach.crystal_charge*50, ZAP_OBJ_DAMAGE | ZAP_ALLOW_DUPLICATES)
if(istype(stomach))
stomach.adjust_charge(100 - stomach.crystal_charge)
to_chat(H, "<span class='warning'>You violently discharge energy!</span>")
H.visible_message("<span class='danger'>[H] violently discharges energy!</span>")
if(prob(10)) //chance of developing heart disease to dissuade overcharging oneself
var/datum/disease/D = new /datum/disease/heart_failure
H.ForceContractDisease(D)
to_chat(H, "<span class='userdanger'>You're pretty sure you just felt your heart stop for a second there..</span>")
H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, 0)
H.Paralyze(100)
return
/datum/species/ethereal/proc/get_charge(mob/living/carbon/H) //this feels like it should be somewhere else. Eh?
var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
return stomach.crystal_charge
return ETHEREAL_CHARGE_NONE
@@ -4,7 +4,7 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH,HAS_BONE)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH)
mutantlungs = /obj/item/organ/lungs/slime
mutant_heart = /obj/item/organ/heart/slime
mutant_bodyparts = list("mcolor" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
@@ -287,11 +287,16 @@
else
ui_interact(owner)
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
/datum/action/innate/swap_body/ui_host(mob/user)
return owner
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/datum/action/innate/swap_body/ui_state(mob/user)
return GLOB.not_incapacitated_state
/datum/action/innate/swap_body/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "SlimeBodySwapper", name, 400, 400, master_ui, state)
ui = new(user, src, "SlimeBodySwapper", name)
ui.open()
/datum/action/innate/swap_body/ui_data(mob/user)
@@ -361,7 +366,8 @@
return
switch(action)
if("swap")
var/mob/living/carbon/human/selected = locate(params["ref"])
var/datum/species/jelly/slime/SS = H.dna.species
var/mob/living/carbon/human/selected = locate(params["ref"]) in SS.bodies
if(!can_swap(selected))
return
SStgui.close_uis(src)
@@ -185,6 +185,8 @@
T.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else if(isliving(AM))
var/mob/living/L = AM
if(isethereal(AM))
AM.emp_act(EMP_LIGHT)
if(iscyborg(AM))
var/mob/living/silicon/robot/borg = AM
if(borg.lamp_intensity)
@@ -32,6 +32,7 @@
name = "Infectious Zombie"
id = "memezombies"
limbs_id = "zombie"
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_NOSOFTCRIT, TRAIT_FAKEDEATH)
mutanthands = /obj/item/zombie_hand
armor = 20 // 120 damage to KO a zombie, which kills it
speedmod = 1.6 // they're very slow
@@ -89,8 +90,8 @@
infection = new()
infection.Insert(C)
//make their bodyparts stamina-resistant
var/incoming_stam_mult = 0.7
//make their bodyparts stamina-immune, its a corpse.
var/incoming_stam_mult = 0
for(var/obj/item/bodypart/part in C.bodyparts)
part.incoming_stam_mult = incoming_stam_mult
//todo: add negative wound resistance to all parts when wounds is merged (zombies are physically weak in terms of limbs)
+32 -1
View File
@@ -326,6 +326,11 @@
key_third_person = "smiles"
message = "smiles."
/datum/emote/living/smirk
key = "smirk"
key_third_person = "smirks"
message = "smirks."
/datum/emote/living/sneeze
key = "sneeze"
key_third_person = "sneezes"
@@ -441,7 +446,7 @@
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/custom_emote = stripped_multiline_input(user, "Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
var/custom_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Custom Emote", null, 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)
@@ -531,3 +536,29 @@
to_chat(user, "<span class='notice'>You ready your slapping hand.</span>")
else
to_chat(user, "<span class='warning'>You're incapable of slapping in your current state.</span>")
/datum/emote/living/audio_emote/blorble
key = "blorble"
key_third_person = "blorbles"
message = "blorbles."
message_param = "blorbles at %t."
/datum/emote/living/audio_emote/blorble/run_emote(mob/user, params)
. = ..()
if(. && iscarbon(user))
var/mob/living/carbon/C = user
if(isjellyperson(C))
pick(playsound(C, 'sound/effects/attackblob.ogg', 50, 1),playsound(C, 'sound/effects/blobattack.ogg', 50, 1))
/datum/emote/living/audio_emote/blurp
key = "blurp"
key_third_person = "blurps"
message = "blurps."
message_param = "blurps at %t."
/datum/emote/living/audio_emote/blurp/run_emote(mob/user, params)
. = ..()
if(. && iscarbon(user))
var/mob/living/carbon/C = user
if(isjellyperson(C))
pick(playsound(C, 'sound/effects/meatslap.ogg', 50, 1),playsound(C, 'sound/effects/gib_step.ogg', 50, 1))
@@ -245,7 +245,7 @@
. |= BLOCK_SUCCESS
var/list/effect_text
if(efficiency >= data.parry_efficiency_to_counterattack)
run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
effect_text = run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
if(data.parry_flags & PARRY_DEFAULT_HANDLE_FEEDBACK)
handle_parry_feedback(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, effect_text)
successful_parries += efficiency
@@ -254,9 +254,12 @@
/mob/living/proc/handle_parry_feedback(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency, list/effect_text)
var/datum/block_parry_data/data = get_parry_data()
var/knockdown_check = FALSE
if(data.parry_data[PARRY_KNOCKDOWN_ATTACKER] && parry_efficiency >= data.parry_efficiency_to_counterattack)
knockdown_check = TRUE
if(data.parry_sounds)
playsound(src, pick(data.parry_sounds), 75)
visible_message("<span class='danger'>[src] parries [attack_text][length(effect_text)? ", [english_list(effect_text)] [attacker]" : ""]!</span>")
visible_message("<span class='danger'>[src] parries [attack_text][length(effect_text)? ", [english_list(effect_text)] [attacker]" : ""][length(effect_text) && knockdown_check? " and" : ""][knockdown_check? " knocking them to the ground" : ""]!</span>")
/// Run counterattack if any
/mob/living/proc/run_parry_countereffects(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency)
@@ -288,15 +291,15 @@
if(data.parry_data[PARRY_DISARM_ATTACKER])
L.drop_all_held_items()
effect_text += "disarming"
if(data.parry_data[PARRY_KNOCKDOWN_ATTACKER])
L.DefaultCombatKnockdown(data.parry_data[PARRY_KNOCKDOWN_ATTACKER])
effect_text += "knocking them to the ground"
if(data.parry_data[PARRY_STAGGER_ATTACKER])
L.Stagger(data.parry_data[PARRY_STAGGER_ATTACKER])
effect_text += "staggering"
if(data.parry_data[PARRY_DAZE_ATTACKER])
L.Daze(data.parry_data[PARRY_DAZE_ATTACKER])
effect_text += "dazing"
if(data.parry_data[PARRY_KNOCKDOWN_ATTACKER])
L.DefaultCombatKnockdown(data.parry_data[PARRY_KNOCKDOWN_ATTACKER])
// effect_text += "knocking them to the ground" - snowflaked above
return effect_text
/// Gets the datum/block_parry_data we're going to use to parry.
+1 -1
View File
@@ -151,7 +151,7 @@
to_chat(src, "Receiving control information from APC.")
sleep(2)
apc_override = 1
theAPC.ui_interact(src, state = GLOB.conscious_state)
theAPC.ui_interact(src)
apc_override = 0
aiRestorePowerRoutine = POWER_RESTORATION_APC_FOUND
sleep(50)
@@ -19,11 +19,13 @@
return ..()
return UI_CLOSE
/datum/robot_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/datum/robot_control/ui_state(mob/user)
return GLOB.always_state
/datum/robot_control/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "RemoteRobotControl", "Remote Robot Control", 500, 500, master_ui, state)
ui = new(user, src, "RemoteRobotControl")
ui.open()
/datum/robot_control/ui_data(mob/user)
@@ -79,15 +79,15 @@
if(activated(O))
to_chat(src, "<span class='warning'>That module is already activated.</span>")
return
if(!held_items[1])
if(!held_items[1] && health >= -maxHealth*0.5)
held_items[1] = O
O.screen_loc = inv1.screen_loc
. = TRUE
else if(!held_items[2])
else if(!held_items[2] && health >= 0)
held_items[2] = O
O.screen_loc = inv2.screen_loc
. = TRUE
else if(!held_items[3])
else if(!held_items[3] && health >= maxHealth*0.5)
held_items[3] = O
O.screen_loc = inv3.screen_loc
. = TRUE
@@ -16,6 +16,8 @@
wires = new /datum/wires/robot(src)
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
RegisterSignal(src, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/charge)
robot_modules_background = new()
robot_modules_background.icon_state = "block"
robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it.
@@ -1097,6 +1099,15 @@
for(var/i in connected_ai.aicamera.stored)
aicamera.stored[i] = TRUE
/mob/living/silicon/robot/proc/charge(datum/source, amount, repairs)
if(module)
var/coeff = amount * 0.005
module.respawn_consumable(src, coeff)
if(repairs)
heal_bodypart_damage(repairs, repairs - 1)
if(cell)
cell.charge = min(cell.charge + amount, cell.maxcharge)
/mob/living/silicon/robot/proc/rest_style()
set name = "Switch Rest Style"
set category = "Robot Commands"
@@ -29,9 +29,6 @@
model = "MULE"
bot_core_type = /obj/machinery/bot_core/mulebot
var/ui_x = 350
var/ui_y = 425
var/id
path_image_color = "#7F5200"
@@ -170,11 +167,10 @@
return
ui_interact(user)
/mob/living/simple_animal/bot/mulebot/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/mob/living/simple_animal/bot/mulebot/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "Mule", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, "Mule", name)
ui.open()
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
@@ -191,8 +187,7 @@
data["modeStatus"] = "average"
if(BOT_NO_ROUTE)
data["modeStatus"] = "bad"
else
data["load"] = load ? load.name : null
data["load"] = load ? load.name : null //IF YOU CHANGE THE NAME OF THIS, UPDATE MULEBOT/PARANORMAL/UI_DATA.
data["destination"] = destination ? destination : null
data["home"] = home_destination
data["destinations"] = GLOB.deliverybeacontags
@@ -206,18 +201,20 @@
return data
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
var/silicon_access = hasSiliconAccessInArea(usr)
if(..() || (locked && silicon_access))
if(..() || (locked && hasSiliconAccessInArea(usr)))
return
switch(action)
if("lock")
if(silicon_access)
if(hasSiliconAccessInArea(usr))
locked = !locked
. = TRUE
if("power")
if(on)
turn_off()
else if(cell && !open)
else if(open)
to_chat(usr, "<span class='warning'>[name]'s maintenance panel is open!</span>")
return
else if(cell)
if(!turn_on())
to_chat(usr, "<span class='warning'>You can't switch on [src]!</span>")
return
@@ -0,0 +1,37 @@
/mob/living/simple_animal/opossum
name = "opossum"
desc = "It's an opossum, a small scavenging marsupial."
icon_state = "possum"
icon_living = "possum"
icon_dead = "possum_dead"
speak = list("Hiss!","HISS!","Hissss?")
speak_emote = list("hisses")
emote_hear = list("hisses.")
emote_see = list("runs in a circle.", "shakes.")
speak_chance = 1
turns_per_move = 3
blood_volume = 250
see_in_dark = 5
maxHealth = 15
health = 15
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "stamps on"
response_harm_simple = "stamp"
density = FALSE
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/opossum/poppy
name = "Poppy the Safety Possum"
desc = "Safety first!"
icon_state = "poppypossum"
icon_living = "poppypossum"
icon_dead = "poppypossum_dead"
butcher_results = list(/obj/item/clothing/head/hardhat = 1)
@@ -184,6 +184,7 @@
/mob/living/simple_animal/hostile/rat/Initialize()
. = ..()
SSmobs.cheeserats += src
AddComponent(/datum/component/swarming)
/mob/living/simple_animal/hostile/rat/Destroy()
SSmobs.cheeserats -= src
+5
View File
@@ -43,6 +43,11 @@
if(GLOB.say_disabled) //This is here to try to identify lag problems
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
return
if(length(message) > MAX_MESSAGE_LEN)
to_chat(usr, message)
to_chat(usr, "<span class='danger'>^^^----- The preceeding message has been DISCARDED for being over the maximum length of [MAX_MESSAGE_LEN]. It has NOT been sent! -----^^^</span>")
return
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
clear_typing_indicator() // clear it immediately!
+2 -2
View File
@@ -37,7 +37,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN)
var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
@@ -98,7 +98,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
var/subtle_emote = stripped_multiline_input_or_reflect(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)