/mob/Destroy()//This makes sure that mobs with clients/keys are not just deleted from the game. mob_list -= src dead_mob_list -= src living_mob_list -= src qdel(hud_used) if(mind && mind.current == src) spellremove(src) for(var/infection in viruses) qdel(infection) for(var/cc in client_colours) qdel(cc) client_colours = null ghostize() return ..() var/next_mob_id = 0 /mob/New() tag = "mob_[next_mob_id++]" mob_list += src if(stat == DEAD) dead_mob_list += src else living_mob_list += src prepare_huds() ..() /atom/proc/prepare_huds() hud_list = list() for(var/hud in hud_possible) var/image/I = image('icons/mob/hud.dmi', src, "") I.appearance_flags = RESET_COLOR hud_list[hud] = I /mob/proc/Cell() set category = "Admin" set hidden = 1 if(!loc) return 0 var/datum/gas_mixture/environment = loc.return_air() var/t = "Coordinates: [x],[y] \n" t += "Temperature: [environment.temperature] \n" for(var/id in environment.gases) var/gas = environment.gases[id] if(gas[MOLES]) t+="[gas[GAS_META][META_GAS_NAME]]: [gas[MOLES]] \n" usr << t /mob/proc/show_message(msg, type, alt_msg, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) if(!client) return msg = copytext(msg, 1, MAX_MESSAGE_LEN) if(type) if(type & 1 && eye_blind )//Vision related if(!alt_msg) return else msg = alt_msg type = alt_type if(type & 2 && ear_deaf)//Hearing related if(!alt_msg) return else msg = alt_msg type = alt_type if(type & 1 && eye_blind) return // voice muffling if(stat == UNCONSCIOUS) if(type & 2) //audio src << "... You can almost hear something ..." else src << msg // Show a message the src mob and to all player mobs who sees the src mob // This would be for visible actions by the src mob // message is the message output to anyone who can see e.g. "[src] does something!" // self_message (optional) is what the src mob sees e.g. "You do something!" // blind_message (optional) is what blind people will hear e.g. "You hear something!" /mob/visible_message(message, self_message, blind_message) var/turf/T = get_turf(src) if(!T) return for(var/mob/M in get_hearers_in_view(7, src)) if(!M.client) continue var/msg = message if(M == src) //the src always see the main message or self message if(self_message) msg = self_message else if(M.see_invisibleYou are unable to equip that!" //Only print if qdel_on_fail is false return 0 equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail. return 1 //This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. //In most cases you will want to use equip_to_slot_if_possible() /mob/proc/equip_to_slot(obj/item/W, slot) return //This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. /mob/proc/equip_to_slot_or_del(obj/item/W, slot) equip_to_slot_if_possible(W, slot, 1, 1, 0) //puts the item "W" into an appropriate slot in a human's inventory //returns 0 if it cannot, 1 if successful /mob/proc/equip_to_appropriate_slot(obj/item/W) if(!istype(W)) return 0 for(var/slot in W.slot_equipment_priority) if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //qdel_on_fail = 0; disable_warning = 0; redraw_mob = 1 return 1 return 0 /mob/proc/reset_perspective(atom/A) if(client) if(istype(A, /atom/movable)) client.perspective = EYE_PERSPECTIVE client.eye = A else if(isturf(loc)) client.eye = client.mob client.perspective = MOB_PERSPECTIVE else client.perspective = EYE_PERSPECTIVE client.eye = loc return 1 /mob/living/reset_perspective(atom/A) if(..()) update_sight() if(client.eye != src) var/atom/AT = client.eye AT.get_remote_view_fullscreens(src) else clear_fullscreen("remote_view", 0) update_pipe_vision() /mob/proc/show_inv(mob/user) return //mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine() /mob/verb/examinate(atom/A as mob|obj|turf in view()) //It used to be oview(12), but I can't really say why set name = "Examine" set category = "IC" if(is_blind(src)) src << "Something is there but you can't see it." return face_atom(A) A.examine(src) //same as above //note: ghosts can point, this is intended //visible_message will handle invisibility properly //overriden here and in /mob/dead/observer for different point span classes and sanity checks /mob/verb/pointed(atom/A as mob|obj|turf in view()) set name = "Point To" set category = "Object" if(!src || !isturf(src.loc) || !(A in view(src.loc))) return 0 if(istype(A, /obj/effect/overlay/temp/point)) return 0 var/tile = get_turf(A) if (!tile) return 0 PoolOrNew(/obj/effect/overlay/temp/point, list(A,invisibility)) return 1 //this and stop_pulling really ought to be /mob/living procs /mob/proc/start_pulling(atom/movable/AM, supress_message = 0) if(!AM || !src) return if(AM == src || !isturf(AM.loc)) return if(AM.anchored || AM.throwing) return if(throwing || incapacitated()) return AM.add_fingerprint(src) // If we're pulling something then drop what we're currently pulling and pull this instead. if(pulling) // Are we trying to pull something we are already pulling? Then just stop here, no need to continue. if(AM == pulling) return stop_pulling() changeNext_move(CLICK_CD_GRABBING) if(AM.pulledby) visible_message("[src] has pulled [AM] from [AM.pulledby]'s grip.") AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. pulling = AM AM.pulledby = src playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) update_pull_hud_icon() if(ismob(AM)) var/mob/M = AM if(!supress_message) visible_message("[src] has grabbed [M] passively!") if(!iscarbon(src)) M.LAssailant = null else M.LAssailant = usr /mob/verb/stop_pulling() set name = "Stop Pulling" set category = "IC" if(pulling) pulling.pulledby = null if(ismob(pulling)) var/mob/M = pulling M.update_canmove()// mob gets up if it was lyng down in a chokehold pulling = null grab_state = 0 update_pull_hud_icon() /mob/proc/update_pull_hud_icon() if(hud_used) if(hud_used.pull_icon) hud_used.pull_icon.update_icon(src) /mob/verb/mode() set name = "Activate Held Object" set category = "Object" set src = usr if(istype(loc,/obj/mecha)) return if(incapacitated()) return if(hand) var/obj/item/W = l_hand if (W) W.attack_self(src) update_inv_l_hand() else var/obj/item/W = r_hand if (W) W.attack_self(src) update_inv_r_hand() /* /mob/verb/dump_source() var/master = "
"
	for(var/t in typesof(/area))
		master += text("[]\n", t)
		//Foreach goto(26)
	src << browse(master)
	return
*/

/mob/verb/memory()
	set name = "Notes"
	set category = "IC"
	if(mind)
		mind.show_memory(src)
	else
		src << "The game appears to have misplaced your mind datum, so we can't show you your notes."

/mob/verb/add_memory(msg as message)
	set name = "Add Note"
	set category = "IC"

	msg = copytext(msg, 1, MAX_MESSAGE_LEN)
	msg = sanitize(msg)

	if(mind)
		mind.store_memory(msg)
	else
		src << "The game appears to have misplaced your mind datum, so we can't show you your notes."

/mob/proc/store_memory(msg as message, popup, sane = 1)
	msg = copytext(msg, 1, MAX_MESSAGE_LEN)

	if (sane)
		msg = sanitize(msg)

	if (length(memory) == 0)
		memory += msg
	else
		memory += "
[msg]" if (popup) memory() /mob/verb/abandon_mob() set name = "Respawn" set category = "OOC" if (!( abandon_allowed )) return if ((stat != 2 || !( ticker ))) usr << "You must be dead to use this!" return log_game("[usr.name]/[usr.key] used abandon mob.") usr << "Please roleplay correctly!" if(!client) log_game("[usr.key] AM failed due to disconnect.") return client.screen.Cut() client.screen += client.void if(!client) log_game("[usr.key] AM failed due to disconnect.") return var/mob/new_player/M = new /mob/new_player() if(!client) log_game("[usr.key] AM failed due to disconnect.") qdel(M) return M.key = key // M.Login() //wat return /mob/verb/observe() set name = "Observe" set category = "OOC" var/is_admin = 0 if(check_rights_for(client,R_ADMIN)) is_admin = 1 else if(stat != DEAD || istype(src, /mob/new_player)) usr << "You must be observing to use this!" return if(is_admin && stat == DEAD) is_admin = 0 var/list/creatures = getpois() client.perspective = EYE_PERSPECTIVE var/eye_name = null var/ok = "[is_admin ? "Admin Observe" : "Observe"]" eye_name = input("Please, select a player!", ok, null, null) as null|anything in creatures if (!eye_name) return var/mob/mob_eye = creatures[eye_name] if(client && mob_eye) client.eye = mob_eye /mob/verb/cancel_camera() set name = "Cancel Camera View" set category = "OOC" reset_perspective(null) unset_machine() /mob/Topic(href, href_list) if(href_list["mach_close"]) var/t1 = text("window=[href_list["mach_close"]]") unset_machine() src << browse(null, t1) if(href_list["refresh"]) if(machine && in_range(src, usr)) show_inv(machine) if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) if(href_list["item"]) var/slot = text2num(href_list["item"]) var/obj/item/what = get_item_by_slot(slot) if(what) usr.stripPanelUnequip(what,src,slot) else usr.stripPanelEquip(what,src,slot) if(usr.machine == src) if(Adjacent(usr)) show_inv(usr) else usr << browse(null,"window=mob\ref[src]") // The src mob is trying to strip an item from someone // Defined in living.dm /mob/proc/stripPanelUnequip(obj/item/what, mob/who) return // The src mob is trying to place an item on someone // Defined in living.dm /mob/proc/stripPanelEquip(obj/item/what, mob/who) return /mob/MouseDrop(mob/M) ..() if(M != usr) return if(usr == src) return if(!Adjacent(usr)) return if(istype(M, /mob/living/silicon/ai)) return show_inv(usr) /mob/proc/is_active() return (0 >= usr.stat) /mob/proc/is_muzzled() return 0 /mob/proc/see(message) if(!is_active()) return 0 src << message return 1 /mob/proc/show_viewers(message) for(var/mob/M in viewers()) M.see(message) /mob/Stat() ..() if(statpanel("Status")) stat(null, "Map: [MAP_NAME]") if (nextmap && istype(nextmap)) stat(null, "Next Map: [nextmap.friendlyname]") stat(null, "Server Time: [time2text(world.realtime, "YYYY-MM-DD hh:mm")]") if(SSshuttle.emergency) var/ETA = SSshuttle.emergency.getModeStr() if(ETA) stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]") if(client && client.holder) if(statpanel("MC")) stat("Location:", "([x], [y], [z])") stat("CPU:", "[world.cpu]") stat("Instances:", "[world.contents.len]") config.stat_entry() stat(null) if(Master) Master.stat_entry() else stat("Master Controller:", "ERROR") if(Failsafe) Failsafe.stat_entry() else stat("Failsafe Controller:", "ERROR") if(Master) stat("Subsystems:", "[round(Master.subsystem_cost, 0.01)]ds") stat(null) for(var/datum/subsystem/SS in Master.subsystems) SS.stat_entry() cameranet.stat_entry() if(listed_turf && client) if(!TurfAdjacent(listed_turf)) listed_turf = null else statpanel(listed_turf.name, null, listed_turf) var/list/overrides = list() for(var/image/I in client.images) if(I.loc && I.loc.loc == listed_turf && I.override) overrides = I.loc for(var/atom/A in listed_turf) if(!A.mouse_opacity) continue if(A.invisibility > see_invisible) continue if(overrides.len && (A in overrides)) continue statpanel(listed_turf.name, null, A) if(mind) add_spells_to_statpanel(mind.spell_list) if(mind.changeling) add_stings_to_statpanel(mind.changeling.purchasedpowers) add_spells_to_statpanel(mob_spell_list) /mob/proc/add_spells_to_statpanel(list/spells) for(var/obj/effect/proc_holder/spell/S in spells) if(S.can_be_cast_by(src)) switch(S.charge_type) if("recharge") statpanel("[S.panel]","[S.charge_counter/10.0]/[S.charge_max/10]",S) if("charges") statpanel("[S.panel]","[S.charge_counter]/[S.charge_max]",S) if("holdervar") statpanel("[S.panel]","[S.holder_var_type] [S.holder_var_amount]",S) /mob/proc/add_stings_to_statpanel(list/stings) for(var/obj/effect/proc_holder/changeling/S in stings) if(S.chemical_cost >=0 && S.can_be_used_by(src)) statpanel("[S.panel]",((S.chemical_cost > 0) ? "[S.chemical_cost]" : ""),S) // facing verbs /mob/proc/canface() if(!canmove) return 0 if(client.moving) return 0 if(world.time < client.move_delay) return 0 if(stat==2) return 0 if(anchored) return 0 if(notransform) return 0 if(restrained()) return 0 return 1 //Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it. //Robots, animals and brains have their own version so don't worry about them /mob/proc/update_canmove() var/ko = weakened || paralysis || stat || (status_flags & FAKEDEATH) var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK var/buckle_lying = !(buckled && !buckled.buckle_lying) var/has_legs = get_num_legs() var/has_arms = get_num_arms() var/ignore_legs = get_leg_ignore() if(ko || resting || stunned || chokehold) drop_r_hand() drop_l_hand() unset_machine() if(pulling) stop_pulling() else if(has_legs || ignore_legs) lying = 0 if(buckled) lying = 90*buckle_lying else if(!lying) if(resting) fall() else if(ko || (!has_legs && !ignore_legs) || chokehold) fall(forced = 1) canmove = !(ko || resting || stunned || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) density = !lying if(lying) if(layer == initial(layer)) //to avoid special cases like hiding larvas. layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs else if(layer == LYING_MOB_LAYER) layer = initial(layer) update_transform() update_action_buttons_icon() lying_prev = lying return canmove /mob/proc/fall(forced) drop_l_hand() drop_r_hand() /mob/verb/eastface() set hidden = 1 if(!canface()) return 0 setDir(EAST) client.move_delay += movement_delay() return 1 /mob/verb/westface() set hidden = 1 if(!canface()) return 0 setDir(WEST) client.move_delay += movement_delay() return 1 /mob/verb/northface() set hidden = 1 if(!canface()) return 0 setDir(NORTH) client.move_delay += movement_delay() return 1 /mob/verb/southface() set hidden = 1 if(!canface()) return 0 setDir(SOUTH) client.move_delay += movement_delay() return 1 /mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check return 0 /mob/proc/swap_hand() return /mob/proc/activate_hand(selhand) return /mob/proc/assess_threat() //For sec bot threat assessment return /mob/proc/get_ghost(even_if_they_cant_reenter = 0) if(mind) return mind.get_ghost(even_if_they_cant_reenter) /mob/proc/grab_ghost(force) if(mind) return mind.grab_ghost(force = force) /mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null) var/mob/dead/observer/ghost = get_ghost() if(ghost) ghost.notify_cloning(message, sound, source) return ghost /mob/proc/AddSpell(obj/effect/proc_holder/spell/S) mob_spell_list += S S.action.Grant(src) //override to avoid rotating pixel_xy on mobs /mob/shuttleRotate(rotation) setDir(angle2dir(rotation+dir2angle(dir))) //You can buckle on mobs if you're next to them since most are dense /mob/buckle_mob(mob/living/M, force = 0) if(M.buckled) return 0 var/turf/T = get_turf(src) if(M.loc != T) var/old_density = density density = 0 var/can_step = step_towards(M, T) density = old_density if(!can_step) return 0 return ..() //Default buckling shift visual for mobs /mob/post_buckle_mob(mob/living/M) if(M in buckled_mobs)//post buckling var/height = M.get_mob_buckling_height(src) M.pixel_y = initial(M.pixel_y) + height if(M.layer < layer) M.layer = layer + 0.1 else //post unbuckling M.layer = initial(M.layer) M.pixel_y = initial(M.pixel_y) //returns the height in pixel the mob should have when buckled to another mob. /mob/proc/get_mob_buckling_height(mob/seat) if(isliving(seat)) var/mob/living/L = seat if(L.mob_size <= MOB_SIZE_SMALL) //being on top of a small mob doesn't put you very high. return 0 return 9 //can the mob be buckled to something by default? /mob/proc/can_buckle() return 1 //can the mob be unbuckled from something by default? /mob/proc/can_unbuckle() return 1 //Can the mob see reagents inside of containers? /mob/proc/can_see_reagents() if(stat == DEAD) //Ghosts and such can always see reagents return 1 if(has_unlimited_silicon_privilege) //Silicons can automatically view reagents return 1 if(ishuman(src)) var/mob/living/carbon/human/H = src if(H.head && istype(H.head, /obj/item/clothing)) var/obj/item/clothing/CL = H.head if(CL.scan_reagents) return 1 if(H.wear_mask && H.wear_mask.scan_reagents) return 1 if(H.glasses && istype(H.glasses, /obj/item/clothing)) var/obj/item/clothing/CL = H.glasses if(CL.scan_reagents) return 1 return 0 //Can the mob use Topic to interact with machines /mob/proc/canUseTopic() return /mob/proc/faction_check(mob/target) for(var/F in faction) if(F in target.faction) return 1 return 0 //This will update a mob's name, real_name, mind.name, data_core records, pda, id and traitor text //Calling this proc without an oldname will only update the mob and skip updating the pda, id and records ~Carn /mob/proc/fully_replace_character_name(oldname,newname) if(!newname) return 0 real_name = newname name = newname if(mind) mind.name = newname if(oldname) //update the datacore records! This is goig to be a bit costly. replace_records_name(oldname,newname) //update our pda and id if we have them on our person replace_identification_name(oldname,newname) for(var/datum/mind/T in ticker.minds) for(var/datum/objective/obj in T.objectives) // Only update if this player is a target if(obj.target && obj.target.current && obj.target.current.real_name == name) obj.update_explanation_text() return 1 //Updates data_core records with new name , see mob/living/carbon/human /mob/proc/replace_records_name(oldname,newname) return /mob/proc/replace_identification_name(oldname,newname) var/list/searching = GetAllContents() var/search_id = 1 var/search_pda = 1 for(var/A in searching) if( search_id && istype(A,/obj/item/weapon/card/id) ) var/obj/item/weapon/card/id/ID = A if(ID.registered_name == oldname) ID.registered_name = newname ID.update_label() if(!search_pda) break search_id = 0 else if( search_pda && istype(A,/obj/item/device/pda) ) var/obj/item/device/pda/PDA = A if(PDA.owner == oldname) PDA.owner = newname PDA.update_label() if(!search_id) break search_pda = 0 /mob/proc/update_stat() return /mob/proc/update_health_hud() return /mob/living/on_varedit(modified_var) switch(modified_var) if("weakened") SetWeakened(weakened) if("stunned") SetStunned(stunned) if("paralysis") SetParalysis(paralysis) if("sleeping") SetSleeping(sleeping) if("eye_blind") set_blindness(eye_blind) if("eye_damage") set_eye_damage(eye_damage) if("eye_blurry") set_blurriness(eye_blurry) if("ear_deaf") setEarDamage(-1, ear_deaf) if("ear_damage") setEarDamage(ear_damage, -1) if("maxHealth") updatehealth() if("resize") update_transform() ..() /mob/proc/is_literate() return 0 /mob/proc/get_idcard() return