Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into proc-define-shit
This commit is contained in:
@@ -169,10 +169,10 @@
|
||||
|
||||
/mob/dead/new_player/Topic(href, href_list[])
|
||||
if(src != usr)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(!client)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
//don't let people get to this unless they are specifically not verified
|
||||
if(href_list["Month"] && (CONFIG_GET(flag/age_verification) && !check_rights_for(client, R_ADMIN) && !(client.ckey in GLOB.bunker_passthrough)))
|
||||
@@ -727,7 +727,7 @@
|
||||
src << browse(dat, "window=manifest;size=387x420;can_close=1")
|
||||
|
||||
/mob/dead/new_player/Move()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/dead/new_player/proc/close_spawn_windows()
|
||||
|
||||
@@ -461,7 +461,7 @@
|
||||
return
|
||||
pollid = text2num(pollid)
|
||||
if (!pollid || pollid < 0)
|
||||
return 0
|
||||
return FALSE
|
||||
//validate the poll is actually the right type of poll and its still active
|
||||
var/datum/db_query/query_validate_poll = SSdbcore.NewQuery({"
|
||||
SELECT id
|
||||
@@ -473,12 +473,12 @@
|
||||
))
|
||||
if(!query_validate_poll.warn_execute())
|
||||
qdel(query_validate_poll)
|
||||
return 0
|
||||
return FALSE
|
||||
if (!query_validate_poll.NextRow())
|
||||
qdel(query_validate_poll)
|
||||
return 0
|
||||
return FALSE
|
||||
qdel(query_validate_poll)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Processes vote form data and saves results to the database for an IRV type poll.
|
||||
@@ -501,7 +501,7 @@
|
||||
if(!QDELETED(client) && client.holder)
|
||||
admin_rank = client.holder.rank.name
|
||||
if (!vote_valid_check(pollid, client?.holder, POLLTYPE_IRV))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/list/special_columns = list(
|
||||
"datetime" = "NOW()",
|
||||
@@ -544,7 +544,7 @@
|
||||
return
|
||||
//validate the poll
|
||||
if (!vote_valid_check(pollid, client.holder, POLLTYPE_OPTION))
|
||||
return 0
|
||||
return FALSE
|
||||
var/voted = poll_check_voted(pollid)
|
||||
if(isnull(voted) || voted) //Failed or already voted.
|
||||
return
|
||||
@@ -567,7 +567,7 @@
|
||||
qdel(query_option_vote)
|
||||
if(!QDELETED(usr))
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/dead/new_player/proc/log_text_poll_reply(pollid, replytext)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -581,7 +581,7 @@
|
||||
return
|
||||
//validate the poll
|
||||
if (!vote_valid_check(pollid, client.holder, POLLTYPE_TEXT))
|
||||
return 0
|
||||
return FALSE
|
||||
if(!replytext)
|
||||
to_chat(usr, "The text you entered was blank. Please correct the text and submit again.")
|
||||
return
|
||||
@@ -611,7 +611,7 @@
|
||||
qdel(query_text_vote)
|
||||
if(!QDELETED(usr))
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/dead/new_player/proc/vote_on_numval_poll(pollid, optionid, rating)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -625,7 +625,7 @@
|
||||
return
|
||||
//validate the poll
|
||||
if (!vote_valid_check(pollid, client.holder, POLLTYPE_RATING))
|
||||
return 0
|
||||
return FALSE
|
||||
var/datum/db_query/query_numval_hasvoted = SSdbcore.NewQuery({"
|
||||
SELECT id
|
||||
FROM [format_table_name("poll_vote")]
|
||||
@@ -655,7 +655,7 @@
|
||||
qdel(query_numval_vote)
|
||||
if(!QDELETED(usr))
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Processes vote form data and saves results to the database for a multiple choice type poll.
|
||||
|
||||
@@ -233,7 +233,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
var/g_val
|
||||
var/color_format = length(input_color)
|
||||
if(color_format != length_char(input_color))
|
||||
return 0
|
||||
return FALSE
|
||||
if(color_format == 3)
|
||||
r_val = hex2num(copytext(input_color, 1, 2)) * 16
|
||||
g_val = hex2num(copytext(input_color, 2, 3)) * 16
|
||||
@@ -243,7 +243,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
g_val = hex2num(copytext(input_color, 3, 5))
|
||||
b_val = hex2num(copytext(input_color, 5, 7))
|
||||
else
|
||||
return 0 //If the color format is not 3 or 6, you're using an unexpected way to represent a color.
|
||||
return FALSE //If the color format is not 3 or 6, you're using an unexpected way to represent a color.
|
||||
|
||||
r_val += (255 - r_val) * 0.4
|
||||
if(r_val > 255)
|
||||
@@ -693,32 +693,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/mob/living/target = input("Your new life begins today!", "Possess Mob", null, null) as null|anything in possessible
|
||||
|
||||
if(!target)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(ismegafauna(target))
|
||||
to_chat(src, "<span class='warning'>This creature is too powerful for you to possess!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
if(alert(src, "Your soul is still tied to your former life as [mind.current.name], if you go forward there is no going back to that life. Are you sure you wish to continue?", "Move On", "Yes", "No") == "No")
|
||||
return 0
|
||||
return FALSE
|
||||
if(target.key)
|
||||
to_chat(src, "<span class='warning'>Someone has taken this body while you were choosing!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
transfer_ckey(target, FALSE)
|
||||
target.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = FALSE, free_ghosting = TRUE)
|
||||
target.faction = list("neutral")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//this is a mob verb instead of atom for performance reasons
|
||||
//see /mob/verb/examinate() in mob.dm for more info
|
||||
//overridden here and in /mob/living for different point span classes and sanity checks
|
||||
/mob/dead/observer/pointed(atom/A as mob|obj|turf in fov_view())
|
||||
if(!..())
|
||||
return 0
|
||||
return FALSE
|
||||
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A].</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/verb/view_manifest()
|
||||
set name = "View Crew Manifest"
|
||||
@@ -839,7 +839,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return IsAdminGhost(usr)
|
||||
|
||||
/mob/dead/observer/is_literate()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
@@ -947,7 +947,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
// Ghosts have no momentum, being massless ectoplasm
|
||||
/mob/dead/observer/Process_Spacemove(movement_dir)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
|
||||
@@ -292,10 +292,18 @@
|
||||
|
||||
//The following functions are the same save for one small difference
|
||||
|
||||
//for when you want the item to end up on the ground
|
||||
//will force move the item to the ground and call the turf's Entered
|
||||
/mob/proc/dropItemToGround(obj/item/I, force = FALSE)
|
||||
return doUnEquip(I, force, drop_location(), FALSE)
|
||||
/**
|
||||
* Used to drop an item (if it exists) to the ground.
|
||||
* * Will pass as TRUE is successfully dropped, or if there is no item to drop.
|
||||
* * Will pass FALSE if the item can not be dropped due to TRAIT_NODROP via doUnEquip()
|
||||
* If the item can be dropped, it will be forceMove()'d to the ground and the turf's Entered() will be called.
|
||||
*/
|
||||
/mob/proc/dropItemToGround(obj/item/I, force = FALSE, silent = FALSE, invdrop = TRUE)
|
||||
if (isnull(I))
|
||||
return TRUE
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOB_DROPPING_ITEM)
|
||||
. = doUnEquip(I, force, drop_location(), FALSE, invdrop = invdrop, silent = silent)
|
||||
|
||||
//for when the item will be immediately placed in a loc other than the ground
|
||||
/mob/proc/transferItemToLoc(obj/item/I, newloc = null, force = FALSE, silent = TRUE)
|
||||
@@ -371,7 +379,7 @@
|
||||
//returns 0 if it cannot, 1 if successful
|
||||
/mob/proc/equip_to_appropriate_slot(obj/item/W, clothing_check = FALSE)
|
||||
if(!istype(W))
|
||||
return 0
|
||||
return FALSE
|
||||
var/slot_priority = W.slot_equipment_priority
|
||||
|
||||
if(!slot_priority)
|
||||
@@ -388,9 +396,9 @@
|
||||
|
||||
for(var/slot in slot_priority)
|
||||
if(equip_to_slot_if_possible(W, slot, FALSE, TRUE, TRUE, FALSE, clothing_check)) //qdel_on_fail = 0; disable_warning = 1; redraw_mob = 1
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Used to return a list of equipped items on a mob; does not include held items (use get_all_gear)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
//entry when holding them
|
||||
// literally only an option for carbons though
|
||||
to_chat(C, "<span class='warning'>You may not hold items while blood crawling!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
var/obj/item/bloodcrawl/B1 = new(C)
|
||||
var/obj/item/bloodcrawl/B2 = new(C)
|
||||
B1.icon_state = "bloodhand_left"
|
||||
@@ -45,7 +45,7 @@
|
||||
spawn(0)
|
||||
bloodpool_sink(B)
|
||||
src.mob_transforming = FALSE
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/bloodpool_sink(obj/effect/decal/cleanable/B)
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
@@ -89,7 +89,7 @@
|
||||
var/success = bloodcrawl_consume(victim)
|
||||
if(!success)
|
||||
to_chat(src, "<span class='danger'>You happily devour... nothing? Your meal vanished at some point!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/bloodcrawl_consume(mob/living/victim)
|
||||
to_chat(src, "<span class='danger'>You begin to feast on [victim]. You can not move while you are doing this.</span>")
|
||||
@@ -161,7 +161,7 @@
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.mob_transforming)
|
||||
to_chat(src, "<span class='warning'>Finish eating first!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
B.visible_message("<span class='warning'>[B] starts to bubble...</span>")
|
||||
if(!do_after(src, 20, target = B))
|
||||
return
|
||||
@@ -178,4 +178,4 @@
|
||||
qdel(BC)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
@@ -47,8 +47,20 @@
|
||||
if(brain)
|
||||
to_chat(user, "<span class='warning'>There's already a brain in the MMI!</span>")
|
||||
return
|
||||
if(!newbrain.brainmob)
|
||||
to_chat(user, "<span class='warning'>You aren't sure where this brain came from, but you're pretty sure it's a useless brain!</span>")
|
||||
if(newbrain.brainmob?.suiciding)
|
||||
to_chat(user, span_warning("[newbrain] is completely useless."))
|
||||
return
|
||||
if(!newbrain.brainmob?.mind || !newbrain.brainmob)
|
||||
var/install = tgui_alert(user, "[newbrain] is inactive, slot it in anyway?", "Installing Brain", list("Yes", "No"))
|
||||
if(install != "Yes")
|
||||
return
|
||||
if(!user.transferItemToLoc(newbrain, src))
|
||||
return
|
||||
user.visible_message(span_notice("[user] sticks [newbrain] into [src]."), span_notice("[src]'s indicator light turns red as you insert [newbrain]. Its brainwave activity alarm buzzes."))
|
||||
brain = newbrain
|
||||
brain.organ_flags |= ORGAN_FROZEN
|
||||
name = "[initial(name)]: [copytext(newbrain.name, 1, -8)]"
|
||||
update_appearance()
|
||||
return
|
||||
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
@@ -97,15 +109,15 @@
|
||||
name = initial(name)
|
||||
|
||||
/obj/item/mmi/proc/eject_brain(mob/user)
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.forceMove(brain) //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
brainmob.remove_from_alive_mob_list() //Get outta here
|
||||
brainmob.add_to_dead_mob_list()
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
if(brain.brainmob)
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.forceMove(brain) //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
log_game("[key_name(user)] has ejected the brain of [key_name(brainmob)] from an MMI at [AREACOORD(src)]")
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
if(user)
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
else
|
||||
@@ -210,6 +222,38 @@
|
||||
/obj/item/mmi/relaymove(mob/user)
|
||||
return //so that the MMI won't get a warning about not being able to move if it tries to move
|
||||
|
||||
/obj/item/mmi/proc/brain_check(mob/user)
|
||||
var/mob/living/brain/B = brainmob
|
||||
if(!B)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that there is no mind present!"))
|
||||
return FALSE
|
||||
if(brain?.decoy_override)
|
||||
if(user)
|
||||
to_chat(user, span_warning("This [name] does not seem to fit!"))
|
||||
return FALSE
|
||||
if(!B.key || !B.mind)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that their mind is completely unresponsive!"))
|
||||
return FALSE
|
||||
if(!B.client)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that their mind is currently inactive."))
|
||||
return FALSE
|
||||
if(B.suiciding)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that their mind has no will to live!"))
|
||||
return FALSE
|
||||
if(B.stat == DEAD)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that the brain is dead!"))
|
||||
return FALSE
|
||||
if(brain?.organ_flags & ORGAN_FAILING)
|
||||
if(user)
|
||||
to_chat(user, span_warning("\The [src] indicates that the brain is damaged!"))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mmi/syndie
|
||||
name = "Syndicate Man-Machine Interface"
|
||||
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it."
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/mob/living/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= HEALTH_THRESHOLD_DEAD)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/brain/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
clear_alert("alien_fire")
|
||||
|
||||
/mob/living/carbon/alien/reagent_check(datum/reagent/R) //can metabolize all reagents
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/IsAdvancedToolUser()
|
||||
return has_fine_manipulation
|
||||
@@ -136,7 +136,7 @@ Des: Removes all infected images from the alien.
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/canBeHandcuffed()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/get_standard_pixel_y_offset(lying = 0)
|
||||
return initial(pixel_y)
|
||||
|
||||
@@ -123,7 +123,7 @@ In all, this is a lot like the monkey code. /N
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
|
||||
return 0//aliens are immune to acid.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/mob/living/carbon/alien/getToxLoss(toxins_type = TOX_OMNI)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT) //alien immune to tox damage
|
||||
return FALSE
|
||||
|
||||
@@ -32,7 +32,7 @@ Doesn't work on other aliens/AI.*/
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/alien/fire(mob/living/carbon/user)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/get_panel_text()
|
||||
. = ..()
|
||||
@@ -72,10 +72,10 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/plant/fire(mob/living/carbon/user)
|
||||
if(locate(/obj/structure/alien/weeds/node) in get_turf(user))
|
||||
to_chat(user, "There's already a weed node here.")
|
||||
return 0
|
||||
return FALSE
|
||||
user.visible_message("<span class='alertalien'>[user] has planted some alien weeds!</span>")
|
||||
new/obj/structure/alien/weeds/node(user.loc)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/whisper
|
||||
name = "Whisper"
|
||||
@@ -89,7 +89,7 @@ Doesn't work on other aliens/AI.*/
|
||||
options += Ms
|
||||
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
|
||||
if(!M)
|
||||
return 0
|
||||
return FALSE
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
to_chat(user, "<span class='noticealien'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
|
||||
return FALSE
|
||||
@@ -108,8 +108,8 @@ Doesn't work on other aliens/AI.*/
|
||||
var/follow_link_whispee = FOLLOW_LINK(ded, M)
|
||||
to_chat(ded, "[follow_link_user] <span class='name'>[user]</span> <span class='alertalien'>Alien Whisper --> </span> [follow_link_whispee] <span class='name'>[M]</span> <span class='noticealien'>[msg]</span>")
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/transfer
|
||||
name = "Transfer Plasma"
|
||||
@@ -124,7 +124,7 @@ Doesn't work on other aliens/AI.*/
|
||||
aliens_around.Add(A)
|
||||
var/mob/living/carbon/M = input("Select who to transfer to:","Transfer plasma to?",null) as mob in aliens_around
|
||||
if(!M)
|
||||
return 0
|
||||
return FALSE
|
||||
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
|
||||
if (amount)
|
||||
amount = min(abs(round(amount)), user.getPlasma())
|
||||
@@ -153,21 +153,21 @@ Doesn't work on other aliens/AI.*/
|
||||
if(target in oview(1,user))
|
||||
if(target.acid_act(200, 100))
|
||||
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='noticealien'>You cannot dissolve this object.</span>")
|
||||
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
to_chat(src, "<span class='noticealien'>[target] is too far away.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/acid/fire(mob/living/carbon/alien/user)
|
||||
var/O = input("Select what to dissolve:","Dissolve",null) as obj|turf in oview(1,user)
|
||||
if(!O || user.incapacitated())
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return corrode(O,user)
|
||||
|
||||
@@ -200,7 +200,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/update_icon()
|
||||
action.button_icon_state = "alien_neurotoxin_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
@@ -320,21 +320,21 @@ Doesn't work on other aliens/AI.*/
|
||||
/mob/living/carbon/proc/getPlasma()
|
||||
var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel)
|
||||
if(!vessel)
|
||||
return 0
|
||||
return FALSE
|
||||
return vessel.storedPlasma
|
||||
|
||||
|
||||
/mob/living/carbon/proc/adjustPlasma(amount)
|
||||
var/obj/item/organ/alien/plasmavessel/vessel = getorgan(/obj/item/organ/alien/plasmavessel)
|
||||
if(!vessel)
|
||||
return 0
|
||||
return FALSE
|
||||
vessel.storedPlasma = max(vessel.storedPlasma + amount,0)
|
||||
vessel.storedPlasma = min(vessel.storedPlasma, vessel.max_plasma) //upper limit of max_plasma, lower limit of 0
|
||||
for(var/X in abilities)
|
||||
var/obj/effect/proc_holder/alien/APH = X
|
||||
if(APH.has_action)
|
||||
APH.action.UpdateButtonIcon()
|
||||
return 1
|
||||
APH.action.UpdateButtons()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/adjustPlasma(amount)
|
||||
. = ..()
|
||||
@@ -343,6 +343,6 @@ Doesn't work on other aliens/AI.*/
|
||||
/mob/living/carbon/proc/usePlasma(amount)
|
||||
if(getPlasma() >= amount)
|
||||
adjustPlasma(-amount)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
@@ -27,18 +27,18 @@
|
||||
var/obj/item/organ/alien/hivenode/node = user.getorgan(/obj/item/organ/alien/hivenode)
|
||||
if(!node) //Players are Murphy's Law. We may not expect there to ever be a living xeno with no hivenode, but they _WILL_ make it happen.
|
||||
to_chat(user, "<span class='danger'>Without the hivemind, you can't possibly hold the responsibility of leadership!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(node.recent_queen_death)
|
||||
to_chat(user, "<span class='danger'>Your thoughts are still too scattered to take up the position of leadership.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(!isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>You can't evolve here!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal))
|
||||
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>We already have a living royal!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
var/obj/item/organ/alien/hivenode/node = user.getorgan(/obj/item/organ/alien/hivenode)
|
||||
if(!node) //Just in case this particular Praetorian gets violated and kept by the RD as a replacement for Lamarr.
|
||||
to_chat(user, "<span class='danger'>Without the hivemind, you would be unfit to rule as queen!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(node.recent_queen_death)
|
||||
to_chat(user, "<span class='danger'>You are still too burdened with guilt to evolve into a queen.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>We already have an alive queen.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen
|
||||
name = "alien queen"
|
||||
@@ -90,20 +90,20 @@
|
||||
var/obj/item/queenpromote/prom
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
to_chat(user, "<span class='noticealien'>You already have a Praetorian!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
for(prom in user)
|
||||
to_chat(user, "<span class='noticealien'>You discard [prom].</span>")
|
||||
qdel(prom)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
prom = new (user.loc)
|
||||
if(!user.put_in_active_hand(prom, 1))
|
||||
to_chat(user, "<span class='warning'>You must empty your hands before preparing the parasite.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
else //Just in case telling the player only once is not enough!
|
||||
to_chat(user, "<span class='noticealien'>Use the royal parasite on one of your children to promote her to Praetorian!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/queenpromote
|
||||
name = "\improper royal parasite"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//can't unequip since it can't equip anything
|
||||
/mob/living/carbon/alien/larva/doUnEquip(obj/item/W, silent = FALSE)
|
||||
/mob/living/carbon/alien/larva/doUnEquip(obj/item/W, invdrop, silent = FALSE)
|
||||
return
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"<span class='userdanger'>[user] has pummeled [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
adjustBruteLoss(5 + rand(1,9))
|
||||
new /datum/forced_movement(src, get_step_away(user,src, 30), 1)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
|
||||
if(!no_effect && !visual_effect_icon)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
user.layer = MOB_LAYER
|
||||
user.visible_message("[user] slowly peeks up from the ground...", \
|
||||
"<span class='noticealien'>You stop hiding.</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/larva_evolve
|
||||
@@ -57,7 +57,7 @@
|
||||
new_xeno = new /mob/living/carbon/alien/humanoid/drone(L.loc)
|
||||
|
||||
L.alien_evolve(new_xeno)
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
to_chat(user, "<span class='danger'>You are not fully grown.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
if(!breath || (breath.total_moles() == 0))
|
||||
//Aliens breathe in vaccuum
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/toxins_used = 0
|
||||
var/tox_detect_threshold = 0.02
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/mob/living/carbon/alien/proc/updatePlasmaDisplay()
|
||||
if(hud_used) //clientless aliens
|
||||
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
|
||||
hud_used.alien_plasma_display.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>")
|
||||
|
||||
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
|
||||
return
|
||||
|
||||
@@ -97,12 +97,12 @@
|
||||
/obj/item/clothing/mask/facehugger/on_found(mob/finder)
|
||||
if(stat == CONSCIOUS)
|
||||
return HasProximity(finder)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(CanHug(AM) && Adjacent(AM))
|
||||
return Leap(AM)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
if(!..())
|
||||
@@ -256,7 +256,7 @@
|
||||
return FALSE
|
||||
|
||||
if(ismonkey(M))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(ishuman(C) && !(ITEM_SLOT_MASK in C.dna.species.no_equip))
|
||||
|
||||
@@ -125,8 +125,8 @@
|
||||
take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5)
|
||||
victim.DefaultCombatKnockdown(20)
|
||||
DefaultCombatKnockdown(20)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim] [extra_speed ? "really hard" : ""], knocking them both over!</span>",\
|
||||
"<span class='userdanger'>You violently crash into [victim] [extra_speed ? "extra hard" : ""]!</span>")
|
||||
visible_message("<span class='danger'>[src] crashes into [victim][extra_speed ? " really hard" : ""], knocking them both over!</span>",\
|
||||
"<span class='userdanger'>You violently crash into [victim][extra_speed ? " extra hard" : ""]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
|
||||
|
||||
@@ -134,33 +134,35 @@
|
||||
/mob/living/carbon/proc/toggle_throw_mode()
|
||||
if(stat)
|
||||
return
|
||||
if(in_throw_mode)
|
||||
if(throw_mode)
|
||||
throw_mode_off()
|
||||
else
|
||||
throw_mode_on()
|
||||
|
||||
|
||||
/mob/living/carbon/proc/throw_mode_off()
|
||||
in_throw_mode = 0
|
||||
throw_mode = FALSE
|
||||
if(client && hud_used)
|
||||
hud_used.throw_icon.icon_state = "act_throw_off"
|
||||
|
||||
|
||||
/mob/living/carbon/proc/throw_mode_on()
|
||||
in_throw_mode = 1
|
||||
throw_mode = TRUE
|
||||
if(client && hud_used)
|
||||
hud_used.throw_icon.icon_state = "act_throw_on"
|
||||
|
||||
/mob/proc/throw_item(atom/target)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_THROW, target)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CARBON_THROW_THING, src, target)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/throw_item(atom/target)
|
||||
. = ..()
|
||||
throw_mode_off()
|
||||
if(!target || !isturf(loc))
|
||||
return
|
||||
return FALSE
|
||||
if(istype(target, /atom/movable/screen))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
//CIT CHANGES - makes it impossible to throw while in stamina softcrit
|
||||
if(IS_STAMCRIT(src))
|
||||
@@ -170,65 +172,62 @@
|
||||
var/random_turn = a_intent == INTENT_HARM
|
||||
//END OF CIT CHANGES
|
||||
|
||||
var/obj/item/I = get_active_held_item()
|
||||
|
||||
var/atom/movable/thrown_thing
|
||||
var/mob/living/throwable_mob
|
||||
var/obj/item/held_item = get_active_held_item()
|
||||
var/verb_text = pick("throw", "toss", "hurl", "chuck", "fling")
|
||||
if(prob(0.5))
|
||||
verb_text = "yeet"
|
||||
|
||||
if(istype(I, /obj/item/clothing/head/mob_holder))
|
||||
var/obj/item/clothing/head/mob_holder/holder = I
|
||||
if(holder.held_mob)
|
||||
throwable_mob = holder.held_mob
|
||||
holder.release()
|
||||
|
||||
if(!I || throwable_mob)
|
||||
if(!throwable_mob && pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
|
||||
throwable_mob = pulling
|
||||
|
||||
if(throwable_mob && !throwable_mob.buckled)
|
||||
thrown_thing = throwable_mob
|
||||
if(pulling)
|
||||
var/neckgrab_throw = FALSE
|
||||
if(!held_item)
|
||||
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
|
||||
var/mob/living/throwable_mob = pulling
|
||||
if(!throwable_mob.buckled)
|
||||
thrown_thing = throwable_mob
|
||||
if(grab_state >= GRAB_NECK)
|
||||
neckgrab_throw = TRUE
|
||||
stop_pulling()
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
|
||||
return
|
||||
if(!UseStaminaBuffer(STAM_COST_THROW_MOB * ((throwable_mob.mob_size+1)**2), TRUE))
|
||||
return
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
if(start_T && end_T)
|
||||
log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]")
|
||||
|
||||
else if(!(I.item_flags & ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP))
|
||||
thrown_thing = I
|
||||
dropItemToGround(I)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM) && I.throwforce)
|
||||
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
|
||||
return
|
||||
|
||||
if(!UseStaminaBuffer(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST), warn = TRUE))
|
||||
return
|
||||
|
||||
if(thrown_thing)
|
||||
var/power_throw = 0
|
||||
if(HAS_TRAIT(src, TRAIT_HULK))
|
||||
power_throw++
|
||||
if(pulling && grab_state >= GRAB_NECK)
|
||||
power_throw++
|
||||
visible_message("<span class='danger'>[src] throws [thrown_thing][power_throw ? " really hard!" : "."]</span>", \
|
||||
"<span class='danger'>You throw [thrown_thing][power_throw ? " really hard!" : "."]</span>")
|
||||
log_message("has thrown [thrown_thing] [power_throw ? "really hard" : ""]", LOG_ATTACK)
|
||||
do_attack_animation(target, no_effect = 1)
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1)
|
||||
newtonian_move(get_dir(target, src))
|
||||
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force, random_turn)
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
to_chat(src, span_notice("You gently let go of [throwable_mob]."))
|
||||
return FALSE
|
||||
if(!UseStaminaBuffer(STAM_COST_THROW_MOB * ((throwable_mob.mob_size+1)**2), TRUE))
|
||||
return FALSE
|
||||
else
|
||||
thrown_thing = held_item.on_thrown(src, target)
|
||||
if(!thrown_thing)
|
||||
return FALSE
|
||||
if(isliving(thrown_thing))
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
if(start_T && end_T)
|
||||
log_combat(src, thrown_thing, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]")
|
||||
var/power_throw = 0
|
||||
if(HAS_TRAIT(src, TRAIT_HULK))
|
||||
power_throw++
|
||||
if(HAS_TRAIT(src, TRAIT_DWARF))
|
||||
power_throw--
|
||||
if(HAS_TRAIT(thrown_thing, TRAIT_DWARF))
|
||||
power_throw++
|
||||
if(neckgrab_throw)
|
||||
power_throw++
|
||||
if(isitem(thrown_thing))
|
||||
var/obj/item/thrown_item = thrown_thing
|
||||
if(thrown_item.throw_verb)
|
||||
verb_text = thrown_item.throw_verb
|
||||
visible_message(span_danger("[src] [verb_text][plural_s(verb_text)] [thrown_thing][power_throw ? " really hard!" : "."]"), \
|
||||
span_danger("You [verb_text] [thrown_thing][power_throw ? " really hard!" : "."]"))
|
||||
log_message("has thrown [thrown_thing] [power_throw > 0 ? "really hard" : ""]", LOG_ATTACK)
|
||||
do_attack_animation(target, no_effect = 1)
|
||||
var/extra_throw_range = 0 // HAS_TRAIT(src, TRAIT_THROWINGARM) ? 2 : 0
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1)
|
||||
newtonian_move(get_dir(target, src))
|
||||
thrown_thing.safe_throw_at(target, thrown_thing.throw_range + extra_throw_range, max(1,thrown_thing.throw_speed + power_throw), src, null, null, null, move_force, random_turn)
|
||||
|
||||
/mob/living/carbon/restrained(ignore_grab)
|
||||
. = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
|
||||
|
||||
/mob/living/carbon/proc/canBeHandcuffed()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
@@ -451,7 +450,7 @@
|
||||
|
||||
/mob/living/carbon/attack_ui(slot)
|
||||
if(!has_hand_for_held_index(active_hand_index))
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
|
||||
@@ -892,7 +891,7 @@
|
||||
/mob/living/carbon/can_be_revived()
|
||||
. = ..()
|
||||
if(!getorgan(/obj/item/organ/brain) && (!mind || !mind.has_antag_datum(/datum/antagonist/changeling)))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/harvest(mob/living/user)
|
||||
if(QDELETED(src))
|
||||
|
||||
@@ -48,22 +48,30 @@
|
||||
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
|
||||
affecting.dismember(P.damtype)
|
||||
|
||||
/mob/living/carbon/catch_item(obj/item/I, skip_throw_mode_check = FALSE)
|
||||
. = ..()
|
||||
if(!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) && !skip_throw_mode_check && !in_throw_mode)
|
||||
/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check)
|
||||
. = FALSE
|
||||
if(!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) && !skip_throw_mode_check && !throw_mode)
|
||||
return
|
||||
if(incapacitated())
|
||||
if(get_active_held_item())
|
||||
return
|
||||
if (get_active_held_item())
|
||||
if (HAS_TRAIT_FROM(src, TRAIT_AUTO_CATCH_ITEM,RISING_BASS_TRAIT))
|
||||
visible_message("<span class='warning'>[src] chops [I] out of the air!</span>")
|
||||
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(!skipcatch && can_catch_item() && isitem(AM) && isturf(AM.loc))
|
||||
var/obj/item/I = AM
|
||||
I.attack_hand(src)
|
||||
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
|
||||
visible_message(span_warning("[src] catches [I]!"), \
|
||||
span_userdanger("You catch [I] in mid-air!"))
|
||||
throw_mode_off()
|
||||
return TRUE
|
||||
return
|
||||
I.attack_hand(src)
|
||||
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
|
||||
visible_message("<span class='warning'>[src] catches [I]!</span>") //catch that sucker!
|
||||
throw_mode_off()
|
||||
if(isitem(AM) && HAS_TRAIT_FROM(src, TRAIT_AUTO_CATCH_ITEM, RISING_BASS_TRAIT))
|
||||
visible_message(span_warning("[src] chops [AM] out of the air!"), \
|
||||
span_userdanger("You chop [AM] out of the air!"))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
|
||||
|
||||
@@ -7,24 +7,24 @@
|
||||
|
||||
/mob/living/carbon/Process_Spacemove(movement_dir = 0)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
if(!isturf(loc))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// Do we have a jetpack implant (and is it on)?
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot(ORGAN_SLOT_THRUSTERS)
|
||||
if(istype(T) && movement_dir && T.allow_thrust(0.01))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/obj/item/I = get_jetpack()
|
||||
if(istype(I, /obj/item/tank/jetpack))
|
||||
var/obj/item/tank/jetpack/J = I
|
||||
if((movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
|
||||
return 1
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/mod/module/jetpack))
|
||||
var/obj/item/mod/module/jetpack/J = I
|
||||
if((movement_dir || J.stabilizers) && J.allow_thrust())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/Moved()
|
||||
. = ..()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/mob/living/carbon/regenerate_icons()
|
||||
if(mob_transforming)
|
||||
return 1
|
||||
return TRUE
|
||||
update_inv_hands()
|
||||
update_inv_handcuffed()
|
||||
update_inv_legcuffed()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!forced && hit_percent <= 0)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
if(!spread_damage)
|
||||
|
||||
@@ -478,17 +478,17 @@
|
||||
return
|
||||
if(is_mouth_covered())
|
||||
to_chat(src, "<span class='warning'>Remove your mask first!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(C.is_mouth_covered())
|
||||
to_chat(src, "<span class='warning'>Remove [p_their()] mask first!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(C.cpr_time < world.time + 30)
|
||||
visible_message("<span class='notice'>[src] is trying to perform CPR on [C.name]!</span>", \
|
||||
"<span class='notice'>You try to perform CPR on [C.name]... Hold still!</span>")
|
||||
if(!do_mob(src, C))
|
||||
to_chat(src, "<span class='warning'>You fail to perform CPR on [C]!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/they_breathe = !HAS_TRAIT(C, TRAIT_NOBREATH)
|
||||
var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
@@ -671,7 +671,7 @@
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
DefaultCombatKnockdown(200)
|
||||
return 1
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/vv_get_dropdown()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/carbon/human/getarmor(def_zone, type)
|
||||
if(HAS_TRAIT(src, TRAIT_ARMOR_BROKEN)) //trait that makes it act as if you have no armor at all, you take natural damage from all sources
|
||||
return 0
|
||||
return FALSE
|
||||
var/armorval = 0
|
||||
var/organnum = 0
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
|
||||
if(!d_type || !def_zone)
|
||||
return 0
|
||||
return FALSE
|
||||
var/protection = 0
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
for(var/bp in body_parts)
|
||||
@@ -68,12 +68,16 @@
|
||||
|
||||
/mob/living/carbon/human/proc/check_martial_melee_block()
|
||||
if(mind)
|
||||
if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
|
||||
if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && throw_mode && !incapacitated(FALSE, TRUE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
return dna?.species?.spec_hitby(AM, src) || ..()
|
||||
if(dna?.species)
|
||||
var/spec_return = dna.species.spec_hitby(AM, src)
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (HAS_TRAIT(src, TRAIT_FAT)) && ismonkey(pulling))
|
||||
@@ -89,7 +93,7 @@
|
||||
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/obj/item/bodypart/affecting
|
||||
if(user == src)
|
||||
@@ -121,7 +125,7 @@
|
||||
"<span class='userdanger'>[user] [hulk_verb_continous] you!</span>", null, COMBAT_MESSAGE_RANGE, null, user,
|
||||
"<span class='danger'>You [hulk_verb_simple] [src]!</span>")
|
||||
apply_damage(15, BRUTE, wound_bonus=10)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
@@ -164,7 +168,7 @@
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, MELEE))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
. = ..()
|
||||
@@ -179,7 +183,7 @@
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at you!</span>", target = M, \
|
||||
target_message = "<span class='danger'>You have lunged at [src]!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
@@ -191,7 +195,7 @@
|
||||
target_message = "<span class='danger'>You have slashed at [src]!</span>")
|
||||
log_combat(M, src, "attacked")
|
||||
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
|
||||
return 1
|
||||
return TRUE
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead.
|
||||
@@ -248,7 +252,7 @@
|
||||
|
||||
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
@@ -525,7 +529,7 @@
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr, acid_volume)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/singularity_act()
|
||||
var/gain = 20
|
||||
@@ -817,7 +821,7 @@
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
else
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
if(damage_type != BRUTE && damage_type != BURN)
|
||||
|
||||
@@ -103,11 +103,11 @@
|
||||
|
||||
/mob/living/carbon/human/can_track(mob/living/user)
|
||||
if(wear_id && istype(wear_id.GetID(), /obj/item/card/id/syndicate))
|
||||
return 0
|
||||
return FALSE
|
||||
if(istype(head, /obj/item/clothing/head))
|
||||
var/obj/item/clothing/head/hat = head
|
||||
if(hat.blockTracking)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
return 0
|
||||
return FALSE
|
||||
if (!(lube & GALOSHES_DONT_HELP))
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPWATER))
|
||||
return 0
|
||||
return FALSE
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
if (CS.clothing_flags & NOSLIP)
|
||||
return 0
|
||||
return FALSE
|
||||
if (lube & SLIDE_ICE)
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
@@ -32,7 +32,7 @@
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/S = shoes
|
||||
if (S.clothing_flags & NOSLIP)
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/mob_has_gravity()
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
to_chat(owner, "There's something stuck to your hand, stopping you from transforming!")
|
||||
return
|
||||
if(IsAvailable())
|
||||
UpdateButtonIcon()
|
||||
UpdateButtons()
|
||||
var/mutcolor = owner.get_ability_property(INNATE_ABILITY_SLIME_BLOBFORM, PROPERTY_BLOBFORM_COLOR) || ("#" + H.dna.features["mcolor"])
|
||||
if(!is_puddle)
|
||||
if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle
|
||||
@@ -78,7 +78,7 @@
|
||||
owner.update_antag_overlays()
|
||||
|
||||
transforming = FALSE
|
||||
UpdateButtonIcon()
|
||||
UpdateButtons()
|
||||
else
|
||||
detransform()
|
||||
else
|
||||
@@ -109,4 +109,4 @@
|
||||
squeak.RemoveComponent()
|
||||
H.regenerate_icons()
|
||||
transforming = FALSE
|
||||
UpdateButtonIcon()
|
||||
UpdateButtons()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
if(limbs_to_heal.len < 1)
|
||||
return 0
|
||||
return FALSE
|
||||
var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE)
|
||||
switch(mode)
|
||||
if(REGROWTH_USES_BLOOD)
|
||||
@@ -20,7 +20,7 @@
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/ability/limb_regrowth/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
@@ -282,9 +282,9 @@
|
||||
else
|
||||
O = outfit
|
||||
if(!istype(O))
|
||||
return 0
|
||||
return FALSE
|
||||
if(!O)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return O.equip(src, visualsOnly, preference_source)
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
if(cold)
|
||||
//CITADEL EDIT Mandatory for vore code.
|
||||
if(istype(loc, /obj/item/dogborg/sleeper) || isbelly(loc) || ismob(loc))
|
||||
return 1 //freezing to death in sleepers ruins fun.
|
||||
return TRUE //freezing to death in sleepers ruins fun.
|
||||
//END EDIT
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = cold ? get_cold_protection_flags(temperature) : get_heat_protection_flags(temperature)
|
||||
@@ -254,7 +254,7 @@
|
||||
if(missing_body_parts_flags & HAND_RIGHT)
|
||||
max_protection -= THERMAL_PROTECTION_HAND_RIGHT
|
||||
if(max_protection == 0) //Is it even a man if it doesn't have a body at all? Early return to avoid division by zero.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/thermal_protection = 0
|
||||
if(thermal_protection_flags)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/get_alt_name()
|
||||
if(name != GetVoice())
|
||||
|
||||
@@ -321,8 +321,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
//Please override this locally if you want to define when what species qualifies for what rank if human authority is enforced.
|
||||
/datum/species/proc/qualifies_for_rank(rank, list/features) //SPECIES JOB RESTRICTIONS
|
||||
//if(rank in GLOB.command_positions) Left as an example: The format qualifies for rank takes.
|
||||
// return 0 //It returns false when it runs the proc so they don't get jobs from the global list.
|
||||
return 1 //It returns 1 to say they are a-okay to continue.
|
||||
// return FALSE //It returns false when it runs the proc so they don't get jobs from the global list.
|
||||
return TRUE //It returns 1 to say they are a-okay to continue.
|
||||
|
||||
/**
|
||||
* Corrects organs in a carbon, removing ones it doesn't need and adding ones it does.
|
||||
@@ -1589,7 +1589,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.throw_alert("nutrition", /atom/movable/screen/alert/starving)
|
||||
|
||||
/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/species/proc/handle_mutations_and_radiation(mob/living/carbon/human/H)
|
||||
. = FALSE
|
||||
@@ -1645,7 +1645,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.help_shake_act(user)
|
||||
if(target != user)
|
||||
log_combat(user, target, "shaked")
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
var/we_breathe = !HAS_TRAIT(user, TRAIT_NOBREATH)
|
||||
var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
@@ -1661,12 +1661,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s grab attempt!</span>", target = user, \
|
||||
target_message = "<span class='warning'>[target] blocks your grab attempt!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.grab_act(user,target))
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
target.grabbedby(user)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, attackchain_flags = NONE)
|
||||
if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
@@ -1929,11 +1929,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(user != H)
|
||||
var/list/block_return = list()
|
||||
if(H.mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, block_return) & BLOCK_SUCCESS)
|
||||
return 0
|
||||
return FALSE
|
||||
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
|
||||
if(H.check_martial_melee_block())
|
||||
H.visible_message("<span class='warning'>[H] blocks [I]!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/hit_area
|
||||
|
||||
@@ -1958,7 +1958,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
I.do_stagger_action(H, user, totitemdamage)
|
||||
|
||||
if(!totitemdamage)
|
||||
return 0 //item force is zero
|
||||
return FALSE //item force is zero
|
||||
|
||||
var/bloody = 0
|
||||
if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
|
||||
@@ -2167,7 +2167,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
|
||||
if(!forced && hit_percent <= 0)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
if(!spread_damage)
|
||||
@@ -2224,7 +2224,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(BRAIN)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
// called when hit by a projectile
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
/datum/species/arachnid/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(istype(weapon, /obj/item/melee/flyswatter))
|
||||
return 9 //flyswatters deal 10x damage to arachnids
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/species/arachnid/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -37,4 +37,4 @@
|
||||
/datum/species/fly/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(istype(weapon, /obj/item/melee/flyswatter))
|
||||
return 29 //Flyswatters deal 30x damage to flypeople.
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
@@ -419,8 +419,9 @@
|
||||
var/obj/item/I
|
||||
if(istype(AM, /obj/item))
|
||||
I = AM
|
||||
if(I.thrownby == H) //No throwing stuff at yourself to trigger the teleport
|
||||
return 0
|
||||
var/mob/thrown_by = I.thrownby?.resolve()
|
||||
if(thrown_by == H) //No throwing stuff at yourself to trigger the teleport
|
||||
return FALSE
|
||||
else
|
||||
reactive_teleport(H)
|
||||
|
||||
@@ -462,8 +463,8 @@
|
||||
/datum/action/innate/unstable_teleport/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
if(world.time > last_teleport + cooldown)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/unstable_teleport/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
@@ -479,9 +480,9 @@
|
||||
spark_system.start()
|
||||
do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
last_teleport = world.time
|
||||
UpdateButtonIcon() //action icon looks unavailable
|
||||
sleep(cooldown + 5)
|
||||
UpdateButtonIcon() //action icon looks available again
|
||||
UpdateButtons() //action icon looks unavailable
|
||||
//action icon looks available again
|
||||
addtimer(CALLBACK(src, .proc/UpdateButtons), cooldown + 5)
|
||||
|
||||
|
||||
//honk
|
||||
@@ -545,7 +546,7 @@
|
||||
if(istype(AM, /obj/item))
|
||||
I = AM
|
||||
if(I.thrownby == H) //No throwing stuff at yourself to make bananas
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
var/datum/action/innate/ability/regrowth = H.ability_actions[INNATE_ABILITY_LIMB_REGROWTH]
|
||||
if(regrowth)
|
||||
regrowth.UpdateButtonIcon()
|
||||
regrowth.UpdateButtons()
|
||||
|
||||
return FALSE // to let living/handle_blood know that the species is handling blood instead
|
||||
|
||||
@@ -183,8 +183,8 @@
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/split_body/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
@@ -472,9 +472,9 @@
|
||||
|
||||
/datum/species/jelly/luminescent/proc/update_slime_actions()
|
||||
integrate_extract.update_name()
|
||||
integrate_extract.UpdateButtonIcon()
|
||||
extract_minor.UpdateButtonIcon()
|
||||
extract_major.UpdateButtonIcon()
|
||||
integrate_extract.UpdateButtons()
|
||||
extract_minor.UpdateButtons()
|
||||
extract_major.UpdateButtons()
|
||||
|
||||
/datum/species/jelly/luminescent/proc/update_glow(mob/living/carbon/C, intensity)
|
||||
if(intensity)
|
||||
@@ -514,7 +514,7 @@
|
||||
name = "Eject Extract"
|
||||
desc = "Eject your current slime extract."
|
||||
|
||||
/datum/action/innate/integrate_extract/UpdateButtonIcon(status_only, force)
|
||||
/datum/action/innate/integrate_extract/UpdateButton(atom/movable/screen/movable/action_button/button, status_only, force)
|
||||
if(!species || !species.current_extract)
|
||||
button_icon_state = "slimeconsume"
|
||||
else
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
H.equipOutfit(O, visualsOnly)
|
||||
H.internal = H.get_item_for_held_index(2)
|
||||
H.update_internals_hud_icon(1)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/species/plasmaman/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/heart/nightmare/Stop()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/organ/heart/nightmare/on_death()
|
||||
if(!owner)
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
|
||||
failed_last_breath = 1
|
||||
throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/safe_oxy_min = 16
|
||||
var/safe_oxy_max = 50
|
||||
@@ -312,7 +312,7 @@
|
||||
//BREATH TEMPERATURE
|
||||
handle_breath_temperature(breath)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//Fourth and final link in a breath chain
|
||||
/mob/living/carbon/proc/handle_breath_temperature(datum/gas_mixture/breath)
|
||||
@@ -660,7 +660,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//used in human and monkey handle_environment()
|
||||
/mob/living/carbon/proc/natural_bodytemperature_stabilization()
|
||||
if(HAS_TRAIT(src, TRAIT_COLDBLOODED) || HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 0 //Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this.
|
||||
return FALSE //return FALSE as your natural temperature. Species proc handle_environment() will adjust your temperature based on this.
|
||||
|
||||
var/body_temperature_difference = BODYTEMP_NORMAL - bodytemperature
|
||||
switch(bodytemperature)
|
||||
@@ -675,7 +675,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
|
||||
/mob/living/carbon/proc/get_cooling_efficiency()
|
||||
if(!HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/integration_bonus = min(blood_volume * SYNTH_INTEGRATION_COOLANT_CAP, integrating_blood * SYNTH_INTEGRATION_COOLANT_PENALTY) //Integration blood somewhat helps, though only at 40% impact and to a cap of 25% of current blood level.
|
||||
var/blood_effective_volume = blood_volume + integration_bonus
|
||||
@@ -691,7 +691,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
return suitlink //If you are wearing full EVA or lavaland hazard gear (on lavaland), assume it has been made to accomodate your cooling needs.
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if(!environment)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/heat = environment.return_temperature()
|
||||
@@ -711,12 +711,18 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(istype(head_item, /obj/item/clothing/head/helmet/space) && istype(suit_item, /obj/item/clothing/suit/space))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(istype(head_item, /obj/item/clothing/head/mod) && istype(suit_item, /obj/item/clothing/suit/mod))
|
||||
var/obj/item/clothing/suit/mod/modsuit = suit_item
|
||||
var/obj/item/mod/control/mod_control = modsuit.mod
|
||||
if(mod_control && mod_control.active)
|
||||
return TRUE
|
||||
|
||||
if(T && is_mining_level(T.z) && istype(head_item, /obj/item/clothing/head/hooded/explorer) && istype(suit_item, /obj/item/clothing/suit/hooded/explorer))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/////////
|
||||
//LIVER//
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
// taken from /mob/living/carbon/human/interactive/
|
||||
/mob/living/carbon/monkey/proc/walk2derpless(target)
|
||||
if(!target || IsStandingStill())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(myPath.len <= 0)
|
||||
myPath = get_path_to(src, target, 250, 1)
|
||||
@@ -39,14 +39,14 @@
|
||||
if(myPath.len >= 1)
|
||||
walk_to(src,myPath[1],0,5)
|
||||
myPath -= myPath[1]
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// failed to path correctly so just try to head straight for a bit
|
||||
walk_to(src,get_turf(target),0,5)
|
||||
sleep(1)
|
||||
walk_to(src,0)
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// taken from /mob/living/carbon/human/interactive/
|
||||
/mob/living/carbon/monkey/proc/IsDeadOrIncap(checkDead = TRUE)
|
||||
@@ -396,12 +396,13 @@
|
||||
retaliate(Proj.firer)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
|
||||
var/mob/living/carbon/human/H = I.thrownby
|
||||
retaliate(H)
|
||||
/mob/living/carbon/monkey/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(hitting_atom, /obj/item))
|
||||
var/obj/item/item_hitby = hitting_atom
|
||||
var/mob/thrown_by = item_hitby.thrownby?.resolve()
|
||||
if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by))
|
||||
var/mob/living/carbon/human/human_throwee = thrown_by
|
||||
retaliate(human_throwee)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/Crossed(atom/movable/AM)
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
/mob/living/carbon/monkey/has_smoke_protection()
|
||||
if(wear_mask)
|
||||
if(wear_mask.clothing_flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/monkey/handle_fire()
|
||||
. = ..()
|
||||
|
||||
@@ -171,8 +171,8 @@ GLOBAL_LIST_INIT(strippable_monkey_items, create_strippable_list(list(
|
||||
|
||||
/mob/living/carbon/monkey/IsVocal()
|
||||
if(!getorganslot(ORGAN_SLOT_LUNGS))
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/monkey/can_use_guns(obj/item/G)
|
||||
return TRUE
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
|
||||
return 1
|
||||
return TRUE
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
|
||||
else
|
||||
@@ -159,7 +159,7 @@
|
||||
damage = rand(20, 40)
|
||||
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
return TRUE
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
/mob/living/carbon/can_speak_vocal(message)
|
||||
if(silent)
|
||||
return 0
|
||||
return FALSE
|
||||
if(get_selected_language() == /datum/language/signlanguage && handcuffed)
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/could_speak_language(datum/language/language)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (hit_percent <= 0))
|
||||
return 0
|
||||
return FALSE
|
||||
var/damage_amount = forced ? damage : damage * hit_percent
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
@@ -32,7 +32,7 @@
|
||||
adjustCloneLoss(damage_amount, forced = forced)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage_amount, forced = forced)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
|
||||
switch(damagetype)
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
|
||||
if(blocked >= 100)
|
||||
return 0
|
||||
return FALSE
|
||||
if(brute)
|
||||
apply_damage(brute, BRUTE, def_zone, blocked)
|
||||
if(burn)
|
||||
@@ -82,12 +82,12 @@
|
||||
apply_damage(stamina, STAMINA, def_zone, blocked)
|
||||
if(brain)
|
||||
apply_damage(brain, BRAIN, def_zone, blocked)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!effect || (hit_percent <= 0))
|
||||
return 0
|
||||
return FALSE
|
||||
switch(effecttype)
|
||||
if(EFFECT_STUN)
|
||||
Stun(effect * hit_percent)
|
||||
@@ -109,7 +109,7 @@
|
||||
if(EFFECT_JITTER)
|
||||
if((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE))
|
||||
jitteriness = max(jitteriness,(effect * hit_percent))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = 0, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
|
||||
@@ -163,7 +163,7 @@
|
||||
|
||||
/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
return FALSE
|
||||
oxyloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
@@ -179,7 +179,7 @@
|
||||
affected_by = TOX_SYSCORRUPT
|
||||
|
||||
if(toxins_type != affected_by)
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return toxloss
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@
|
||||
if(E.can_run_emote(user, status_check = FALSE))
|
||||
keys += E.key
|
||||
|
||||
keys = sortList(keys)
|
||||
keys = sort_list(keys)
|
||||
|
||||
for(var/emote in keys)
|
||||
if(LAZYLEN(message) > 1)
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
if(fire_stacks < 0) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
fire_stacks = min(0, fire_stacks + 1)//So we dry ourselves back to default, nonflammable.
|
||||
if(!on_fire)
|
||||
return 1
|
||||
return TRUE
|
||||
if(fire_stacks > 0)
|
||||
adjust_fire_stacks(-0.1) //the fire is slowly consumed
|
||||
else
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
|
||||
// If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
|
||||
// This can happen when a player is stood on the same turf as a directional window. All attempts to push
|
||||
// the window will fail as get_dir will return 0 and the player will be unable to move the window when
|
||||
// the window will fail as get_dir will return FALSE and the player will be unable to move the window when
|
||||
// it should be pushable.
|
||||
// In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
|
||||
// a fallback.
|
||||
@@ -636,7 +636,7 @@
|
||||
if(mind)
|
||||
for(var/S in mind.spell_list)
|
||||
var/obj/effect/proc_holder/spell/spell = S
|
||||
spell.updateButtonIcon()
|
||||
spell.UpdateButton()
|
||||
|
||||
//proc used to remove all immobilisation effects + reset stamina
|
||||
/mob/living/proc/remove_CC(should_update_mobility = TRUE)
|
||||
@@ -683,7 +683,7 @@
|
||||
/mob/living/proc/can_be_revived()
|
||||
. = 1
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/update_damage_overlays()
|
||||
return
|
||||
@@ -1051,27 +1051,27 @@
|
||||
//basic fast checks go first. When overriding this proc, I recommend calling ..() at the end.
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return 0
|
||||
return FALSE
|
||||
if(is_centcom_level(T.z)) //dont detect mobs on centcom
|
||||
return 0
|
||||
return FALSE
|
||||
if(is_away_level(T.z))
|
||||
return 0
|
||||
return FALSE
|
||||
if(user != null && src == user)
|
||||
return 0
|
||||
return FALSE
|
||||
if(invisibility || alpha == 0)//cloaked
|
||||
return 0
|
||||
return FALSE
|
||||
if(digitalcamo || digitalinvis)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
|
||||
if(!near_camera(src))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//used in datum/reagents/reaction() proc
|
||||
/mob/living/proc/get_permeability_protection(list/target_zones)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering
|
||||
return
|
||||
@@ -1120,7 +1120,7 @@
|
||||
/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(mind && mind.has_antag_datum(/datum/antagonist/devil))
|
||||
return check_devil_bane_multiplier(weapon, attacker)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/check_acedia()
|
||||
if(mind && mind.has_objective(/datum/objective/sintouched/acedia))
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
// before doing anything, check if the user moused over them properly
|
||||
if(!client)
|
||||
return BLOCK_NONE
|
||||
var/found = attacker == client.mouseObject
|
||||
var/found = attacker == client.mouse_object_ref?.resolve()
|
||||
if(!found)
|
||||
for(var/i in client.moused_over_objects)
|
||||
if(i == object)
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
|
||||
|
||||
/mob/living/proc/getarmor(def_zone, type)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2) from bright lights
|
||||
/mob/living/proc/get_eye_protection()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
|
||||
/mob/living/proc/get_ear_protection()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/is_mouth_covered(head_only = 0, mask_only = 0)
|
||||
return FALSE
|
||||
@@ -96,7 +96,7 @@
|
||||
return P.on_hit(src, final_percent, def_zone) ? BULLET_ACT_HIT : BULLET_ACT_BLOCK
|
||||
|
||||
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
|
||||
if(throwforce && w_class)
|
||||
@@ -104,50 +104,53 @@
|
||||
else if(w_class)
|
||||
return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
/mob/living/proc/catch_item(obj/item/I, skip_throw_mode_check = FALSE)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
// Throwingdatum can be null if someone had an accident() while slipping with an item in hand.
|
||||
var/obj/item/I
|
||||
var/throwpower = 30
|
||||
if(isitem(AM))
|
||||
I = AM
|
||||
throwpower = I.throwforce
|
||||
var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
var/list/block_return = list()
|
||||
var/total_damage = AM.throwforce
|
||||
if(mob_run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, block_return) & BLOCK_SUCCESS)
|
||||
if(!isitem(AM))
|
||||
// Filled with made up numbers for non-items.
|
||||
if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list()))
|
||||
hitpush = FALSE
|
||||
skipcatch = TRUE
|
||||
blocked = TRUE
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) //Item sounds are handled in the item itself
|
||||
return ..()
|
||||
|
||||
var/obj/item/thrown_item = AM
|
||||
if(thrown_item.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions
|
||||
return ..()
|
||||
|
||||
if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list()))
|
||||
hitpush = FALSE
|
||||
skipcatch = TRUE
|
||||
blocked = TRUE
|
||||
total_damage = block_calculate_resultant_damage(total_damage, block_return)
|
||||
if(I)
|
||||
var/nosell_hit = SEND_SIGNAL(I, COMSIG_MOVABLE_IMPACT_ZONE, src, impacting_zone, throwingdatum, FALSE, blocked)
|
||||
if(nosell_hit)
|
||||
skipcatch = TRUE
|
||||
hitpush = FALSE
|
||||
if(!skipcatch && isturf(I.loc) && catch_item(I))
|
||||
return TRUE
|
||||
var/dtype = BRUTE
|
||||
|
||||
dtype = I.damtype
|
||||
var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
var/nosell_hit = SEND_SIGNAL(thrown_item, COMSIG_MOVABLE_IMPACT_ZONE, src, zone, blocked, throwingdatum) // TODO: find a better way to handle hitpush and skipcatch for humans
|
||||
if(nosell_hit)
|
||||
skipcatch = TRUE
|
||||
hitpush = FALSE
|
||||
|
||||
if(!blocked)
|
||||
if(!nosell_hit)
|
||||
visible_message("<span class='danger'>[src] is hit by [I]!</span>", \
|
||||
"<span class='userdanger'>You're hit by [I]!</span>")
|
||||
if(!I.throwforce)
|
||||
return
|
||||
var/armor = run_armor_check(impacting_zone, MELEE, "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, impacting_zone, armor, sharpness=I.get_sharpness(), wound_bonus=(nosell_hit * CANT_WOUND))
|
||||
else
|
||||
return 1
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
..()
|
||||
if(blocked)
|
||||
return TRUE
|
||||
|
||||
var/mob/thrown_by = thrown_item.thrownby?.resolve()
|
||||
if(thrown_by)
|
||||
log_combat(thrown_by, src, "threw and hit", thrown_item)
|
||||
if(nosell_hit)
|
||||
return ..()
|
||||
visible_message(span_danger("[src] is hit by [thrown_item]!"), \
|
||||
span_userdanger("You're hit by [thrown_item]!"))
|
||||
if(!thrown_item.throwforce)
|
||||
return
|
||||
var/armor = run_armor_check(zone, MELEE, "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", thrown_item.armour_penetration, "", FALSE)
|
||||
apply_damage(thrown_item.throwforce, thrown_item.damtype, zone, armor, sharpness = thrown_item.get_sharpness(), wound_bonus = (nosell_hit * CANT_WOUND))
|
||||
if(QDELETED(src)) //Damage can delete the mob.
|
||||
return
|
||||
if(lying) // physics says it's significantly harder to push someone by constantly chucking random furniture at them if they are down on the floor.
|
||||
hitpush = FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(3)
|
||||
@@ -199,11 +202,11 @@
|
||||
if(GRAB_NECK)
|
||||
log_combat(user, src, "attempted to strangle", addition="kill grab")
|
||||
if(!do_mob(user, src, grab_upgrade_time))
|
||||
return 0
|
||||
return FALSE
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
|
||||
return 0
|
||||
return FALSE
|
||||
if(user.voremode && user.grab_state == GRAB_AGGRESSIVE)
|
||||
return 0
|
||||
return FALSE
|
||||
user.setGrabState(user.grab_state + 1)
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
@@ -237,7 +240,7 @@
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
user.set_pull_offsets(src, grab_state)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/on_attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags)
|
||||
..() //Ignoring parent return value here.
|
||||
@@ -299,7 +302,7 @@
|
||||
M.visible_message("<span class='notice'>\The [M] [M.friendly_verb_continuous] [src]!</span>",
|
||||
"<span class='notice'>You [M.friendly_verb_simple] [src]!</span>", target = src,
|
||||
target_message = "<span class='notice'>\The [M] [M.friendly_verb_continuous] you!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
@@ -307,7 +310,7 @@
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
var/list/return_list = list()
|
||||
if(mob_run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected), return_list) & BLOCK_SUCCESS)
|
||||
return 0
|
||||
return FALSE
|
||||
damage = block_calculate_resultant_damage(damage, return_list)
|
||||
if(M.attack_sound)
|
||||
playsound(src, M.attack_sound, 50, 1, 1)
|
||||
@@ -415,7 +418,7 @@
|
||||
|
||||
/mob/living/acid_act(acidpwr, acid_volume)
|
||||
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
///As the name suggests, this should be called to apply electric shocks.
|
||||
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
@@ -515,7 +518,7 @@
|
||||
|
||||
//called when the mob receives a loud bang
|
||||
/mob/living/proc/soundbang_act()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
//to damage the clothes worn by a mob
|
||||
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
/mob/living/proc/update_resting(update_mobility = TRUE)
|
||||
if(update_mobility)
|
||||
update_mobility()
|
||||
update_rest_hud_icon()
|
||||
|
||||
//Force mob to rest, does NOT do stamina damage.
|
||||
//It's really not recommended to use this proc to give feedback, hence why silent is defaulting to true.
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
if (!buckled.anchored)
|
||||
return buckled.Move(newloc, direct)
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/old_direction = dir
|
||||
var/turf/T = loc
|
||||
|
||||
@@ -208,7 +208,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
if(radio_return & REDUCE_RANGE)
|
||||
message_range = 1
|
||||
if(radio_return & NOPASS)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//No screams in space, unless you're next to someone.
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -226,7 +226,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
succumb()
|
||||
to_chat(src, compose_message(src, language, message, null, spans, message_mode))
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE, atom/movable/source)
|
||||
. = ..()
|
||||
@@ -358,23 +358,23 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/can_speak(message) //For use outside of Say()
|
||||
if(can_speak_basic(message) && can_speak_vocal(message))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/can_speak_basic(message, ignore_spam = FALSE) //Check BEFORE handling of xeno and ling channels
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (muted).</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!ignore_spam && client.handle_spam_prevention(message,MUTE_IC))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels
|
||||
var/obj/item/bodypart/leftarm = get_bodypart(BODY_ZONE_L_ARM)
|
||||
var/obj/item/bodypart/rightarm = get_bodypart(BODY_ZONE_R_ARM)
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE) && get_selected_language() != /datum/language/signlanguage)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if (get_selected_language() == /datum/language/signlanguage)
|
||||
var/left_disabled = FALSE
|
||||
@@ -390,15 +390,15 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
else
|
||||
right_disabled = TRUE
|
||||
if (left_disabled && right_disabled) // We want this to only return false if both arms are either missing or disabled since you could technically sign one-handed.
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(is_muzzled())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(!IsVocal())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/get_key(message)
|
||||
var/key = message[1]
|
||||
@@ -468,9 +468,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_BINARY)
|
||||
return ITALICS | REDUCE_RANGE //Does not return 0 since this is only reached by humans, not borgs or AIs.
|
||||
return ITALICS | REDUCE_RANGE //Does not return FALSE since this is only reached by humans, not borgs or AIs.
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/say_mod(input, message_mode)
|
||||
. = ..()
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
has_field_of_vision = FALSE //Vision through cameras.
|
||||
var/battery = 200 //emergency power if the AI's APC is off
|
||||
var/list/network = list("ss13")
|
||||
var/obj/machinery/camera/current
|
||||
var/list/connected_robots = list()
|
||||
@@ -46,7 +47,7 @@
|
||||
var/obj/item/multitool/aiMulti
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed.
|
||||
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
|
||||
var/datum/effect_system/spark_spread/spark_system //So they can initialize sparks whenever/N
|
||||
var/obj/machinery/status_display/controlled_display
|
||||
|
||||
//MALFUNCTION
|
||||
@@ -83,7 +84,7 @@
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
|
||||
var/obj/structure/AIcore/deactivated/linked_core //For exosuit control
|
||||
var/obj/structure/ai_core/deactivated/linked_core //For exosuit control
|
||||
var/mob/living/silicon/robot/deployed_shell = null //For shell control
|
||||
var/datum/action/innate/deploy_shell/deploy_action = new
|
||||
var/datum/action/innate/deploy_last_shell/redeploy_action = new
|
||||
@@ -105,11 +106,17 @@
|
||||
///remember AI's last location
|
||||
var/atom/lastloc
|
||||
interaction_range = INFINITY
|
||||
///whether its mmi is a posibrain or regular mmi when going ai mob to ai core structure
|
||||
var/posibrain_inside = TRUE
|
||||
///whether its cover is opened, so you can wirecut it for deconstruction
|
||||
var/opened = FALSE
|
||||
///whether AI is anchored or not, used for checks
|
||||
var/is_anchored = TRUE
|
||||
|
||||
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
|
||||
. = ..()
|
||||
if(!target_ai) //If there is no player/brain inside.
|
||||
new/obj/structure/AIcore/deactivated(loc) //New empty terminal.
|
||||
new/obj/structure/ai_core/deactivated(loc) //New empty terminal.
|
||||
return INITIALIZE_HINT_QDEL //Delete AI.
|
||||
|
||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
@@ -125,6 +132,8 @@
|
||||
mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.")
|
||||
to_chat(src, "<span class='userdanger'>You have been installed as an AI! </span>")
|
||||
to_chat(src, "<span class='danger'>You must obey your silicon laws above all else. Your objectives will consider you to be dead.</span>")
|
||||
if(!mind.has_ever_been_ai)
|
||||
mind.has_ever_been_ai = TRUE
|
||||
|
||||
to_chat(src, "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>")
|
||||
to_chat(src, "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>")
|
||||
@@ -237,6 +246,8 @@
|
||||
. += text("Systems nonfunctional")
|
||||
return
|
||||
. += text("System integrity: [(health + 100) * 0.5]%")
|
||||
if(isturf(loc)) //only show if we're "in" a core
|
||||
. += "Backup Power: [battery * 0.5]%"
|
||||
. += text("Connected cyborgs: [length(connected_robots)]")
|
||||
for(var/r in connected_robots)
|
||||
var/mob/living/silicon/robot/connected_robot = r
|
||||
@@ -333,18 +344,64 @@
|
||||
if(!isturf(loc)) // if their location isn't a turf
|
||||
return // stop
|
||||
if(incapacitated())
|
||||
return
|
||||
var/is_anchored = FALSE
|
||||
if(move_resist == MOVE_FORCE_OVERPOWERING)
|
||||
if(battery < 50)
|
||||
to_chat(src, span_warning("Insufficient backup power!"))
|
||||
return
|
||||
battery = battery - 50
|
||||
to_chat(src, span_notice("You route power from your backup battery to move the bolts."))
|
||||
flip_anchored()
|
||||
to_chat(src, "<b>You are now [is_anchored ? "" : "un"]anchored.</b>")
|
||||
|
||||
/mob/living/silicon/ai/proc/flip_anchored()
|
||||
if(is_anchored)
|
||||
is_anchored = !is_anchored
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
status_flags |= CANPUSH
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
else
|
||||
is_anchored = TRUE
|
||||
is_anchored = !is_anchored
|
||||
move_resist = MOVE_FORCE_OVERPOWERING
|
||||
status_flags &= ~CANPUSH
|
||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
|
||||
to_chat(src, "<b>You are now [is_anchored ? "" : "un"]anchored.</b>")
|
||||
// the message in the [] will change depending whether or not the AI is anchored
|
||||
/mob/living/silicon/ai/proc/ai_mob_to_structure()
|
||||
disconnect_shell()
|
||||
ShutOffDoomsdayDevice()
|
||||
var/obj/structure/ai_core/deactivated/ai_core = new(get_turf(src), /* skip_mmi_creation = */ TRUE)
|
||||
if(make_mmi_drop_and_transfer(ai_core.core_mmi, the_core = ai_core))
|
||||
qdel(src)
|
||||
return ai_core
|
||||
|
||||
/mob/living/silicon/ai/proc/make_mmi_drop_and_transfer(obj/item/mmi/the_mmi, the_core)
|
||||
var/mmi_type
|
||||
if(posibrain_inside)
|
||||
mmi_type = new/obj/item/mmi/posibrain(src, /* autoping = */ FALSE)
|
||||
else
|
||||
mmi_type = new/obj/item/mmi(src)
|
||||
if(hack_software)
|
||||
new/obj/item/malf_upgrade(get_turf(src))
|
||||
the_mmi = mmi_type
|
||||
the_mmi.brain = new /obj/item/organ/brain(the_mmi)
|
||||
the_mmi.brain.organ_flags |= ORGAN_FROZEN
|
||||
the_mmi.brain.name = "[real_name]'s brain"
|
||||
the_mmi.name = "[initial(the_mmi.name)]: [real_name]"
|
||||
the_mmi.brainmob = new /mob/living/brain(the_mmi)
|
||||
the_mmi.brainmob.name = src.real_name
|
||||
the_mmi.brainmob.real_name = src.real_name
|
||||
the_mmi.brainmob.container = the_mmi
|
||||
the_mmi.brainmob.suiciding = suiciding
|
||||
if(the_core)
|
||||
var/obj/structure/ai_core/core = the_core
|
||||
core.core_mmi = the_mmi
|
||||
the_mmi.forceMove(the_core)
|
||||
else
|
||||
the_mmi.forceMove(get_turf(src))
|
||||
if(the_mmi.brainmob.stat == DEAD && !suiciding)
|
||||
the_mmi.brainmob.stat = CONSCIOUS
|
||||
if(mind)
|
||||
mind.transfer_to(the_mmi.brainmob)
|
||||
the_mmi.update_appearance()
|
||||
return TRUE
|
||||
|
||||
// AIs are immobile
|
||||
/mob/living/silicon/ai/update_mobility()
|
||||
@@ -427,18 +484,30 @@
|
||||
return
|
||||
|
||||
if (href_list["ai_take_control"]) //Mech domination
|
||||
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"])
|
||||
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"]) in GLOB.mechas_list
|
||||
if (!M)
|
||||
return
|
||||
|
||||
var/mech_has_controlbeacon = FALSE
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in M.trackers)
|
||||
mech_has_controlbeacon = TRUE
|
||||
break
|
||||
if(!can_dominate_mechs && !mech_has_controlbeacon)
|
||||
message_admins("Warning: possible href exploit by [key_name(usr)] - attempted control of a mecha without can_dominate_mechs or a control beacon in the mech.")
|
||||
usr.log_message("possibly attempting href exploit - attempted control of a mecha without can_dominate_mechs or a control beacon in the mech.", LOG_ADMIN)
|
||||
return
|
||||
|
||||
if(controlled_equipment)
|
||||
to_chat(src, "<span class='warning'>You are already loaded into an onboard computer!</span>")
|
||||
to_chat(src, span_warning("You are already loaded into an onboard computer!"))
|
||||
return
|
||||
if(!GLOB.cameranet.checkCameraVis(M))
|
||||
to_chat(src, "<span class='warning'>Exosuit is no longer near active cameras.</span>")
|
||||
to_chat(src, span_warning("Exosuit is no longer near active cameras."))
|
||||
return
|
||||
if(!isturf(loc))
|
||||
to_chat(src, "<span class='warning'>You aren't in your core!</span>")
|
||||
to_chat(src, span_warning("You aren't in your core!"))
|
||||
return
|
||||
if(M)
|
||||
M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
|
||||
M.transfer_ai(AI_MECH_HACK, src, usr) //Called on the mech itself.
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
|
||||
@@ -549,7 +618,7 @@
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class)
|
||||
if (viewalerts)
|
||||
ai_alerts()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/ai/freeCamera(area/home, obj/machinery/camera/cam)
|
||||
for(var/class in alarms)
|
||||
@@ -825,17 +894,19 @@
|
||||
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
|
||||
return
|
||||
ShutOffDoomsdayDevice()
|
||||
new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
|
||||
var/obj/structure/ai_core/new_core = new /obj/structure/ai_core/deactivated(loc, posibrain_inside)//Spawns a deactivated terminal at AI location.
|
||||
new_core.circuit.battery = battery
|
||||
ai_restore_power()//So the AI initially has power.
|
||||
control_disabled = 1//Can't control things remotely if you're stuck in a card!
|
||||
radio_enabled = 0 //No talking on the built-in radio for you either!
|
||||
control_disabled = TRUE //Can't control things remotely if you're stuck in a card!
|
||||
interaction_range = 0
|
||||
radio_enabled = FALSE //No talking on the built-in radio for you either!
|
||||
forceMove(card)
|
||||
card.AI = src
|
||||
to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.")
|
||||
to_chat(user, "<span class='boldnotice'>Transfer successful</span>: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
|
||||
|
||||
/mob/living/silicon/ai/can_buckle()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/ai/incapacitated(ignore_restraints, ignore_grab)
|
||||
if(aiRestorePowerRoutine)
|
||||
@@ -1063,7 +1134,7 @@
|
||||
// Sends an announcement the AI has cryoed.
|
||||
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
|
||||
announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, list())
|
||||
new /obj/structure/AIcore/latejoin_inactive(loc)
|
||||
new /obj/structure/ai_core/latejoin_inactive(loc)
|
||||
if(src.mind)
|
||||
//Handle job slot/tater cleanup.
|
||||
if(src.mind.assigned_role == "AI")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
|
||||
if(I.force && I.damtype != STAMINA && stat != DEAD && !QDELETED(src)) //only sparks if real damage is dealt.
|
||||
spark_system.start()
|
||||
|
||||
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
|
||||
@@ -12,8 +12,8 @@
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/ai/emp_act(severity)
|
||||
. = ..()
|
||||
@@ -48,3 +48,105 @@
|
||||
|
||||
/mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/silicon/ai/emag_act(mob/user, obj/item/card/emag/emag_card) ///emags access panel lock, so you can crowbar it without robotics access or consent
|
||||
. = ..()
|
||||
if(emagged)
|
||||
balloon_alert(user, "access panel lock already shorted!")
|
||||
return
|
||||
balloon_alert(user, "access panel lock shorted")
|
||||
var/message = (user ? "[user] shorts out your access panel lock!" : "Your access panel lock was short circuited!")
|
||||
to_chat(src, span_warning(message))
|
||||
do_sparks(3, FALSE, src) // just a bit of extra "oh shit" to the ai - might grab its attention
|
||||
emagged = TRUE
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/ai/wrench_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return
|
||||
balloon_alert(user, "[!is_anchored ? "tightening" : "loosening"] bolts...")
|
||||
balloon_alert(src, "bolts being [!is_anchored ? "tightened" : "loosened"]...")
|
||||
if(!tool.use_tool(src, user, 4 SECONDS))
|
||||
return TRUE
|
||||
flip_anchored()
|
||||
balloon_alert(user, "bolts [is_anchored ? "tightened" : "loosened"]")
|
||||
balloon_alert(src, "bolts [is_anchored ? "tightened" : "loosened"]")
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/ai/crowbar_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return
|
||||
if(!is_anchored)
|
||||
balloon_alert(user, "bolt it down first!")
|
||||
return TRUE
|
||||
if(opened)
|
||||
if(emagged)
|
||||
balloon_alert(user, "access panel lock damaged!")
|
||||
return TRUE
|
||||
balloon_alert(user, "closing access panel...")
|
||||
balloon_alert(src, "access panel being closed...")
|
||||
if(!tool.use_tool(src, user, 5 SECONDS))
|
||||
return TRUE
|
||||
balloon_alert(src, "access panel closed")
|
||||
balloon_alert(user, "access panel closed")
|
||||
opened = FALSE
|
||||
return TRUE
|
||||
if(stat == DEAD)
|
||||
to_chat(user, span_warning("The access panel looks damaged, you try dislodging the cover."))
|
||||
else
|
||||
var/consent
|
||||
var/consent_override = FALSE
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
if(human_user.wear_id)
|
||||
var/list/access = human_user.wear_id.GetAccess()
|
||||
if(ACCESS_ROBOTICS in access)
|
||||
consent_override = TRUE
|
||||
if(mind)
|
||||
consent = tgui_alert(src, "[user] is attempting to open your access panel, unlock the cover?", "AI Access Panel", list("Yes", "No"))
|
||||
if(consent == "No" && !consent_override && !emagged)
|
||||
to_chat(user, span_notice("[src] refuses to unlock its access panel."))
|
||||
return TRUE
|
||||
if(consent != "Yes" && (consent_override || emagged))
|
||||
to_chat(user, span_warning("[src] refuses to unlock its access panel...so you[!emagged ? " swipe your ID and " : " "]open it anyway!"))
|
||||
else
|
||||
if(!consent_override && !emagged)
|
||||
to_chat(user, span_notice("[src] did not respond to your request to unlock its access panel cover lock."))
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, span_notice("[src] did not respond to your request to unlock its access panel cover lock. You[!emagged ? " swipe your ID and " : " "]open it anyway."))
|
||||
|
||||
balloon_alert(user, "prying open access panel...")
|
||||
balloon_alert(src, "access panel being pried open...")
|
||||
if(!tool.use_tool(src, user, (stat == DEAD ? 40 SECONDS : 5 SECONDS)))
|
||||
return TRUE
|
||||
balloon_alert(src, "access panel opened")
|
||||
balloon_alert(user, "access panel opened")
|
||||
opened = TRUE
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/ai/wirecutter_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return
|
||||
if(!is_anchored)
|
||||
balloon_alert(user, "bolt it down first!")
|
||||
return TRUE
|
||||
if(!opened)
|
||||
balloon_alert(user, "open the access panel first!")
|
||||
return TRUE
|
||||
balloon_alert(src, "neural network being disconnected...")
|
||||
balloon_alert(user, "disconnecting neural network...")
|
||||
if(!tool.use_tool(src, user, (stat == DEAD ? 40 SECONDS : 5 SECONDS)))
|
||||
return TRUE
|
||||
if(IS_MALF_AI(src))
|
||||
to_chat(user, span_userdanger("The voltage inside the wires rises dramatically!"))
|
||||
user.electrocute_act(120, src)
|
||||
opened = FALSE
|
||||
return TRUE
|
||||
to_chat(src, span_danger("You feel incredibly confused and disorientated."))
|
||||
var/atom/ai_structure = ai_mob_to_structure()
|
||||
ai_structure.balloon_alert(user, "disconnected neural network")
|
||||
return TRUE
|
||||
|
||||
@@ -177,8 +177,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
if(chunk.visibleTurfs[position])
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/cameranet/proc/stat_entry()
|
||||
if(!statclick)
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
return TRUE
|
||||
|
||||
/mob/camera/aiEye/Move()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/camera/aiEye/proc/GetViewerClient()
|
||||
if(ai)
|
||||
|
||||
@@ -28,11 +28,15 @@
|
||||
// Handle power damage (oxy)
|
||||
if(aiRestorePowerRoutine)
|
||||
// Lost power
|
||||
adjustOxyLoss(1)
|
||||
if (!battery)
|
||||
to_chat(src, span_warning("Your backup battery's output drops below usable levels. It takes only a moment longer for your systems to fail, corrupted and unusable."))
|
||||
adjustOxyLoss(200)
|
||||
else
|
||||
battery--
|
||||
else
|
||||
// Gain Power
|
||||
if(getOxyLoss())
|
||||
adjustOxyLoss(-1)
|
||||
if (battery < 200)
|
||||
battery++
|
||||
|
||||
if(!lacks_power())
|
||||
var/area/home = get_area(src)
|
||||
|
||||
@@ -187,8 +187,8 @@
|
||||
SEND_SOUND(M, voice)
|
||||
else
|
||||
SEND_SOUND(only_listener, voice)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
#undef VOX_DELAY
|
||||
#endif
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = SHARP_NONE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (!forced && hit_percent <= 0))
|
||||
return 0
|
||||
return FALSE
|
||||
var/damage_amount = forced ? damage : damage * hit_percent
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage_amount, forced = forced)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage_amount, forced = forced)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/silicon/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
|
||||
/datum/action/innate/pai/Trigger()
|
||||
if(!ispAI(owner))
|
||||
return 0
|
||||
return FALSE
|
||||
P = owner
|
||||
|
||||
/datum/action/innate/pai/software
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/datum/paiCandidate/proc/savefile_save(mob/user)
|
||||
if(IsGuestKey(user.key))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/savefile/F = new /savefile(src.savefile_path(user))
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
WRITE_FILE(F["version"], 1)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// loads the savefile corresponding to the mob's ckey
|
||||
// if silent=true, report incompatible savefiles
|
||||
@@ -33,12 +33,12 @@
|
||||
|
||||
/datum/paiCandidate/proc/savefile_load(mob/user, silent = TRUE)
|
||||
if (IsGuestKey(user.key))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/path = savefile_path(user)
|
||||
|
||||
if (!fexists(path))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/savefile/F = new /savefile(path)
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
fdel(path)
|
||||
if (!silent)
|
||||
alert(user, "Your savefile was incompatible with this version and was deleted.")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
F["name"] >> src.name
|
||||
F["description"] >> src.description
|
||||
F["role"] >> src.role
|
||||
F["comments"] >> src.comments
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
@@ -206,12 +206,12 @@
|
||||
var/count = 0
|
||||
while(!isliving(M))
|
||||
if(!M || !M.loc)
|
||||
return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
|
||||
return FALSE //For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
|
||||
M = M.loc
|
||||
count++
|
||||
if(count >= 6)
|
||||
to_chat(src, "You are not being carried by anyone!")
|
||||
return 0
|
||||
return FALSE
|
||||
spawn CheckDNA(M, src)
|
||||
|
||||
if("pdamessage")
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
if(module_active)
|
||||
return held_items.Find(module_active)
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Selects the module in the slot module_num.
|
||||
|
||||
@@ -28,11 +28,13 @@
|
||||
inv2 = new /atom/movable/screen/robot/module2()
|
||||
inv3 = new /atom/movable/screen/robot/module3()
|
||||
|
||||
ident = rand(1, 999)
|
||||
|
||||
if(!shell)
|
||||
aiPDA = new/obj/item/pda/ai(src)
|
||||
aiPDA.owner = real_name
|
||||
aiPDA.ownjob = "Cyborg"
|
||||
aiPDA.name = real_name + " (" + aiPDA.ownjob + ")"
|
||||
aiPDA.name = real_name + " ([aiPDA.ownjob])"
|
||||
|
||||
previous_health = health
|
||||
|
||||
@@ -59,26 +61,29 @@
|
||||
update_icons()
|
||||
. = ..()
|
||||
|
||||
//If this body is meant to be a borg controlled by the AI player
|
||||
//If this body is meant to be a borg controlled by the AI player
|
||||
if(shell)
|
||||
make_shell()
|
||||
|
||||
//MMI stuff. Held togheter by magic. ~Miauw
|
||||
else if(!mmi || !mmi.brainmob)
|
||||
mmi = new (src)
|
||||
mmi.brain = new /obj/item/organ/brain(mmi)
|
||||
mmi.brain.organ_flags |= ORGAN_FROZEN
|
||||
mmi.brain.name = "[real_name]'s brain"
|
||||
mmi.icon_state = "mmi_full"
|
||||
mmi.name = "Man-Machine Interface: [real_name]"
|
||||
mmi.brainmob = new(mmi)
|
||||
mmi.brainmob.name = src.real_name
|
||||
mmi.brainmob.real_name = src.real_name
|
||||
mmi.brainmob.container = mmi
|
||||
var/obj/item/borg/upgrade/ai/board = new(src)
|
||||
make_shell(board)
|
||||
add_to_upgrades(board)
|
||||
else
|
||||
//MMI stuff. Held togheter by magic. ~Miauw
|
||||
if(!mmi?.brainmob)
|
||||
mmi = new (src)
|
||||
mmi.brain = new /obj/item/organ/brain(mmi)
|
||||
mmi.brain.organ_flags |= ORGAN_FROZEN
|
||||
mmi.brain.name = "[real_name]'s brain"
|
||||
mmi.icon_state = "mmi_full"
|
||||
mmi.name = "[initial(mmi.name)]: [real_name]"
|
||||
mmi.brainmob = new(mmi)
|
||||
mmi.brainmob.name = src.real_name
|
||||
mmi.brainmob.real_name = src.real_name
|
||||
mmi.brainmob.container = mmi
|
||||
mmi.update_appearance()
|
||||
|
||||
INVOKE_ASYNC(src, .proc/updatename)
|
||||
|
||||
playsound(loc, 'sound/voice/liveagain.ogg', 75, TRUE)
|
||||
aicamera = new/obj/item/camera/siliconcam/robot_camera(src)
|
||||
toner = tonermax
|
||||
diag_hud_set_borgcell()
|
||||
@@ -157,7 +162,7 @@
|
||||
if(BORG_SEC_AVAILABLE)
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in sortList(modulelist)
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in sort_list(modulelist)
|
||||
if(!input_module || module.type != /obj/item/robot_module)
|
||||
return
|
||||
|
||||
@@ -266,7 +271,7 @@
|
||||
if(source.z != z)
|
||||
return
|
||||
if(stat == DEAD)
|
||||
return 1
|
||||
return TRUE
|
||||
var/list/our_sort = alarms[class]
|
||||
for(var/areaname in our_sort)
|
||||
if (areaname == home.name)
|
||||
@@ -274,7 +279,7 @@
|
||||
var/list/sources = alarm[3]
|
||||
if (!(source in sources))
|
||||
sources += source
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/obj/machinery/camera/cam = null
|
||||
var/list/our_cams = null
|
||||
@@ -330,194 +335,145 @@
|
||||
return FALSE
|
||||
return ISINRANGE(T1.x, T0.x - interaction_range, T0.x + interaction_range) && ISINRANGE(T1.y, T0.y - interaction_range, T0.y + interaction_range)
|
||||
|
||||
/mob/living/silicon/robot/proc/attempt_welder_repair(obj/item/W, mob/user)
|
||||
if(!W.tool_behaviour == TOOL_WELDER)
|
||||
return
|
||||
if(!getBruteLoss())
|
||||
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
|
||||
return
|
||||
if(!W.tool_start_check(user, amount=0)) //The welder has 1u of fuel consumed by it's afterattack, so we don't need to worry about taking any away.
|
||||
return
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if(src == user)
|
||||
to_chat(user, "<span class='notice'>You start fixing yourself...</span>")
|
||||
if(!W.use_tool(src, user, 50))
|
||||
return
|
||||
adjustBruteLoss(-10)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
|
||||
if(!do_after(user, 30, target = src))
|
||||
return
|
||||
adjustBruteLoss(-30)
|
||||
updatehealth()
|
||||
add_fingerprint(user)
|
||||
visible_message("<span class='notice'>[user] has fixed some of the dents on [src].</span>")
|
||||
|
||||
/mob/living/silicon/robot/proc/attempt_cable_repair(obj/item/stack/cable_coil/W, mob/user)
|
||||
if (getFireLoss() > 0 || getToxLoss() > 0)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if(src == user)
|
||||
to_chat(user, "<span class='notice'>You start fixing yourself...</span>")
|
||||
if(!W.use_tool(src, user, 50, 1, skill_gain_mult = TRIVIAL_USE_TOOL_MULT))
|
||||
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
|
||||
return
|
||||
adjustFireLoss(-10)
|
||||
adjustToxLoss(-10)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
|
||||
if(!W.use_tool(src, user, 30, 1))
|
||||
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
|
||||
return
|
||||
adjustFireLoss(-30)
|
||||
adjustToxLoss(-30)
|
||||
updatehealth()
|
||||
user.visible_message("[user] has fixed some of the burnt wires on [src].", "<span class='notice'>You fix some of the burnt wires on [src].</span>")
|
||||
else
|
||||
to_chat(user, "The wires seem fine, there's no need to fix them.")
|
||||
|
||||
/mob/living/silicon/robot/attackby(obj/item/W, mob/user, params)
|
||||
if(W.tool_behaviour == TOOL_WELDER && (user.a_intent != INTENT_HARM || user == src))
|
||||
INVOKE_ASYNC(src, .proc/attempt_welder_repair, W, user)
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
|
||||
INVOKE_ASYNC(src, .proc/attempt_cable_repair, W, user)
|
||||
return
|
||||
|
||||
else if(W.tool_behaviour == TOOL_CROWBAR) // crowbar means open or close the cover
|
||||
if(opened)
|
||||
to_chat(user, "<span class='notice'>You close the cover.</span>")
|
||||
opened = 0
|
||||
update_icons()
|
||||
else
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The cover is locked and cannot be opened!</span>")
|
||||
if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if (getFireLoss() > 0 || getToxLoss() > 0)
|
||||
if(src == user)
|
||||
to_chat(user, span_notice("You start fixing yourself..."))
|
||||
if(!W.use_tool(src, user, 5 SECONDS, 1, skill_gain_mult = TRIVIAL_USE_TOOL_MULT))
|
||||
to_chat(user, span_warning("You need more cable to repair [src]!"))
|
||||
return
|
||||
adjustFireLoss(-10)
|
||||
adjustToxLoss(-10)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You open the cover.</span>")
|
||||
opened = 1
|
||||
update_icons()
|
||||
to_chat(user, span_notice("You start fixing [src]..."))
|
||||
if(!W.use_tool(src, user, 3 SECONDS, 1))
|
||||
to_chat(user, span_warning("You need more cable to repair [src]!"))
|
||||
adjustFireLoss(-30)
|
||||
adjustToxLoss(-30)
|
||||
updatehealth()
|
||||
user.visible_message(span_notice("[user] has fixed some of the burnt wires on [src]."), span_notice("You fix some of the burnt wires on [src]."))
|
||||
else
|
||||
to_chat(user, span_warning("The wires seem fine, there's no need to fix them."))
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
|
||||
if(istype(W, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
|
||||
if(wiresexposed)
|
||||
to_chat(user, "<span class='warning'>Close the cover first!</span>")
|
||||
to_chat(user, span_warning("Close the cover first!"))
|
||||
else if(cell)
|
||||
to_chat(user, "<span class='warning'>There is a power cell already installed!</span>")
|
||||
to_chat(user, span_warning("There is a power cell already installed!"))
|
||||
else
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
cell = W
|
||||
to_chat(user, "<span class='notice'>You insert the power cell.</span>")
|
||||
to_chat(user, span_notice("You insert the power cell."))
|
||||
update_icons()
|
||||
diag_hud_set_borgcell()
|
||||
return
|
||||
|
||||
else if(is_wire_tool(W))
|
||||
if(is_wire_tool(W))
|
||||
if (wiresexposed)
|
||||
wires.interact(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't reach the wiring!</span>")
|
||||
to_chat(user, span_warning("You can't reach the wiring!"))
|
||||
return
|
||||
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER && opened && !cell) // haxing
|
||||
wiresexposed = !wiresexposed
|
||||
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
|
||||
update_icons()
|
||||
|
||||
else if((W.tool_behaviour == TOOL_SCREWDRIVER) && opened && cell) // radio
|
||||
if(shell)
|
||||
to_chat(user, "You cannot seem to open the radio compartment") //Prevent AI radio key theft
|
||||
else if(radio)
|
||||
radio.attackby(W,user)//Push it to the radio to let it handle everything
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
|
||||
update_icons()
|
||||
|
||||
else if(W.tool_behaviour == TOOL_WRENCH && opened && !cell) //Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module.
|
||||
if(!locked_down)
|
||||
to_chat(user, "<span class='boldannounce'>[src]'s bolts spark! Maybe you should lock them down first!</span>")
|
||||
spark_system.start()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start to unfasten [src]'s securing bolts...</span>")
|
||||
if(W.use_tool(src, user, 50, volume=50) && !cell)
|
||||
user.visible_message("[user] deconstructs [src]!", "<span class='notice'>You unfasten the securing bolts, and [src] falls to pieces!</span>")
|
||||
deconstruct()
|
||||
|
||||
else if(istype(W, /obj/item/aiModule))
|
||||
var/obj/item/aiModule/MOD = W
|
||||
if(istype(W, /obj/item/ai_module))
|
||||
var/obj/item/ai_module/MOD = W
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>You need access to the robot's insides to do that!</span>")
|
||||
to_chat(user, span_warning("You need access to the robot's insides to do that!"))
|
||||
return
|
||||
if(wiresexposed)
|
||||
to_chat(user, "<span class='warning'>You need to close the wire panel to do that!</span>")
|
||||
to_chat(user, span_warning("You need to close the wire panel to do that!"))
|
||||
return
|
||||
if(!cell)
|
||||
to_chat(user, "<span class='warning'>You need to install a power cell to do that!</span>")
|
||||
to_chat(user, span_warning("You need to install a power cell to do that!"))
|
||||
return
|
||||
if(shell) //AI shells always have the laws of the AI
|
||||
to_chat(user, "<span class='warning'>[src] is controlled remotely! You cannot upload new laws this way!</span>")
|
||||
to_chat(user, span_warning("[src] is controlled remotely! You cannot upload new laws this way!"))
|
||||
return
|
||||
if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers
|
||||
emote("buzz-[user.name]")
|
||||
if(connected_ai && lawupdate)
|
||||
to_chat(user, span_warning("[src] is receiving laws remotely from a synced AI!"))
|
||||
return
|
||||
if(emagged)
|
||||
to_chat(user, span_warning("The law interface glitches out!"))
|
||||
emote("buzz")
|
||||
return
|
||||
if(!mind) //A player mind is required for law procs to run antag checks.
|
||||
to_chat(user, "<span class='warning'>[src] is entirely unresponsive!</span>")
|
||||
to_chat(user, span_warning("[src] is entirely unresponsive!"))
|
||||
return
|
||||
MOD.install(laws, user) //Proc includes a success mesage so we don't need another one
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/encryptionkey/) && opened)
|
||||
if(istype(W, /obj/item/encryptionkey) && opened)
|
||||
if(radio)//sanityyyyyy
|
||||
radio.attackby(W,user)//GTFO, you have your own procs
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Unable to locate a radio!</span>")
|
||||
to_chat(user, span_warning("Unable to locate a radio!"))
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/pda)) // trying to unlock the interface with an ID card
|
||||
if(emagged)//still allow them to open the cover
|
||||
to_chat(user, "<span class='notice'>The interface seems slightly damaged.</span>")
|
||||
if (W.GetID()) // trying to unlock the interface with an ID card
|
||||
if(opened)
|
||||
to_chat(user, "<span class='warning'>You must close the cover to swipe an ID card!</span>")
|
||||
to_chat(user, span_warning("You must close the cover to swipe an ID card!"))
|
||||
else
|
||||
if(allowed(usr))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] [src]'s cover.</span>")
|
||||
to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] [src]'s cover."))
|
||||
update_icons()
|
||||
if(emagged)
|
||||
to_chat(user, span_notice("The cover interface glitches out for a split second."))
|
||||
logevent("ChÃ¥vÃis cover lock has been [locked ? "engaged" : "released"]") //ChÃ¥vÃis: see above line
|
||||
else
|
||||
logevent("Chassis cover lock has been [locked ? "engaged" : "released"]")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
to_chat(user, span_danger("Access denied."))
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/borg/upgrade/))
|
||||
if(istype(W, /obj/item/borg/upgrade))
|
||||
var/obj/item/borg/upgrade/U = W
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>You must access the borg's internals!</span>")
|
||||
else if(!src.module && U.require_module)
|
||||
to_chat(user, "<span class='warning'>The borg must choose a module before it can be upgraded!</span>")
|
||||
else if(U.locked)
|
||||
to_chat(user, "<span class='warning'>The upgrade is locked and cannot be used yet!</span>")
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(U))
|
||||
return
|
||||
if(U.action(src))
|
||||
to_chat(user, "<span class='notice'>You apply the upgrade to [src].</span>")
|
||||
if(U.one_use)
|
||||
U.afterInstall(src)
|
||||
qdel(U)
|
||||
else
|
||||
U.forceMove(src)
|
||||
upgrades += U
|
||||
U.afterInstall(src)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Upgrade error.</span>")
|
||||
U.forceMove(drop_location())
|
||||
to_chat(user, span_warning("You must access the cyborg's internals!"))
|
||||
return
|
||||
if(!module && U.require_module)
|
||||
to_chat(user, span_warning("The cyborg must choose a model before it can be upgraded!"))
|
||||
return
|
||||
if(U.locked)
|
||||
to_chat(user, span_warning("The upgrade is locked and cannot be used yet!"))
|
||||
return
|
||||
if(!user.canUnEquip(U))
|
||||
to_chat(user, span_warning("The upgrade is stuck to you and you can't seem to let go of it!"))
|
||||
return
|
||||
apply_upgrade(U, user)
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/toner))
|
||||
if(istype(W, /obj/item/toner))
|
||||
if(toner >= tonermax)
|
||||
to_chat(user, "<span class='warning'>The toner level of [src] is at its highest level possible!</span>")
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
toner = tonermax
|
||||
qdel(W)
|
||||
to_chat(user, "<span class='notice'>You fill the toner level of [src] to its max capacity.</span>")
|
||||
else
|
||||
return ..()
|
||||
to_chat(user, span_warning("The toner level of [src] is at its highest level possible!"))
|
||||
return
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
return
|
||||
toner = tonermax
|
||||
qdel(W)
|
||||
to_chat(user, span_notice("You fill the toner level of [src] to its max capacity."))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/flashlight))
|
||||
if(!opened)
|
||||
to_chat(user, span_warning("You need to open the panel to repair the headlamp!"))
|
||||
return
|
||||
if(lamp_functional)
|
||||
to_chat(user, span_warning("The headlamp is already functional!"))
|
||||
return
|
||||
if(!user.temporarilyRemoveItemFromInventory(W))
|
||||
to_chat(user, span_warning("[W] seems to be stuck to your hand. You'll have to find a different light."))
|
||||
return
|
||||
lamp_functional = TRUE
|
||||
qdel(W)
|
||||
to_chat(user, span_notice("You replace the headlamp bulbs."))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/crowbar_act(mob/living/user, obj/item/I) //TODO: make fucking everything up there in that attackby() proc use the proper tool_act() procs. But honestly, who has time for that? 'cause I know for sure that you, the person reading this, sure as hell doesn't.
|
||||
var/validbreakout = FALSE
|
||||
@@ -1023,7 +979,7 @@
|
||||
ionpulse = FALSE
|
||||
revert_shell()
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/robot/proc/has_module()
|
||||
if(!module || module.type == /obj/item/robot_module)
|
||||
@@ -1064,29 +1020,45 @@
|
||||
*Checking Exited() to detect if a hat gets up and walks off.
|
||||
*Drones and pAIs might do this, after all.
|
||||
*/
|
||||
/mob/living/silicon/robot/Exited(atom/A)
|
||||
if(hat && hat == A)
|
||||
/mob/living/silicon/robot/Exited(atom/movable/gone)
|
||||
. = ..()
|
||||
if(hat == gone)
|
||||
hat = null
|
||||
if(!QDELETED(src)) //Don't update icons if we are deleted.
|
||||
update_icons()
|
||||
return ..()
|
||||
|
||||
///Use this to add upgrades to robots. It'll register signals for when the upgrade is moved or deleted, if not single use.
|
||||
/mob/living/silicon/robot/proc/add_to_upgrades(obj/item/borg/upgrade/new_upgrade, mob/user)
|
||||
if(gone == cell)
|
||||
cell = null
|
||||
|
||||
if(gone == mmi)
|
||||
mmi = null
|
||||
|
||||
///Called when a mob uses an upgrade on an open borg. Checks to make sure the upgrade can be applied
|
||||
/mob/living/silicon/robot/proc/apply_upgrade(obj/item/borg/upgrade/new_upgrade, mob/user, admin_added)
|
||||
if(!admin_added && isnull(user))
|
||||
return FALSE
|
||||
if(new_upgrade in upgrades)
|
||||
return FALSE
|
||||
if(!user.temporarilyRemoveItemFromInventory(new_upgrade)) //calling the upgrade's dropped() proc /before/ we add action buttons
|
||||
if(!admin_added && !user.temporarilyRemoveItemFromInventory(new_upgrade)) //calling the upgrade's dropped() proc /before/ we add action buttons
|
||||
return FALSE
|
||||
if(!new_upgrade.action(src, user))
|
||||
to_chat(user, "<span class='danger'>Upgrade error.</span>")
|
||||
new_upgrade.forceMove(loc) //gets lost otherwise
|
||||
to_chat(user, span_danger("Upgrade error."))
|
||||
if(admin_added)
|
||||
qdel(new_upgrade)
|
||||
else
|
||||
new_upgrade.forceMove(loc) //gets lost otherwise
|
||||
return FALSE
|
||||
to_chat(user, "<span class='notice'>You apply the upgrade to [src].</span>")
|
||||
to_chat(user, span_notice("You apply the upgrade to [src]."))
|
||||
add_to_upgrades(new_upgrade)
|
||||
return TRUE
|
||||
|
||||
///Moves the upgrade inside the robot and registers relevant signals.
|
||||
/mob/living/silicon/robot/proc/add_to_upgrades(obj/item/borg/upgrade/new_upgrade)
|
||||
to_chat(src, "----------------\nNew hardware detected...Identified as \"<b>[new_upgrade]</b>\"...Setup complete.\n----------------")
|
||||
if(new_upgrade.one_use)
|
||||
logevent("Firmware [new_upgrade] run successfully.")
|
||||
qdel(new_upgrade)
|
||||
return FALSE
|
||||
return
|
||||
upgrades += new_upgrade
|
||||
new_upgrade.forceMove(src)
|
||||
RegisterSignal(new_upgrade, COMSIG_MOVABLE_MOVED, PROC_REF(remove_from_upgrades))
|
||||
@@ -1117,15 +1089,17 @@
|
||||
* * board - B.O.R.I.S. module board used for transforming the cyborg into AI shell
|
||||
*/
|
||||
/mob/living/silicon/robot/proc/make_shell(obj/item/borg/upgrade/ai/board)
|
||||
if(!board)
|
||||
upgrades |= new /obj/item/borg/upgrade/ai(src)
|
||||
if(isnull(board))
|
||||
stack_trace("make_shell was called without a board argument! This is never supposed to happen!")
|
||||
return FALSE
|
||||
|
||||
shell = TRUE
|
||||
braintype = "AI Shell"
|
||||
name = "Empty AI Shell-[ident]"
|
||||
real_name = name
|
||||
GLOB.available_ai_shells |= src
|
||||
if(!QDELETED(builtInCamera))
|
||||
builtInCamera.c_tag = real_name //update the camera name too
|
||||
builtInCamera.c_tag = real_name //update the camera name too
|
||||
diag_hud_set_aishell()
|
||||
notify_ai(AI_SHELL)
|
||||
|
||||
@@ -1328,7 +1302,7 @@
|
||||
switch(choice)
|
||||
if("Resting")
|
||||
update_icons()
|
||||
return 0
|
||||
return FALSE
|
||||
if("Sitting")
|
||||
sitting = 1
|
||||
if("Belly up")
|
||||
|
||||
@@ -94,6 +94,76 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
|
||||
apply_status_effect(/datum/status_effect/vtec_disabled, time)
|
||||
update_movespeed()
|
||||
|
||||
/mob/living/silicon/robot/welder_act(mob/living/user, obj/item/tool)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return FALSE
|
||||
. = TRUE
|
||||
if (!getBruteLoss())
|
||||
to_chat(user, span_warning("[src] is already in good condition!"))
|
||||
return
|
||||
if (!tool.tool_start_check(user, amount=0)) //The welder has 1u of fuel consumed by it's afterattack, so we don't need to worry about taking any away.
|
||||
return
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if(src == user)
|
||||
to_chat(user, span_notice("You start fixing yourself..."))
|
||||
if(!tool.use_tool(src, user, 50))
|
||||
return
|
||||
adjustBruteLoss(-10)
|
||||
else
|
||||
to_chat(user, span_notice("You start fixing [src]..."))
|
||||
if(!do_after(user, 3 SECONDS, target = src))
|
||||
return
|
||||
adjustBruteLoss(-30)
|
||||
updatehealth()
|
||||
add_fingerprint(user)
|
||||
visible_message(span_notice("[user] has fixed some of the dents on [src]."))
|
||||
|
||||
/mob/living/silicon/robot/crowbar_act(mob/living/user, obj/item/tool)
|
||||
. = TRUE
|
||||
if(opened)
|
||||
to_chat(user, span_notice("You close the cover."))
|
||||
opened = FALSE
|
||||
update_icons()
|
||||
else
|
||||
if(locked)
|
||||
to_chat(user, span_warning("The cover is locked and cannot be opened!"))
|
||||
else
|
||||
to_chat(user, span_notice("You open the cover."))
|
||||
opened = TRUE
|
||||
update_icons()
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/robot/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
if(!opened)
|
||||
return FALSE
|
||||
. = TRUE
|
||||
if(!cell) // haxing
|
||||
wiresexposed = !wiresexposed
|
||||
to_chat(user, span_notice("The wires have been [wiresexposed ? "exposed" : "unexposed"]."))
|
||||
else // radio
|
||||
if(shell)
|
||||
to_chat(user, span_warning("You cannot seem to open the radio compartment!")) //Prevent AI radio key theft
|
||||
else if(radio)
|
||||
radio.screwdriver_act(user, tool) // Push it to the radio to let it handle everything
|
||||
else
|
||||
to_chat(user, span_warning("Unable to locate a radio!"))
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/wrench_act(mob/living/user, obj/item/tool)
|
||||
if(!(opened && !cell)) // Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module.
|
||||
return FALSE
|
||||
. = TRUE
|
||||
if(!locked_down)
|
||||
to_chat(user, span_boldannounce("[src]'s bolts spark! Maybe you should lock them down first!"))
|
||||
spark_system.start()
|
||||
return
|
||||
to_chat(user, span_notice("You start to unfasten [src]'s securing bolts..."))
|
||||
if(tool.use_tool(src, user, 5 SECONDS, volume = 50) && !cell)
|
||||
user.visible_message(span_notice("[user] deconstructs [src]!"), span_notice("You unfasten the securing bolts, and [src] falls to pieces!"))
|
||||
deconstruct()
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/fire_act()
|
||||
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
|
||||
IgniteMob()
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high ///If this is a path, this gets created as an object in Initialize.
|
||||
|
||||
var/opened = FALSE
|
||||
var/emagged = FALSE
|
||||
var/emag_cooldown = 0
|
||||
var/wiresexposed = FALSE
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
if(!(m in R.held_items))
|
||||
. += m
|
||||
|
||||
/obj/item/robot_module/proc/get_or_create_estorage(var/storage_type)
|
||||
/obj/item/robot_module/proc/get_or_create_estorage(storage_type)
|
||||
for(var/datum/robot_energy_storage/S in storages)
|
||||
if(istype(S, storage_type))
|
||||
return S
|
||||
@@ -95,42 +95,9 @@
|
||||
|
||||
/obj/item/robot_module/proc/add_module(obj/item/I, nonstandard, requires_rebuild)
|
||||
rad_flags |= RAD_NO_CONTAMINATE
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
|
||||
if(is_type_in_list(S, list(/obj/item/stack/sheet/metal, /obj/item/stack/rods, /obj/item/stack/tile/plasteel)))
|
||||
if(S.custom_materials?.len && S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)])
|
||||
S.cost = S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)] * 0.25
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
|
||||
|
||||
else if(istype(S, /obj/item/stack/sheet/glass))
|
||||
S.cost = 500
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/glass)
|
||||
|
||||
else if(istype(S, /obj/item/stack/sheet/rglass/cyborg))
|
||||
var/obj/item/stack/sheet/rglass/cyborg/G = S
|
||||
G.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
|
||||
G.glasource = get_or_create_estorage(/datum/robot_energy_storage/glass)
|
||||
|
||||
else if(istype(S, /obj/item/stack/medical))
|
||||
S.cost = 250
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/medical)
|
||||
|
||||
else if(istype(S, /obj/item/stack/cable_coil))
|
||||
S.cost = 1
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/wire)
|
||||
|
||||
else if(istype(S, /obj/item/stack/marker_beacon))
|
||||
S.cost = 1
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/beacon)
|
||||
|
||||
else if(istype(S, /obj/item/stack/packageWrap))
|
||||
S.cost = 1
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/wrapping_paper)
|
||||
|
||||
if(S && S.source)
|
||||
S.set_custom_materials(null)
|
||||
S.is_cyborg = 1
|
||||
var/obj/item/stack/S = I
|
||||
if(istype(I, /obj/item/stack) && !S.is_cyborg) // Now handled in the type itself
|
||||
stack_trace("Non-cyborg variant of /obj/item/stack added to a cyborg's modules.")
|
||||
|
||||
if(I.loc != src)
|
||||
I.forceMove(src)
|
||||
@@ -380,7 +347,7 @@
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-med")
|
||||
bad_snowflake.pixel_x = -16
|
||||
med_icons["Alina"] = bad_snowflake
|
||||
med_icons = sortList(med_icons)
|
||||
med_icons = sort_list(med_icons)
|
||||
var/med_borg_icon = show_radial_menu(R, R , med_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), R), radius = 42, require_near = TRUE)
|
||||
switch(med_borg_icon)
|
||||
if("Default")
|
||||
@@ -498,7 +465,7 @@
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-eng")
|
||||
bad_snowflake.pixel_x = -16
|
||||
engi_icons["Alina"] = bad_snowflake
|
||||
engi_icons = sortList(engi_icons)
|
||||
engi_icons = sort_list(engi_icons)
|
||||
var/engi_borg_icon = show_radial_menu(R, R , engi_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), R), radius = 42, require_near = TRUE)
|
||||
switch(engi_borg_icon)
|
||||
if("Default")
|
||||
@@ -595,7 +562,7 @@
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
sec_icons["Alina"] = bad_snowflake
|
||||
sec_icons = sortList(sec_icons)
|
||||
sec_icons = sort_list(sec_icons)
|
||||
var/sec_borg_icon = show_radial_menu(R, R , sec_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), R), radius = 42, require_near = TRUE)
|
||||
switch(sec_borg_icon)
|
||||
if("Default")
|
||||
@@ -681,7 +648,7 @@
|
||||
|
||||
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/static/list/peace_icons = sortList(list(
|
||||
var/static/list/peace_icons = sort_list(list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "peace"),
|
||||
"Borgi" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "borgi"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "whitespider")
|
||||
@@ -852,7 +819,7 @@
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
service_icons["Alina"] = bad_snowflake
|
||||
service_icons = sortList(service_icons)
|
||||
service_icons = sort_list(service_icons)
|
||||
var/service_robot_icon = show_radial_menu(R, R , service_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), R), radius = 42, require_near = TRUE)
|
||||
switch(service_robot_icon)
|
||||
if("(Service) Waitress")
|
||||
@@ -935,9 +902,9 @@
|
||||
/obj/item/gps/cyborg,
|
||||
/obj/item/gripper/mining,
|
||||
/obj/item/cyborg_clamp,
|
||||
/obj/item/stack/marker_beacon,
|
||||
/obj/item/stack/marker_beacon/cyborg,
|
||||
/obj/item/destTagger,
|
||||
/obj/item/stack/packageWrap,
|
||||
/obj/item/stack/packageWrap/cyborg,
|
||||
/obj/item/card/id/miningborg)
|
||||
emag_modules = list(/obj/item/borg/stun)
|
||||
ratvar_modules = list(
|
||||
@@ -966,7 +933,7 @@
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
mining_icons[a] = wide
|
||||
mining_icons = sortList(mining_icons)
|
||||
mining_icons = sort_list(mining_icons)
|
||||
var/mining_borg_icon = show_radial_menu(R, R , mining_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), R), radius = 42, require_near = TRUE)
|
||||
switch(mining_borg_icon)
|
||||
if("Lavaland")
|
||||
@@ -1056,7 +1023,7 @@
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/stack/medical/bone_gel,
|
||||
/obj/item/stack/medical/bone_gel/cyborg,
|
||||
/obj/item/melee/transforming/energy/sword/cyborg/saw,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/card/emag,
|
||||
@@ -1128,10 +1095,10 @@
|
||||
if (energy >= amount)
|
||||
energy -= amount
|
||||
if (energy == 0)
|
||||
return 1
|
||||
return TRUE
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/robot_energy_storage/proc/add_charge(amount)
|
||||
energy = min(energy + amount, max_energy)
|
||||
@@ -1191,7 +1158,7 @@
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/stack/medical/bone_gel,
|
||||
/obj/item/stack/medical/bone_gel/cyborg,
|
||||
/obj/item/melee/transforming/energy/sword/cyborg/saw,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/silicon/robot/Process_Spacemove(movement_dir = 0)
|
||||
if(ionpulse())
|
||||
return 1
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/mob_negates_gravity()
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
to_chat(M, "<span class='binarysay'>[link] [rendered]</span>")
|
||||
|
||||
/mob/living/silicon/binarycheck()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/lingcheck()
|
||||
return 0 //Borged or AI'd lings can't speak on the ling channel.
|
||||
return FALSE //Borged or AI'd lings can't speak on the ling channel.
|
||||
|
||||
/mob/living/silicon/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
@@ -44,7 +44,7 @@
|
||||
radio.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/get_message_mode(message)
|
||||
. = ..()
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
|
||||
///Whether we have been emagged
|
||||
var/emagged = FALSE
|
||||
var/hack_software = FALSE //Will be able to use hacking actions
|
||||
var/interaction_range = 7 //wireless control range
|
||||
|
||||
@@ -362,12 +364,12 @@
|
||||
to_chat(src, "<span class='notice'>Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]</span>")
|
||||
|
||||
/mob/living/silicon/put_in_hand_check() // This check is for borgs being able to receive items, not put them in others' hands.
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// But the src mob is a silicon!! Disable.
|
||||
/mob/living/silicon/stripPanelEquip(obj/item/what, mob/who, slot)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/silicon/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //Secbots won't hunt silicon units
|
||||
@@ -432,7 +434,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/is_literate()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/get_inactive_held_item()
|
||||
return FALSE
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
unbuckle_mob(M)
|
||||
M.electrocute_act(shock_damage/100, source, siemens_coeff, flags) //Hard metal shell conducts!
|
||||
return 0 //So borgs they don't die trying to fix wiring
|
||||
return FALSE //So borgs they don't die trying to fix wiring
|
||||
|
||||
/mob/living/silicon/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
if(.) //successful larva bite
|
||||
var/damage = rand(1, 3)
|
||||
attack_threshold_check(damage)
|
||||
return 1
|
||||
return TRUE
|
||||
if (M.a_intent == INTENT_HELP)
|
||||
if (health > 0)
|
||||
visible_message("<span class='notice'>[M.name] [response_help_continuous] [src].</span>", \
|
||||
|
||||
@@ -349,8 +349,8 @@
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item)
|
||||
if(slot_item && (slot_item.item_flags & NEEDS_PERMIT))
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/explode()
|
||||
walk_to(src,0)
|
||||
|
||||
@@ -284,9 +284,9 @@
|
||||
/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
|
||||
var/area/t_area = get_area(t)
|
||||
if(t_area && (t_area.name == "Space" || findtext(t_area.name, "huttle")))
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//Floorbots, having several functions, need sort out special conditions here.
|
||||
/mob/living/simple_animal/bot/floorbot/process_scan(scan_target)
|
||||
|
||||
@@ -138,13 +138,14 @@
|
||||
bike_horn(A)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(AM, /obj/item))
|
||||
/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(hitting_atom, /obj/item))
|
||||
playsound(src, honksound, 50, TRUE, -1)
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < health && I.thrownby && (istype(I.thrownby, /mob/living/carbon/human)))
|
||||
var/mob/living/carbon/human/H = I.thrownby
|
||||
retaliate(H)
|
||||
var/obj/item/item_hitby = hitting_atom
|
||||
var/mob/thrown_by = item_hitby.thrownby?.resolve()
|
||||
if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by))
|
||||
var/mob/living/carbon/human/human_throwee = thrown_by
|
||||
retaliate(human_throwee)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/bike_horn() //use bike_horn
|
||||
|
||||
@@ -351,12 +351,13 @@
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
|
||||
var/mob/living/carbon/human/H = I.thrownby
|
||||
retaliate(H)
|
||||
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(istype(hitting_atom, /obj/item))
|
||||
var/obj/item/item_hitby = hitting_atom
|
||||
var/mob/thrown_by = item_hitby.thrownby?.resolve()
|
||||
if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by))
|
||||
var/mob/living/carbon/human/human_throwee = thrown_by
|
||||
retaliate(human_throwee)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
var/can_repair_constructs = FALSE
|
||||
var/can_repair_self = FALSE
|
||||
var/runetype
|
||||
var/datum/action/innate/cult/create_rune/our_rune
|
||||
/// Theme controls color. THEME_CULT is red THEME_WIZARD is purple and THEME_HOLY is blue
|
||||
var/theme = "cult"
|
||||
var/datum/mind/original_mind
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Initialize(mapload)
|
||||
@@ -51,24 +54,26 @@
|
||||
update_health_hud()
|
||||
var/spellnum = 1
|
||||
for(var/spell in construct_spells)
|
||||
var/the_spell = new spell(null)
|
||||
AddSpell(the_spell)
|
||||
var/obj/effect/proc_holder/spell/S = mob_spell_list[spellnum]
|
||||
var/pos = 2+spellnum*31
|
||||
if(construct_spells.len >= 4)
|
||||
pos -= 31*(construct_spells.len - 4)
|
||||
S.action.button.screen_loc = "6:[pos],4:-2"
|
||||
S.action.button.moved = "6:[pos],4:-2"
|
||||
var/obj/effect/proc_holder/spell/the_spell = new spell(null)
|
||||
the_spell?.action.default_button_position ="6:[pos],4:-2"
|
||||
AddSpell(the_spell)
|
||||
spellnum++
|
||||
if(runetype)
|
||||
var/datum/action/innate/cult/create_rune/CR = new runetype(src)
|
||||
CR.Grant(src)
|
||||
var/pos = 2+spellnum*31
|
||||
CR.button.screen_loc = "6:[pos],4:-2"
|
||||
CR.button.moved = "6:[pos],4:-2"
|
||||
if(construct_spells.len >= 4)
|
||||
pos -= 31*(construct_spells.len - 4)
|
||||
our_rune = new runetype(src)
|
||||
our_rune.default_button_position = "6:[pos],4:-2" // Set the default position to this random position
|
||||
our_rune.Grant(src)
|
||||
if(icon_state)
|
||||
add_overlay("glow_[icon_state]_[theme]")
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Destroy()
|
||||
original_mind = null
|
||||
QDEL_NULL(our_rune)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/death()
|
||||
@@ -274,17 +279,17 @@
|
||||
if(isconstruct(A)) //is it a construct?
|
||||
var/mob/living/simple_animal/hostile/construct/C = A
|
||||
if(C.health < C.maxHealth) //is it hurt? let's go heal it if it is
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/builder/CanAttack(atom/the_target)
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return 0
|
||||
return FALSE
|
||||
if(Found(the_target) || ..()) //If we Found it or Can_Attack it normally, we Can_Attack it as long as it wasn't invisible
|
||||
return 1 //as a note this shouldn't be added to base hostile mobs because it'll mess up retaliate hostile mobs
|
||||
return TRUE //as a note this shouldn't be added to base hostile mobs because it'll mess up retaliate hostile mobs
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/builder/MoveToTarget(var/list/possible_targets)
|
||||
..()
|
||||
@@ -292,7 +297,7 @@
|
||||
var/mob/living/L = target
|
||||
if(isconstruct(L) && L.health >= L.maxHealth) //is this target an unhurt construct? stop trying to heal it
|
||||
LoseTarget()
|
||||
return 0
|
||||
return FALSE
|
||||
if(L.health <= melee_damage_lower+melee_damage_upper) //ey bucko you're hurt as fuck let's go hit you
|
||||
retreat_distance = null
|
||||
minimum_distance = 1
|
||||
|
||||
@@ -670,7 +670,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
vocal_pitch = 0.6
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0)
|
||||
return 1 //Void puppies can navigate space.
|
||||
return TRUE //Void puppies can navigate space.
|
||||
|
||||
|
||||
//LISA! SQUEEEEEEEEE~
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/drone/mob_negates_gravity()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/drone/mob_has_gravity()
|
||||
return ..() || mob_negates_gravity()
|
||||
@@ -286,10 +286,10 @@
|
||||
|
||||
/mob/living/simple_animal/drone/bee_friendly()
|
||||
// Why would bees pay attention to drones?
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/drone/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
return 0 //So they don't die trying to fix wiring
|
||||
return FALSE //So they don't die trying to fix wiring
|
||||
|
||||
/mob/living/simple_animal/drone/can_see_reagents()
|
||||
. = ..()
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/get_armor_effectiveness()
|
||||
if(GLOB.ratvar_awakens)
|
||||
return 1
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/triggerAlarm(class, area/A, O, obj/alarmsource)
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
return (armorval * get_armor_effectiveness()) //armor is reduced for tiny fragile drones
|
||||
|
||||
/mob/living/simple_animal/drone/proc/get_armor_effectiveness()
|
||||
return 0 //multiplier for whatever head armor you wear as a drone
|
||||
return FALSE //multiplier for whatever head armor you wear as a drone
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_drone_hack(hack, clockwork)
|
||||
if(!istype(src) || !mind)
|
||||
|
||||
@@ -15,22 +15,22 @@
|
||||
if(I == internal_storage)
|
||||
internal_storage = null
|
||||
update_inv_internal_storage()
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
|
||||
switch(slot)
|
||||
if(ITEM_SLOT_HEAD)
|
||||
if(head)
|
||||
return 0
|
||||
return FALSE
|
||||
if(!((I.slot_flags & ITEM_SLOT_HEAD) || (I.slot_flags & ITEM_SLOT_MASK)))
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(ITEM_SLOT_DEX_STORAGE)
|
||||
if(internal_storage)
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
|
||||
udder.milkAnimal(O, user)
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
/mob/living/simple_animal/cow/attackby(obj/item/O, mob/user, params)
|
||||
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
|
||||
udder.milkAnimal(O, user)
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ GLOBAL_LIST(bad_gremlin_items)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/gremlin/IsAdvancedToolUser()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/gremlin/proc/divide()
|
||||
//Health is halved and then reduced by 2. A new gremlin is spawned with the same health as the parent
|
||||
|
||||
@@ -257,7 +257,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100)
|
||||
else
|
||||
resulthealth = round((summoner.health / summoner.maxHealth) * 100, 0.5)
|
||||
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#efeeef'>[resulthealth]%</font></div>"
|
||||
hud_used.healths.maptext = MAPTEXT("<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#efeeef'>[resulthealth]%</font></div>")
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/adjustHealth(amount, updating_health = TRUE, forced = FALSE) //The spirit is invincible, but passes on damage to the summoner
|
||||
. = amount
|
||||
|
||||
@@ -41,21 +41,21 @@
|
||||
..() //lose items, then return
|
||||
|
||||
//SLOT HANDLING BULLSHIT FOR INTERNAL STORAGE
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/doUnEquip(obj/item/I, force, silent = FALSE)
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/doUnEquip(obj/item/I, force, invdrop, silent = FALSE)
|
||||
if(..())
|
||||
update_inv_hands()
|
||||
if(I == internal_storage)
|
||||
internal_storage = null
|
||||
update_inv_internal_storage()
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
|
||||
switch(slot)
|
||||
if(ITEM_SLOT_DEX_STORAGE)
|
||||
if(internal_storage)
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/equip_to_slot(obj/item/I, slot)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/protector/ToggleMode()
|
||||
if(cooldown > world.time)
|
||||
return 0
|
||||
return FALSE
|
||||
cooldown = world.time + 10
|
||||
if(toggle)
|
||||
cut_overlays()
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
var/datum/action/boss/AB = ab
|
||||
if(!boss.client && (!AB.req_statuses || (boss.AIStatus in AB.req_statuses)) && prob(AB.usage_probability) && AB.Trigger())
|
||||
break
|
||||
AB.UpdateButtonIcon(TRUE)
|
||||
AB.UpdateButtons(TRUE)
|
||||
|
||||
|
||||
/datum/boss_active_timed_battle/Destroy()
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/handle_automated_action()
|
||||
if(!..()) //AIStatus is off
|
||||
return 0
|
||||
return FALSE
|
||||
if(AIStatus == AI_IDLE)
|
||||
//1% chance to skitter madly away
|
||||
if(!busy && prob(1))
|
||||
@@ -255,7 +255,7 @@
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(C)
|
||||
spawn(100)
|
||||
@@ -336,7 +336,7 @@
|
||||
if(L.blood_volume && (L.stat != DEAD || !consumed_mobs[L.tag])) //if they're not dead, you can consume them anyway
|
||||
consumed_mobs[L.tag] = TRUE
|
||||
fed++
|
||||
lay_eggs.UpdateButtonIcon(TRUE)
|
||||
lay_eggs.UpdateButtons(TRUE)
|
||||
visible_message("<span class='danger'>[src] sticks a proboscis into [L] and sucks a viscous substance out.</span>","<span class='notice'>You suck the nutriment out of [L], feeding you enough to lay a cluster of eggs.</span>")
|
||||
L.death() //you just ate them, they're dead.
|
||||
else
|
||||
@@ -402,7 +402,7 @@
|
||||
|
||||
/obj/effect/proc_holder/wrap/update_icon()
|
||||
action.button_icon_state = "wrap_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
action.UpdateButtons()
|
||||
|
||||
/obj/effect/proc_holder/wrap/Trigger(mob/living/simple_animal/hostile/poison/giant_spider/nurse/user)
|
||||
if(!istype(user))
|
||||
@@ -418,7 +418,7 @@
|
||||
else
|
||||
message = "<span class='notice'>You prepare to wrap something in a cocoon. <B>Left-click your target to start wrapping!</B></span>"
|
||||
add_ranged_ability(user, message, TRUE)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/wrap/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
@@ -450,11 +450,11 @@
|
||||
/datum/action/innate/spider/lay_eggs/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return 0
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/S = owner
|
||||
if(S.fed)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/spider/lay_eggs/Activate()
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
@@ -482,7 +482,7 @@
|
||||
C.poison_per_bite = S.poison_per_bite
|
||||
C.faction = S.faction.Copy()
|
||||
S.fed--
|
||||
UpdateButtonIcon(TRUE)
|
||||
UpdateButtons(TRUE)
|
||||
S.busy = SPIDER_IDLE
|
||||
S.stop_automated_movement = FALSE
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/handle_automated_action()
|
||||
if(AIStatus == AI_OFF)
|
||||
return 0
|
||||
return FALSE
|
||||
var/list/possible_targets = ListTargets() //we look around for potential targets and make it a list for later use.
|
||||
|
||||
if(environment_smash)
|
||||
@@ -98,7 +98,7 @@
|
||||
if(!MoveToTarget(possible_targets)) //if we lose our target
|
||||
if(AIShouldSleep(possible_targets)) // we try to acquire a new one
|
||||
toggle_ai(AI_IDLE) // otherwise we go idle
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/handle_automated_movement()
|
||||
. = ..()
|
||||
@@ -273,7 +273,7 @@
|
||||
if(target != null)
|
||||
GainPatience()
|
||||
Aggro()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//What we do after closing in
|
||||
/mob/living/simple_animal/hostile/proc/MeleeAction(patience = TRUE)
|
||||
@@ -295,12 +295,12 @@
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return 0
|
||||
return FALSE
|
||||
if(target in possible_targets)
|
||||
var/turf/T = get_turf(src)
|
||||
if(target.z != T.z)
|
||||
LoseTarget()
|
||||
return 0
|
||||
return FALSE
|
||||
var/target_distance = get_dist(targets_from,target)
|
||||
if(ranged) //We ranged? Shoot at em
|
||||
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
|
||||
@@ -310,7 +310,7 @@
|
||||
return TRUE
|
||||
if(!Process_Spacemove()) //Drifting
|
||||
walk(src,0)
|
||||
return 1
|
||||
return TRUE
|
||||
if(retreat_distance != null) //If we have a retreat distance, check if we need to run from our target
|
||||
if(target_distance <= retreat_distance) //If target's closer than our retreat distance, run
|
||||
walk_away(src,target,retreat_distance,move_to_delay)
|
||||
@@ -325,8 +325,8 @@
|
||||
if(rapid_melee > 1 && target_distance <= melee_queue_distance)
|
||||
MeleeAction(FALSE)
|
||||
in_melee = FALSE //If we're just preparing to strike do not enter sidestep mode
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(environment_smash)
|
||||
if(target.loc != null && get_dist(targets_from, target.loc) <= vision_range) //We can't see our target, but he's in our vision range still
|
||||
if(ranged_ignores_vision && ranged_cooldown <= world.time) //we can't see our target... but we can fire at them!
|
||||
@@ -334,12 +334,12 @@
|
||||
if((environment_smash & ENVIRONMENT_SMASH_WALLS) || (environment_smash & ENVIRONMENT_SMASH_RWALLS)) //If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
FindHidden()
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
if(FindHidden())
|
||||
return 1
|
||||
return TRUE
|
||||
LoseTarget()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(target, delay, minimum_distance)
|
||||
if(target == src.target)
|
||||
@@ -530,7 +530,7 @@
|
||||
Goto(A,move_to_delay,minimum_distance)
|
||||
if(A.Adjacent(targets_from))
|
||||
A.attack_animal(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/RangedAttack(atom/A, params) //Player firing
|
||||
if(ranged && ranged_cooldown <= world.time)
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
return FALSE
|
||||
target = null //Target was our mecha, so null it out
|
||||
M.aimob_enter_mech(src)
|
||||
targets_from = M
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
mecha.aimob_exit_mech(src)
|
||||
allow_movement_on_non_turfs = FALSE
|
||||
@@ -280,7 +280,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/EscapeConfinement()
|
||||
if(mecha && loc == mecha)
|
||||
return 0
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ Difficulty: Hard
|
||||
if(is_enraged())
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons while enraged!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 300, 1)
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target, origin)
|
||||
|
||||
@@ -203,7 +203,7 @@ Difficulty: Medium
|
||||
if(!any_attack)
|
||||
for(var/obj/effect/temp_visual/drakewall/D in drakewalls)
|
||||
qdel(D)
|
||||
return 0 // nothing to attack in the arena time for enraged attack if we still have a target
|
||||
return FALSE // nothing to attack in the arena time for enraged attack if we still have a target
|
||||
for(var/turf/T in turfs)
|
||||
if(!(T in empty))
|
||||
new /obj/effect/temp_visual/lava_warning(T)
|
||||
@@ -211,7 +211,7 @@ Difficulty: Medium
|
||||
new /obj/effect/temp_visual/lava_safe(T)
|
||||
amount--
|
||||
sleep(24)
|
||||
return 1 // attack finished completely
|
||||
return TRUE // attack finished completely
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/arena_escape_enrage() // you ran somehow / teleported away from my arena attack now i'm mad fucker
|
||||
SetRecoveryTime(80)
|
||||
|
||||
@@ -143,8 +143,8 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/proc/CheckObject(obj/O)
|
||||
if((isitem(O) || isstructure(O)) && !is_type_in_list(O, GLOB.protected_objects))
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/user, destroy_original = 0)
|
||||
if(destroy_original || CheckObject(O))
|
||||
@@ -176,7 +176,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
faction += "[REF(creator)]" // very unique
|
||||
if(destroy_original)
|
||||
qdel(O)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
|
||||
if(destroy_objects)
|
||||
@@ -197,11 +197,11 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/machine/CanAttack(atom/the_target)
|
||||
if(the_target == creator) // Don't attack our creator AI.
|
||||
return 0
|
||||
return FALSE
|
||||
if(iscyborg(the_target))
|
||||
var/mob/living/silicon/robot/R = the_target
|
||||
if(R.connected_ai == creator) // Only attack robots that aren't synced to our creator AI.
|
||||
return 0
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ranged
|
||||
|
||||
@@ -72,19 +72,48 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
icon_icon = 'icons/mob/actions/actions_elites.dmi'
|
||||
button_icon_state = ""
|
||||
background_icon_state = "bg_default"
|
||||
var/mob/living/simple_animal/hostile/asteroid/elite/M
|
||||
var/chosen_message
|
||||
var/chosen_attack_num = 0
|
||||
|
||||
/datum/action/innate/elite_attack/CreateButton()
|
||||
var/atom/movable/screen/movable/action_button/button = ..()
|
||||
button.maptext = ""
|
||||
button.maptext_x = 8
|
||||
button.maptext_y = 0
|
||||
button.maptext_width = 24
|
||||
button.maptext_height = 12
|
||||
return button
|
||||
|
||||
/datum/action/innate/elite_attack/process()
|
||||
if(owner == null)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
qdel(src)
|
||||
return
|
||||
UpdateButtons()
|
||||
|
||||
/datum/action/innate/elite_attack/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(status_only)
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/asteroid/elite/elite_owner = owner
|
||||
var/timeleft = max(elite_owner.ranged_cooldown - world.time, 0)
|
||||
if(timeleft == 0)
|
||||
button.maptext = ""
|
||||
else
|
||||
button.maptext = "<b class='maptext'>[round(timeleft/10, 0.1)]</b>"
|
||||
|
||||
/datum/action/innate/elite_attack/Grant(mob/living/L)
|
||||
if(istype(L, /mob/living/simple_animal/hostile/asteroid/elite))
|
||||
M = L
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/elite_attack/Activate()
|
||||
M.chosen_attack = chosen_attack_num
|
||||
to_chat(M, chosen_message)
|
||||
var/mob/living/simple_animal/hostile/asteroid/elite/elite_owner = owner
|
||||
elite_owner.chosen_attack = chosen_attack_num
|
||||
to_chat(elite_owner, chosen_message)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/updatehealth()
|
||||
. = ..()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user