April sync (#360)
* Maps and things no code/icons * helpers defines globalvars * Onclick world.dm orphaned_procs * subsystems Round vote and shuttle autocall done here too * datums * Game folder * Admin - chatter modules * clothing - mining * modular computers - zambies * client * mob level 1 * mob stage 2 + simple_animal * silicons n brains * mob stage 3 + Alien/Monkey * human mobs * icons updated * some sounds * emitter y u no commit * update tgstation.dme * compile fixes * travis fixes Also removes Fast digest mode, because reasons. * tweaks for travis Mentors are broke again Also fixes Sizeray guns * oxygen loss fix for vore code. * removes unused code * some code updates * bulk fixes * further fixes * outside things * whoops. * Maint bar ported * GLOBs.
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
/mob/dead/dust() //ghosts can't be vaporised.
|
||||
return
|
||||
|
||||
/mob/dead/gib() //ghosts can't be gibbed.
|
||||
return
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
..()
|
||||
|
||||
if(join_motd)
|
||||
to_chat(src, "<div class=\"motd\">[join_motd]</div>")
|
||||
if(GLOB.join_motd)
|
||||
to_chat(src, "<div class=\"motd\">[GLOB.join_motd]</div>")
|
||||
|
||||
if(admin_notice)
|
||||
to_chat(src, "<span class='notice'><b>Admin Notice:</b>\n \t [admin_notice]</span>")
|
||||
if(GLOB.admin_notice)
|
||||
to_chat(src, "<span class='notice'><b>Admin Notice:</b>\n \t [GLOB.admin_notice]</span>")
|
||||
|
||||
if(config.soft_popcap && living_player_count() >= config.soft_popcap)
|
||||
to_chat(src, "<span class='notice'><b>Server Notice:</b>\n \t [config.soft_popcap_message]</span>")
|
||||
@@ -28,5 +28,5 @@
|
||||
*/
|
||||
new_player_panel()
|
||||
client.playtitlemusic()
|
||||
if(ticker.current_state < GAME_STATE_SETTING_UP)
|
||||
to_chat(src, "Please set up your character and select \"Ready\". The game will start in about [round(ticker.GetTimeLeft(), 1)/10] seconds.")
|
||||
if(SSticker.current_state < GAME_STATE_SETTING_UP)
|
||||
to_chat(src, "Please set up your character and select \"Ready\". The game will start in about [round(SSticker.GetTimeLeft(), 1)/10] seconds.")
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
initialized = TRUE
|
||||
tag = "mob_[next_mob_id++]"
|
||||
mob_list += src
|
||||
GLOB.mob_list += src
|
||||
|
||||
if(client && ticker.state == GAME_STATE_STARTUP)
|
||||
if(client && SSticker.state == GAME_STATE_STARTUP)
|
||||
var/obj/screen/splash/S = new(client, TRUE, TRUE)
|
||||
S.Fade(TRUE)
|
||||
|
||||
if(length(newplayer_start))
|
||||
loc = pick(newplayer_start)
|
||||
if(length(GLOB.newplayer_start))
|
||||
loc = pick(GLOB.newplayer_start)
|
||||
else
|
||||
loc = locate(1,1,1)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
var/output = "<center><p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
|
||||
|
||||
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
|
||||
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME)
|
||||
if(ready)
|
||||
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
|
||||
else
|
||||
@@ -48,11 +48,11 @@
|
||||
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
|
||||
|
||||
if(!IsGuestKey(src.key))
|
||||
if (dbcon.Connect())
|
||||
if (GLOB.dbcon.Connect())
|
||||
var/isadmin = 0
|
||||
if(src.client && src.client.holder)
|
||||
isadmin = 1
|
||||
var/DBQuery/query_get_new_polls = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
|
||||
var/DBQuery/query_get_new_polls = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
|
||||
if(!query_get_new_polls.Execute())
|
||||
return
|
||||
var/newpoll = 0
|
||||
@@ -77,18 +77,18 @@
|
||||
..()
|
||||
|
||||
if(statpanel("Lobby"))
|
||||
stat("Game Mode:", (ticker.hide_mode) ? "Secret" : "[master_mode]")
|
||||
stat("Game Mode:", (SSticker.hide_mode) ? "Secret" : "[GLOB.master_mode]")
|
||||
stat("Map:", SSmapping.config.map_name)
|
||||
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
var/time_remaining = ticker.GetTimeLeft()
|
||||
if(SSticker.current_state == GAME_STATE_PREGAME)
|
||||
var/time_remaining = SSticker.GetTimeLeft()
|
||||
if(time_remaining >= 0)
|
||||
time_remaining /= 10
|
||||
stat("Time To Start:", (time_remaining >= 0) ? "[round(time_remaining)]s" : "DELAYED")
|
||||
|
||||
stat("Players:", "[ticker.totalPlayers]")
|
||||
stat("Players:", "[SSticker.totalPlayers]")
|
||||
if(client.holder)
|
||||
stat("Players Ready:", "[ticker.totalPlayersReady]")
|
||||
stat("Players Ready:", "[SSticker.totalPlayersReady]")
|
||||
|
||||
|
||||
/mob/dead/new_player/Topic(href, href_list[])
|
||||
@@ -110,7 +110,7 @@
|
||||
return 1
|
||||
|
||||
if(href_list["ready"])
|
||||
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
|
||||
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
|
||||
ready = text2num(href_list["ready"])
|
||||
|
||||
if(href_list["refresh"])
|
||||
@@ -141,14 +141,14 @@
|
||||
observer.real_name = observer.client.prefs.real_name
|
||||
observer.name = observer.real_name
|
||||
observer.update_icon()
|
||||
observer.stopLobbySound()
|
||||
observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
qdel(mind)
|
||||
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
if(href_list["late_join"])
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
if(!SSticker || SSticker.current_state != GAME_STATE_PLAYING)
|
||||
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
|
||||
return
|
||||
|
||||
@@ -156,17 +156,17 @@
|
||||
LateChoices()
|
||||
return
|
||||
|
||||
if(ticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in admin_datums)))
|
||||
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
|
||||
to_chat(usr, "<span class='danger'>[config.hard_popcap_message]</span>")
|
||||
|
||||
var/queue_position = ticker.queued_players.Find(usr)
|
||||
var/queue_position = SSticker.queued_players.Find(usr)
|
||||
if(queue_position == 1)
|
||||
to_chat(usr, "<span class='notice'>You are next in line to join the game. You will be notified when a slot opens up.</span>")
|
||||
else if(queue_position)
|
||||
to_chat(usr, "<span class='notice'>There are [queue_position-1] players in front of you in the queue to join the game.</span>")
|
||||
else
|
||||
ticker.queued_players += usr
|
||||
to_chat(usr, "<span class='notice'>You have been added to the queue to join the game. Your position in queue is [ticker.queued_players.len].</span>")
|
||||
SSticker.queued_players += usr
|
||||
to_chat(usr, "<span class='notice'>You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].</span>")
|
||||
return
|
||||
LateChoices()
|
||||
|
||||
@@ -175,12 +175,12 @@
|
||||
|
||||
if(href_list["SelectedJob"])
|
||||
|
||||
if(!enter_allowed)
|
||||
if(!GLOB.enter_allowed)
|
||||
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
|
||||
return
|
||||
|
||||
if(ticker.queued_players.len && !(ckey(key) in admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != ticker.queued_players[1]))
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, "<span class='warning'>Server is full.</span>")
|
||||
return
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
alert(src, "[rank] is not available. Please try another.")
|
||||
return 0
|
||||
|
||||
if(ticker.late_join_disabled)
|
||||
if(SSticker.late_join_disabled)
|
||||
alert(src, "An administrator has disabled late join spawning.")
|
||||
return FALSE
|
||||
|
||||
@@ -314,8 +314,8 @@
|
||||
return FALSE
|
||||
|
||||
//Remove the player from the join queue if he was in one and reset the timer
|
||||
ticker.queued_players -= src
|
||||
ticker.queue_delay = 4
|
||||
SSticker.queued_players -= src
|
||||
SSticker.queue_delay = 4
|
||||
|
||||
SSjob.AssignRole(src, rank, 1)
|
||||
|
||||
@@ -325,8 +325,8 @@
|
||||
character = equip
|
||||
|
||||
var/D
|
||||
if(latejoin.len)
|
||||
D = get_turf(pick(latejoin))
|
||||
if(GLOB.latejoin.len)
|
||||
D = get_turf(pick(GLOB.latejoin))
|
||||
if(!D)
|
||||
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
|
||||
if(!T.density)
|
||||
@@ -346,46 +346,46 @@
|
||||
if(chair)
|
||||
chair.buckle_mob(character)
|
||||
|
||||
ticker.minds += character.mind
|
||||
SSticker.minds += character.mind
|
||||
|
||||
var/mob/living/carbon/human/humanc
|
||||
if(ishuman(character))
|
||||
humanc = character //Let's retypecast the var to be human,
|
||||
|
||||
if(humanc) //These procs all expect humans
|
||||
data_core.manifest_inject(humanc)
|
||||
GLOB.data_core.manifest_inject(humanc)
|
||||
if(SSshuttle.arrivals)
|
||||
SSshuttle.arrivals.QueueAnnounce(humanc, rank)
|
||||
else
|
||||
AnnounceArrival(humanc, rank)
|
||||
AddEmploymentContract(humanc)
|
||||
if(highlander)
|
||||
if(GLOB.highlander)
|
||||
to_chat(humanc, "<span class='userdanger'><i>THERE CAN BE ONLY ONE!!!</i></span>")
|
||||
humanc.make_scottish()
|
||||
|
||||
joined_player_list += character.ckey
|
||||
GLOB.joined_player_list += character.ckey
|
||||
|
||||
if(config.allow_latejoin_antagonists && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
|
||||
if(SSshuttle.emergency)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_RECALL, SHUTTLE_IDLE)
|
||||
ticker.mode.make_antag_chance(humanc)
|
||||
SSticker.mode.make_antag_chance(humanc)
|
||||
if(SHUTTLE_CALL)
|
||||
if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
|
||||
ticker.mode.make_antag_chance(humanc)
|
||||
SSticker.mode.make_antag_chance(humanc)
|
||||
qdel(src)
|
||||
|
||||
/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
|
||||
//TODO: figure out a way to exclude wizards/nukeops/demons from this.
|
||||
sleep(30)
|
||||
for(var/C in employmentCabinets)
|
||||
for(var/C in GLOB.employmentCabinets)
|
||||
var/obj/structure/filingcabinet/employment/employmentCabinet = C
|
||||
if(!employmentCabinet.virgin)
|
||||
employmentCabinet.addFile(employee)
|
||||
|
||||
|
||||
/mob/dead/new_player/proc/LateChoices()
|
||||
var/mills = world.time - round_start_time // 1/10 of a second, not real milliseconds but whatever
|
||||
var/mills = world.time - SSticker.round_start_time // 1/10 of a second, not real milliseconds but whatever
|
||||
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
|
||||
var/mins = (mills % 36000) / 600
|
||||
var/hours = mills / 36000
|
||||
@@ -425,7 +425,7 @@
|
||||
if (job_count > round(available_job_count / 2))
|
||||
dat += "</div><div class='jobsColumn'>"
|
||||
var/position_class = "otherPosition"
|
||||
if (job.title in command_positions)
|
||||
if (job.title in GLOB.command_positions)
|
||||
position_class = "commandPosition"
|
||||
dat += "<a class='[position_class]' href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions])</a><br>"
|
||||
if(!job_count) //if there's nowhere to go, assistant opens up.
|
||||
@@ -471,12 +471,12 @@
|
||||
. = new_character
|
||||
if(.)
|
||||
new_character.key = key //Manually transfer the key to log them in
|
||||
new_character.stopLobbySound()
|
||||
new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
|
||||
/mob/dead/new_player/proc/ViewManifest()
|
||||
var/dat = "<html><body>"
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += data_core.get_manifest(OOC = 1)
|
||||
dat += GLOB.data_core.get_manifest(OOC = 1)
|
||||
|
||||
src << browse(dat, "window=manifest;size=387x420;can_close=1")
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
var/optiontext
|
||||
|
||||
/mob/dead/new_player/proc/handle_player_polling()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!GLOB.dbcon.IsConnected())
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/DBQuery/query_poll_get = dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE Now() BETWEEN starttime AND endtime [(client.holder ? "" : "AND adminonly = false")]")
|
||||
var/DBQuery/query_poll_get = GLOB.dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE Now() BETWEEN starttime AND endtime [(client.holder ? "" : "AND adminonly = false")]")
|
||||
if(!query_poll_get.warn_execute())
|
||||
return
|
||||
var/output = "<div align='center'><B>Player polls</B><hr><table>"
|
||||
@@ -22,10 +22,10 @@
|
||||
/mob/dead/new_player/proc/poll_player(pollid)
|
||||
if(!pollid)
|
||||
return
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/DBQuery/query_poll_get_details = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
|
||||
var/DBQuery/query_poll_get_details = GLOB.dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
|
||||
if(!query_poll_get_details.warn_execute())
|
||||
return
|
||||
var/pollstarttime = ""
|
||||
@@ -41,14 +41,14 @@
|
||||
multiplechoiceoptions = text2num(query_poll_get_details.item[5])
|
||||
switch(polltype)
|
||||
if(POLLTYPE_OPTION)
|
||||
var/DBQuery/query_option_get_votes = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_option_get_votes = GLOB.dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_option_get_votes.warn_execute())
|
||||
return
|
||||
var/votedoptionid = 0
|
||||
if(query_option_get_votes.NextRow())
|
||||
votedoptionid = text2num(query_option_get_votes.item[1])
|
||||
var/list/datum/polloption/options = list()
|
||||
var/DBQuery/query_option_options = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
var/DBQuery/query_option_options = GLOB.dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
if(!query_option_options.warn_execute())
|
||||
return
|
||||
while(query_option_options.NextRow())
|
||||
@@ -82,7 +82,7 @@
|
||||
src << browse(null ,"window=playerpolllist")
|
||||
src << browse(output,"window=playerpoll;size=500x250")
|
||||
if(POLLTYPE_TEXT)
|
||||
var/DBQuery/query_text_get_votes = dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_text_get_votes = GLOB.dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_text_get_votes.warn_execute())
|
||||
return
|
||||
var/vote_text = ""
|
||||
@@ -111,7 +111,7 @@
|
||||
src << browse(null ,"window=playerpolllist")
|
||||
src << browse(output,"window=playerpoll;size=500x500")
|
||||
if(POLLTYPE_RATING)
|
||||
var/DBQuery/query_rating_get_votes = dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, [format_table_name("poll_vote")] v WHERE o.pollid = [pollid] AND v.ckey = '[ckey]' AND o.id = v.optionid")
|
||||
var/DBQuery/query_rating_get_votes = GLOB.dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, [format_table_name("poll_vote")] v WHERE o.pollid = [pollid] AND v.ckey = '[ckey]' AND o.id = v.optionid")
|
||||
if(!query_rating_get_votes.warn_execute())
|
||||
return
|
||||
var/output = "<div align='center'><B>Player poll</B><hr>"
|
||||
@@ -129,7 +129,7 @@
|
||||
output += "<input type='hidden' name='votetype' value=[POLLTYPE_RATING]>"
|
||||
var/minid = 999999
|
||||
var/maxid = 0
|
||||
var/DBQuery/query_rating_options = dbcon.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
var/DBQuery/query_rating_options = GLOB.dbcon.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
if(!query_rating_options.warn_execute())
|
||||
return
|
||||
while(query_rating_options.NextRow())
|
||||
@@ -163,7 +163,7 @@
|
||||
src << browse(null ,"window=playerpolllist")
|
||||
src << browse(output,"window=playerpoll;size=500x500")
|
||||
if(POLLTYPE_MULTI)
|
||||
var/DBQuery/query_multi_get_votes = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_multi_get_votes = GLOB.dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_multi_get_votes.warn_execute())
|
||||
return
|
||||
var/list/votedfor = list()
|
||||
@@ -172,7 +172,7 @@
|
||||
var/list/datum/polloption/options = list()
|
||||
var/maxoptionid = 0
|
||||
var/minoptionid = 0
|
||||
var/DBQuery/query_multi_options = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
var/DBQuery/query_multi_options = GLOB.dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
if(!query_multi_options.warn_execute())
|
||||
return
|
||||
while(query_multi_options.NextRow())
|
||||
@@ -214,7 +214,7 @@
|
||||
var/datum/asset/irv_assets = get_asset_datum(/datum/asset/simple/IRV)
|
||||
irv_assets.send(src)
|
||||
|
||||
var/DBQuery/query_irv_get_votes = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_irv_get_votes = GLOB.dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_irv_get_votes.warn_execute())
|
||||
return
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
var/list/datum/polloption/options = list()
|
||||
|
||||
var/DBQuery/query_irv_options = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
var/DBQuery/query_irv_options = GLOB.dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
if(!query_irv_options.warn_execute())
|
||||
return
|
||||
while(query_irv_options.NextRow())
|
||||
@@ -327,10 +327,10 @@
|
||||
var/table = "poll_vote"
|
||||
if (text)
|
||||
table = "poll_textreply"
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/DBQuery/query_hasvoted = dbcon.NewQuery("SELECT id FROM `[format_table_name(table)]` WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_hasvoted = GLOB.dbcon.NewQuery("SELECT id FROM `[format_table_name(table)]` WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_hasvoted.warn_execute())
|
||||
return
|
||||
if(query_hasvoted.NextRow())
|
||||
@@ -355,14 +355,14 @@
|
||||
return 1
|
||||
|
||||
/mob/dead/new_player/proc/vote_valid_check(pollid, holder, type)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
pollid = text2num(pollid)
|
||||
if (!pollid || pollid < 0)
|
||||
return 0
|
||||
//validate the poll is actually the right type of poll and its still active
|
||||
var/DBQuery/query_validate_poll = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime AND polltype = '[type]' [(holder ? "" : "AND adminonly = false")]")
|
||||
var/DBQuery/query_validate_poll = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime AND polltype = '[type]' [(holder ? "" : "AND adminonly = false")]")
|
||||
if(!query_validate_poll.warn_execute())
|
||||
return 0
|
||||
if (!query_validate_poll.NextRow())
|
||||
@@ -370,7 +370,7 @@
|
||||
return 1
|
||||
|
||||
/mob/dead/new_player/proc/vote_on_irv_poll(pollid, list/votelist)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
if (!vote_rig_check())
|
||||
@@ -395,7 +395,7 @@
|
||||
return 0
|
||||
|
||||
//lets collect the options
|
||||
var/DBQuery/query_irv_id = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
var/DBQuery/query_irv_id = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
|
||||
if(!query_irv_id.warn_execute())
|
||||
return 0
|
||||
var/list/optionlist = list()
|
||||
@@ -426,12 +426,12 @@
|
||||
sqlrowlist += "(Now(), [pollid], [vote], '[sanitizeSQL(ckey)]', INET_ATON('[sanitizeSQL(address)]'), '[sanitizeSQL(rank)]')"
|
||||
|
||||
//now lets delete their old votes (if any)
|
||||
var/DBQuery/query_irv_del_old = dbcon.NewQuery("DELETE FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_irv_del_old = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_irv_del_old.warn_execute())
|
||||
return 0
|
||||
|
||||
//now to add the new ones.
|
||||
var/DBQuery/query_irv_vote = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES [sqlrowlist]")
|
||||
var/DBQuery/query_irv_vote = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES [sqlrowlist]")
|
||||
if(!query_irv_vote.warn_execute())
|
||||
return 0
|
||||
src << browse(null,"window=playerpoll")
|
||||
@@ -439,7 +439,7 @@
|
||||
|
||||
|
||||
/mob/dead/new_player/proc/vote_on_poll(pollid, optionid)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
if (!vote_rig_check())
|
||||
@@ -452,14 +452,14 @@
|
||||
var/adminrank = sanitizeSQL(poll_check_voted(pollid))
|
||||
if(!adminrank)
|
||||
return
|
||||
var/DBQuery/query_option_vote = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]')")
|
||||
var/DBQuery/query_option_vote = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]')")
|
||||
if(!query_option_vote.warn_execute())
|
||||
return
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
|
||||
/mob/dead/new_player/proc/log_text_poll_reply(pollid, replytext)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
if (!vote_rig_check())
|
||||
@@ -479,14 +479,14 @@
|
||||
if(!(length(replytext) > 0) || !(length(replytext) <= 8000))
|
||||
to_chat(usr, "The text you entered was invalid or too long. Please correct the text and submit again.")
|
||||
return
|
||||
var/DBQuery/query_text_vote = dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (Now(), [pollid], '[ckey]', INET_ATON('[client.address]'), '[replytext]', '[adminrank]')")
|
||||
var/DBQuery/query_text_vote = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (Now(), [pollid], '[ckey]', INET_ATON('[client.address]'), '[replytext]', '[adminrank]')")
|
||||
if(!query_text_vote.warn_execute())
|
||||
return
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
|
||||
/mob/dead/new_player/proc/vote_on_numval_poll(pollid, optionid, rating)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
if (!vote_rig_check())
|
||||
@@ -496,7 +496,7 @@
|
||||
//validate the poll
|
||||
if (!vote_valid_check(pollid, client.holder, POLLTYPE_RATING))
|
||||
return 0
|
||||
var/DBQuery/query_numval_hasvoted = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_numval_hasvoted = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[ckey]'")
|
||||
if(!query_numval_hasvoted.warn_execute())
|
||||
return
|
||||
if(query_numval_hasvoted.NextRow())
|
||||
@@ -506,14 +506,14 @@
|
||||
if(client.holder)
|
||||
adminrank = client.holder.rank.name
|
||||
adminrank = sanitizeSQL(adminrank)
|
||||
var/DBQuery/query_numval_vote = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]', [(isnull(rating)) ? "null" : rating])")
|
||||
var/DBQuery/query_numval_vote = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]', [(isnull(rating)) ? "null" : rating])")
|
||||
if(!query_numval_vote.warn_execute())
|
||||
return
|
||||
usr << browse(null,"window=playerpoll")
|
||||
return 1
|
||||
|
||||
/mob/dead/new_player/proc/vote_on_multi_poll(pollid, optionid)
|
||||
if (!dbcon.Connect())
|
||||
if (!GLOB.dbcon.Connect())
|
||||
to_chat(src, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return 0
|
||||
if (!vote_rig_check())
|
||||
@@ -523,13 +523,13 @@
|
||||
//validate the poll
|
||||
if (!vote_valid_check(pollid, client.holder, POLLTYPE_MULTI))
|
||||
return 0
|
||||
var/DBQuery/query_multi_choicelen = dbcon.NewQuery("SELECT multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
|
||||
var/DBQuery/query_multi_choicelen = GLOB.dbcon.NewQuery("SELECT multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
|
||||
if(!query_multi_choicelen.warn_execute())
|
||||
return 1
|
||||
var/i
|
||||
if(query_multi_choicelen.NextRow())
|
||||
i = text2num(query_multi_choicelen.item[1])
|
||||
var/DBQuery/query_multi_hasvoted = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
var/DBQuery/query_multi_hasvoted = GLOB.dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
|
||||
if(!query_multi_hasvoted.warn_execute())
|
||||
return 1
|
||||
while(i)
|
||||
@@ -543,7 +543,7 @@
|
||||
if(client.holder)
|
||||
adminrank = client.holder.rank.name
|
||||
adminrank = sanitizeSQL(adminrank)
|
||||
var/DBQuery/query_multi_vote = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]')")
|
||||
var/DBQuery/query_multi_vote = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES (Now(), [pollid], [optionid], '[ckey]', INET_ATON('[client.address]'), '[adminrank]')")
|
||||
if(!query_multi_vote.warn_execute())
|
||||
return 1
|
||||
usr << browse(null,"window=playerpoll")
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// Silicons only need a very basic preview since there is no customization for them.
|
||||
if(job_engsec_high)
|
||||
switch(job_engsec_high)
|
||||
if(AI)
|
||||
if(AI_JF)
|
||||
preview_icon = icon('icons/mob/AI.dmi', "AI", SOUTH)
|
||||
preview_icon.Scale(64, 64)
|
||||
return
|
||||
|
||||
@@ -812,7 +812,7 @@
|
||||
gender = FEMALE
|
||||
|
||||
/datum/sprite_accessory/undershirt/lover
|
||||
name = "Lover shirt"
|
||||
name = "Lover Shirt"
|
||||
icon_state = "lover"
|
||||
gender = NEUTER
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/mob/dead/observer/Logout()
|
||||
if (client)
|
||||
client.images -= ghost_darkness_images
|
||||
client.images -= (GLOB.ghost_images_default+GLOB.ghost_images_simple)
|
||||
|
||||
if(observetarget)
|
||||
if(ismob(observetarget))
|
||||
var/mob/target = observetarget
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
var/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness, BUT NOT THE GHOSTS THEMSELVES!
|
||||
var/list/image/ghost_images_full = list() //this is a list of full images of the ghosts themselves
|
||||
var/list/image/ghost_images_default = list() //this is a list of the default (non-accessorized, non-dir) images of the ghosts themselves
|
||||
var/list/image/ghost_images_simple = list() //this is a list of all ghost images as the simple white ghost
|
||||
GLOBAL_LIST_EMPTY(ghost_images_default) //this is a list of the default (non-accessorized, non-dir) images of the ghosts themselves
|
||||
GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as the simple white ghost
|
||||
|
||||
var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
|
||||
/mob/dead/observer
|
||||
name = "ghost"
|
||||
@@ -19,8 +17,6 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_in_dark = 100
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
var/can_reenter_corpse
|
||||
var/datum/hud/living/carbon/hud = null // hud
|
||||
var/bootime = 0
|
||||
@@ -29,11 +25,9 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
|
||||
var/atom/movable/following = null
|
||||
var/fun_verbs = 0
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/image/ghostimage_default = null //this mobs ghost image without accessories and dirs
|
||||
var/image/ghostimage_simple = null //this mob with the simple white ghost sprite
|
||||
var/ghostvision = 1 //is the ghost able to see things humans can't?
|
||||
var/seedarkness = 1
|
||||
var/mob/observetarget = null //The target mob that the ghost is observing. Used as a reference in logout()
|
||||
var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD?
|
||||
var/data_huds_on = 0 //Are data HUDs currently enabled?
|
||||
@@ -60,22 +54,24 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
var/deadchat_name
|
||||
|
||||
/mob/dead/observer/Initialize()
|
||||
invisibility = observer_default_invisibility
|
||||
invisibility = GLOB.observer_default_invisibility
|
||||
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
if(config.cross_allowed)
|
||||
verbs += /mob/dead/observer/proc/server_hop
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
if(icon_state in ghost_forms_with_directions_list)
|
||||
if(icon_state in GLOB.ghost_forms_with_directions_list)
|
||||
ghostimage_default = image(src.icon,src,src.icon_state + "_nodir")
|
||||
else
|
||||
ghostimage_default = image(src.icon,src,src.icon_state)
|
||||
ghostimage_default.override = TRUE
|
||||
GLOB.ghost_images_default |= ghostimage_default
|
||||
|
||||
ghostimage_simple = image(src.icon,src,"ghost_nodir")
|
||||
ghost_images_full |= ghostimage
|
||||
ghost_images_default |= ghostimage_default
|
||||
ghost_images_simple |= ghostimage_simple
|
||||
ghostimage_simple.override = TRUE
|
||||
GLOB.ghost_images_simple |= ghostimage_simple
|
||||
|
||||
updateallghostimages()
|
||||
|
||||
var/turf/T
|
||||
@@ -123,6 +119,8 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
verbs -= /mob/dead/observer/verb/possess
|
||||
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
grant_all_languages()
|
||||
..()
|
||||
|
||||
/mob/dead/observer/narsie_act()
|
||||
@@ -137,16 +135,11 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
animate(src, color = old_color, time = 10)
|
||||
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 10)
|
||||
|
||||
/mob/dead/observer/Destroy()
|
||||
ghost_images_full -= ghostimage
|
||||
qdel(ghostimage)
|
||||
ghostimage = null
|
||||
|
||||
ghost_images_default -= ghostimage_default
|
||||
GLOB.ghost_images_default -= ghostimage_default
|
||||
qdel(ghostimage_default)
|
||||
ghostimage_default = null
|
||||
|
||||
ghost_images_simple -= ghostimage_simple
|
||||
GLOB.ghost_images_simple -= ghostimage_simple
|
||||
qdel(ghostimage_simple)
|
||||
ghostimage_simple = null
|
||||
|
||||
@@ -170,49 +163,44 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
|
||||
if(hair_image)
|
||||
cut_overlay(hair_image)
|
||||
ghostimage.add_overlay(hair_image)
|
||||
hair_image = null
|
||||
|
||||
if(facial_hair_image)
|
||||
cut_overlay(facial_hair_image)
|
||||
ghostimage.add_overlay(facial_hair_image)
|
||||
facial_hair_image = null
|
||||
|
||||
|
||||
if(new_form)
|
||||
icon_state = new_form
|
||||
ghostimage.icon_state = new_form
|
||||
if(icon_state in ghost_forms_with_directions_list)
|
||||
if(icon_state in GLOB.ghost_forms_with_directions_list)
|
||||
ghostimage_default.icon_state = new_form + "_nodir" //if this icon has dirs, the default ghostimage must use its nodir version or clients with the preference set to default sprites only will see the dirs
|
||||
else
|
||||
ghostimage_default.icon_state = new_form
|
||||
|
||||
if(ghost_accs >= GHOST_ACCS_DIR && icon_state in ghost_forms_with_directions_list) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
|
||||
if(ghost_accs >= GHOST_ACCS_DIR && icon_state in GLOB.ghost_forms_with_directions_list) //if this icon has dirs AND the client wants to show them, we make sure we update the dir on movement
|
||||
updatedir = 1
|
||||
else
|
||||
updatedir = 0 //stop updating the dir in case we want to show accessories with dirs on a ghost sprite without dirs
|
||||
setDir(2 )//reset the dir to its default so the sprites all properly align up
|
||||
|
||||
if(ghost_accs == GHOST_ACCS_FULL && icon_state in ghost_forms_with_accessories_list) //check if this form supports accessories and if the client wants to show them
|
||||
if(ghost_accs == GHOST_ACCS_FULL && icon_state in GLOB.ghost_forms_with_accessories_list) //check if this form supports accessories and if the client wants to show them
|
||||
var/datum/sprite_accessory/S
|
||||
if(facial_hair_style)
|
||||
S = facial_hair_styles_list[facial_hair_style]
|
||||
S = GLOB.facial_hair_styles_list[facial_hair_style]
|
||||
if(S)
|
||||
facial_hair_image = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER)
|
||||
if(facial_hair_color)
|
||||
facial_hair_image.color = "#" + facial_hair_color
|
||||
facial_hair_image.alpha = 200
|
||||
add_overlay(facial_hair_image)
|
||||
ghostimage.add_overlay(facial_hair_image)
|
||||
if(hair_style)
|
||||
S = hair_styles_list[hair_style]
|
||||
S = GLOB.hair_styles_list[hair_style]
|
||||
if(S)
|
||||
hair_image = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER)
|
||||
if(hair_color)
|
||||
hair_image.color = "#" + hair_color
|
||||
hair_image.alpha = 200
|
||||
add_overlay(hair_image)
|
||||
ghostimage.add_overlay(hair_image)
|
||||
|
||||
/*
|
||||
* Increase the brightness of a color by calculating the average distance between the R, G and B values,
|
||||
@@ -310,14 +298,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(ticker && ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(SSticker && SSticker.mode)
|
||||
for(var/datum/gang/G in SSticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = ticker.mode
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||
stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/dead/observer/verb/reenter_corpse()
|
||||
set category = "Ghost"
|
||||
@@ -368,7 +356,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "Not when you're not dead!")
|
||||
return
|
||||
var/A
|
||||
A = input("Area to jump to", "BOOYEA", A) as null|anything in sortedAreas
|
||||
A = input("Area to jump to", "BOOYEA", A) as null|anything in GLOB.sortedAreas
|
||||
var/area/thearea = A
|
||||
if(!thearea)
|
||||
return
|
||||
@@ -510,35 +498,42 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
|
||||
set category = "Ghost"
|
||||
ghostvision = !(ghostvision)
|
||||
updateghostsight()
|
||||
update_sight()
|
||||
to_chat(usr, "You [(ghostvision?"now":"no longer")] have ghost vision.")
|
||||
|
||||
/mob/dead/observer/verb/toggle_darkness()
|
||||
set name = "Toggle Darkness"
|
||||
set category = "Ghost"
|
||||
seedarkness = !(seedarkness)
|
||||
updateghostsight()
|
||||
switch(lighting_alpha)
|
||||
if (LIGHTING_PLANE_ALPHA_VISIBLE)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
|
||||
else
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
||||
|
||||
/mob/dead/observer/proc/updateghostsight()
|
||||
update_sight()
|
||||
|
||||
/mob/dead/observer/update_sight()
|
||||
if(client)
|
||||
ghost_others = client.prefs.ghost_others //A quick update just in case this setting was changed right before calling the proc
|
||||
|
||||
if (seedarkness)
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
if (!ghostvision || ghost_others <= GHOST_OTHERS_DEFAULT_SPRITE)
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
if (!ghostvision)
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_NOLIGHTING
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
|
||||
|
||||
updateghostimages()
|
||||
..()
|
||||
|
||||
/proc/updateallghostimages()
|
||||
listclearnulls(ghost_images_full)
|
||||
listclearnulls(ghost_images_default)
|
||||
listclearnulls(ghost_images_simple)
|
||||
listclearnulls(ghost_darkness_images)
|
||||
listclearnulls(GLOB.ghost_images_default)
|
||||
listclearnulls(GLOB.ghost_images_simple)
|
||||
|
||||
for (var/mob/dead/observer/O in player_list)
|
||||
for (var/mob/dead/observer/O in GLOB.player_list)
|
||||
O.updateghostimages()
|
||||
|
||||
/mob/dead/observer/proc/updateghostimages()
|
||||
@@ -547,34 +542,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
if(lastsetting)
|
||||
switch(lastsetting) //checks the setting we last came from, for a little efficiency so we don't try to delete images from the client that it doesn't have anyway
|
||||
if(GHOST_OTHERS_THEIR_SETTING)
|
||||
client.images -= ghost_images_full
|
||||
if(GHOST_OTHERS_DEFAULT_SPRITE)
|
||||
client.images -= ghost_images_default
|
||||
client.images -= GLOB.ghost_images_default
|
||||
if(GHOST_OTHERS_SIMPLE)
|
||||
client.images -= ghost_images_simple
|
||||
|
||||
if ((seedarkness || !ghostvision) && client.prefs.ghost_others == GHOST_OTHERS_THEIR_SETTING)
|
||||
client.images -= ghost_darkness_images
|
||||
lastsetting = null
|
||||
else if(ghostvision && (!seedarkness || client.prefs.ghost_others <= GHOST_OTHERS_DEFAULT_SPRITE))
|
||||
//add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now
|
||||
if(!lastsetting)
|
||||
client.images |= ghost_darkness_images
|
||||
client.images -= GLOB.ghost_images_simple
|
||||
lastsetting = client.prefs.ghost_others
|
||||
if(!ghostvision)
|
||||
return
|
||||
if(client.prefs.ghost_others != GHOST_OTHERS_THEIR_SETTING)
|
||||
switch(client.prefs.ghost_others)
|
||||
if(GHOST_OTHERS_THEIR_SETTING)
|
||||
client.images |= ghost_images_full
|
||||
if (ghostimage)
|
||||
client.images -= ghostimage //remove ourself
|
||||
if(GHOST_OTHERS_DEFAULT_SPRITE)
|
||||
client.images |= ghost_images_default
|
||||
if(ghostimage_default)
|
||||
client.images -= ghostimage_default
|
||||
client.images |= (GLOB.ghost_images_default-ghostimage_default)
|
||||
if(GHOST_OTHERS_SIMPLE)
|
||||
client.images |= ghost_images_simple
|
||||
if(ghostimage_simple)
|
||||
client.images -= ghostimage_simple
|
||||
lastsetting = client.prefs.ghost_others
|
||||
client.images |= (GLOB.ghost_images_simple-ghostimage_simple)
|
||||
|
||||
/mob/dead/observer/verb/possess()
|
||||
set category = "Ghost"
|
||||
@@ -582,8 +562,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set desc= "Take over the body of a mindless creature!"
|
||||
|
||||
var/list/possessible = list()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(!(L in player_list) && !L.mind)
|
||||
for(var/mob/living/L in GLOB.living_mob_list)
|
||||
if(!(L in GLOB.player_list) && !L.mind)
|
||||
possessible += L
|
||||
|
||||
var/mob/living/target = input("Your new life begins today!", "Possess Mob", null, null) as null|anything in possessible
|
||||
@@ -595,7 +575,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(src, "<span class='warning'>This creature is too powerful for you to possess!</span>")
|
||||
return 0
|
||||
|
||||
if(can_reenter_corpse || (mind && mind.current))
|
||||
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
|
||||
if(target.key)
|
||||
@@ -631,7 +611,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/proc/show_server_hop_transfer_screen(expected_key)
|
||||
//only show it to incoming ghosts
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
for(var/mob/dead/observer/O in GLOB.player_list)
|
||||
if(O.key == expected_key)
|
||||
if(O.client)
|
||||
new /obj/screen/splash(O.client, TRUE)
|
||||
@@ -652,7 +632,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
var/dat
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += data_core.get_manifest()
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
|
||||
src << browse(dat, "window=manifest;size=387x420;can_close=1")
|
||||
|
||||
@@ -692,12 +672,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
/mob/dead/observer/proc/show_data_huds()
|
||||
for(var/hudtype in datahuds)
|
||||
var/datum/atom_hud/H = huds[hudtype]
|
||||
var/datum/atom_hud/H = GLOB.huds[hudtype]
|
||||
H.add_hud_to(src)
|
||||
|
||||
/mob/dead/observer/proc/remove_data_huds()
|
||||
for(var/hudtype in datahuds)
|
||||
var/datum/atom_hud/H = huds[hudtype]
|
||||
var/datum/atom_hud/H = GLOB.huds[hudtype]
|
||||
H.remove_hud_from(src)
|
||||
|
||||
/mob/dead/observer/verb/toggle_data_huds()
|
||||
@@ -742,7 +722,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
update_icon()
|
||||
|
||||
/mob/dead/observer/canUseTopic()
|
||||
/mob/dead/observer/canUseTopic(atom/movable/AM,be_close = FALSE)
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
return 1
|
||||
return
|
||||
@@ -754,11 +734,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if("icon")
|
||||
ghostimage.icon = icon
|
||||
ghostimage_default.icon = icon
|
||||
ghostimage_simple.icon = icon
|
||||
if("icon_state")
|
||||
ghostimage.icon_state = icon_state
|
||||
ghostimage_default.icon_state = icon_state
|
||||
ghostimage_simple.icon_state = icon_state
|
||||
if("fun_verbs")
|
||||
@@ -805,7 +783,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(mob_eye.hud_used)
|
||||
LAZYINITLIST(mob_eye.observers)
|
||||
mob_eye.observers |= src
|
||||
mob_eye.hud_used.show_hud(1,src)
|
||||
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
|
||||
observetarget = mob_eye
|
||||
|
||||
/mob/dead/observer/verb/register_pai_candidate()
|
||||
@@ -826,9 +804,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(isobserver(user) && check_rights(R_SPAWN))
|
||||
change_mob_type( /mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering
|
||||
|
||||
/mob/dead/observer/examine(mob/user)
|
||||
..()
|
||||
if(!invisibility)
|
||||
to_chat(user, "It seems extremely obvious.")
|
||||
|
||||
/proc/set_observer_default_invisibility(amount, message=null)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
G.invisibility = amount
|
||||
if(message)
|
||||
to_chat(G, message)
|
||||
observer_default_invisibility = amount
|
||||
GLOB.observer_default_invisibility = amount
|
||||
|
||||
@@ -8,15 +8,18 @@
|
||||
|
||||
. = src.say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
var/atom/movable/to_follow = speaker
|
||||
if(radio_freq)
|
||||
var/atom/movable/virtualspeaker/V = speaker
|
||||
|
||||
if(isAI(V.source))
|
||||
var/mob/living/silicon/ai/S = V.source
|
||||
speaker = S.eyeobj
|
||||
to_follow = S.eyeobj
|
||||
else
|
||||
speaker = V.source
|
||||
var/link = FOLLOW_LINK(src, speaker)
|
||||
to_follow = V.source
|
||||
var/link = FOLLOW_LINK(src, to_follow)
|
||||
// Recompose the message, because it's scrambled by default
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans)
|
||||
to_chat(src, "[link] [message]")
|
||||
|
||||
|
||||
@@ -280,14 +280,15 @@
|
||||
|
||||
//visibly unequips I but it is NOT MOVED AND REMAINS IN SRC
|
||||
//item MUST BE FORCEMOVE'D OR QDEL'D
|
||||
/mob/proc/temporarilyRemoveItemFromInventory(obj/item/I, force = FALSE)
|
||||
return doUnEquip(I, force, null, TRUE)
|
||||
/mob/proc/temporarilyRemoveItemFromInventory(obj/item/I, force = FALSE, idrop = TRUE)
|
||||
return doUnEquip(I, force, null, TRUE, idrop)
|
||||
|
||||
//DO NOT CALL THIS PROC
|
||||
//use one of the above 2 helper procs
|
||||
//you may override it, but do not modify the args
|
||||
/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move) //Force overrides NODROP for things like wizarditis and admin undress.
|
||||
/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides NODROP for things like wizarditis and admin undress.
|
||||
//Use no_move if the item is just gonna be immediately moved afterward
|
||||
//Invdrop is used to prevent stuff in pockets dropping. only set to false if it's going to immediately be replaced
|
||||
if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP.
|
||||
return TRUE
|
||||
|
||||
@@ -346,7 +347,12 @@
|
||||
items += w_uniform
|
||||
return items
|
||||
|
||||
|
||||
/mob/living/proc/unequip_everything()
|
||||
var/list/items = list()
|
||||
items |= get_equipped_items()
|
||||
for(var/I in items)
|
||||
dropItemToGround(I)
|
||||
drop_all_held_items()
|
||||
|
||||
/obj/item/proc/equip_to_best_slot(var/mob/M)
|
||||
if(src != M.get_active_held_item())
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/obj/item/device/mmi
|
||||
name = "Man-Machine Interface"
|
||||
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
|
||||
@@ -66,8 +64,8 @@
|
||||
brainmob.container = src
|
||||
if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
|
||||
brainmob.stat = CONSCIOUS //we manually revive the brain mob
|
||||
dead_mob_list -= brainmob
|
||||
living_mob_list += brainmob
|
||||
GLOB.dead_mob_list -= brainmob
|
||||
GLOB.living_mob_list += brainmob
|
||||
|
||||
brainmob.reset_perspective()
|
||||
brain = newbrain
|
||||
@@ -99,8 +97,8 @@
|
||||
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
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
GLOB.living_mob_list -= brainmob //Get outta here
|
||||
GLOB.dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
if(user)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
|
||||
/mob/living/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
@@ -64,4 +62,4 @@
|
||||
/mob/living/brain/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(stored_dna)
|
||||
stored_dna.real_name = real_name
|
||||
stored_dna.real_name = real_name
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/datum/emote/brain/flash
|
||||
key = "flash"
|
||||
message = "lights' blink."
|
||||
message = "blinks their lights."
|
||||
|
||||
/datum/emote/brain/notice
|
||||
key = "notice"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var/global/posibrain_notif_cooldown = 0
|
||||
GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
|
||||
/obj/item/device/mmi/posibrain
|
||||
name = "positronic brain"
|
||||
@@ -7,11 +7,11 @@ var/global/posibrain_notif_cooldown = 0
|
||||
icon_state = "posibrain"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "biotech=3;programming=3;plasmatech=2"
|
||||
var/notified = 0
|
||||
var/next_ask
|
||||
var/askDelay = 600 //one minute
|
||||
var/used = 0 //Prevents split personality virus. May be reset if personality deletion code is added.
|
||||
var/searching = FALSE
|
||||
brainmob = null
|
||||
req_access = list(access_robotics)
|
||||
req_access = list(GLOB.access_robotics)
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
braintype = "Android"
|
||||
var/autoping = TRUE //if it pings on creation immediately
|
||||
@@ -25,9 +25,8 @@ var/global/posibrain_notif_cooldown = 0
|
||||
Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
|
||||
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
|
||||
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
|
||||
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
|
||||
var/picked_fluff_name //which fluff name we picked
|
||||
|
||||
var/list/possible_names //If you leave this blank, it will use the global posibrain names
|
||||
var/picked_name
|
||||
|
||||
/obj/item/device/mmi/posibrain/Topic(href, href_list)
|
||||
if(href_list["activate"])
|
||||
@@ -36,42 +35,42 @@ var/global/posibrain_notif_cooldown = 0
|
||||
activate(ghost)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
|
||||
if(newlymade || !posibrain_notif_cooldown)
|
||||
if(newlymade || GLOB.posibrain_notify_cooldown <= world.time)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
if(!newlymade)
|
||||
posibrain_notif_cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/reset_posibrain_cooldown), askDelay)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/reset_posibrain_cooldown()
|
||||
posibrain_notif_cooldown = 0
|
||||
GLOB.posibrain_notify_cooldown = world.time + askDelay
|
||||
|
||||
/obj/item/device/mmi/posibrain/attack_self(mob/user)
|
||||
if(brainmob && !brainmob.key && !notified)
|
||||
//Start the process of requesting a new ghost.
|
||||
to_chat(user, begin_activation_message)
|
||||
ping_ghosts("requested", FALSE)
|
||||
notified = 1
|
||||
used = 0
|
||||
update_icon()
|
||||
spawn(askDelay) //Seperate from the global cooldown.
|
||||
notified = 0
|
||||
update_icon()
|
||||
if(brainmob.client)
|
||||
visible_message(success_message)
|
||||
else
|
||||
visible_message(fail_message)
|
||||
|
||||
return //Code for deleting personalities recommended here.
|
||||
if(!brainmob || brainmob.key)
|
||||
return
|
||||
if(next_ask > world.time)
|
||||
return
|
||||
//Start the process of requesting a new ghost.
|
||||
to_chat(user, begin_activation_message)
|
||||
ping_ghosts("requested", FALSE)
|
||||
next_ask = world.time + askDelay
|
||||
searching = TRUE
|
||||
addtimer(CALLBACK(src, .proc/check_success), askDelay)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/check_success()
|
||||
searching = FALSE
|
||||
update_icon()
|
||||
if(QDELETED(brainmob))
|
||||
return
|
||||
if(brainmob.client)
|
||||
visible_message(success_message)
|
||||
else
|
||||
visible_message(fail_message)
|
||||
|
||||
/obj/item/device/mmi/posibrain/attack_ghost(mob/user)
|
||||
activate(user)
|
||||
|
||||
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
|
||||
/obj/item/device/mmi/posibrain/proc/activate(mob/user)
|
||||
if(used || (brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
|
||||
if(QDELETED(brainmob))
|
||||
return
|
||||
if(brainmob.key || jobban_isbanned(user,"posibrain"))
|
||||
return
|
||||
|
||||
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
|
||||
if(posi_ask == "No" || QDELETED(src))
|
||||
return
|
||||
@@ -97,10 +96,11 @@ var/global/posibrain_notif_cooldown = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
|
||||
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
|
||||
if(QDELETED(brainmob))
|
||||
return
|
||||
if(brainmob.key) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
|
||||
to_chat(candidate, "This brain has already been taken! Please try your possession again later!")
|
||||
return FALSE
|
||||
notified = 0
|
||||
if(candidate.mind && !isobserver(candidate))
|
||||
candidate.mind.transfer_to(brainmob)
|
||||
else
|
||||
@@ -109,12 +109,11 @@ var/global/posibrain_notif_cooldown = 0
|
||||
to_chat(brainmob, welcome_message)
|
||||
brainmob.mind.assigned_role = new_role
|
||||
brainmob.stat = CONSCIOUS
|
||||
dead_mob_list -= brainmob
|
||||
living_mob_list += brainmob
|
||||
GLOB.dead_mob_list -= brainmob
|
||||
GLOB.living_mob_list += brainmob
|
||||
|
||||
visible_message(new_mob_message)
|
||||
update_icon()
|
||||
used = 1
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -124,7 +123,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
if(brainmob && brainmob.key)
|
||||
switch(brainmob.stat)
|
||||
if(CONSCIOUS)
|
||||
if(!src.brainmob.client)
|
||||
if(!brainmob.client)
|
||||
msg = "It appears to be in stand-by mode." //afk
|
||||
if(DEAD)
|
||||
msg = "<span class='deadsay'>It appears to be completely inactive.</span>"
|
||||
@@ -133,24 +132,27 @@ var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
to_chat(user, msg)
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
/obj/item/device/mmi/posibrain/Initialize()
|
||||
..()
|
||||
brainmob = new(src)
|
||||
picked_fluff_name = pick(fluff_names)
|
||||
brainmob.name = "[picked_fluff_name]-[rand(100, 999)]"
|
||||
var/new_name
|
||||
if(!LAZYLEN(possible_names))
|
||||
new_name = pick(GLOB.posibrain_names)
|
||||
else
|
||||
new_name = pick(possible_names)
|
||||
brainmob.name = "[new_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.loc = src
|
||||
brainmob.container = src
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/attackby(obj/item/O, mob/user)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/update_icon()
|
||||
if(notified)
|
||||
if(searching)
|
||||
icon_state = "[initial(icon_state)]-searching"
|
||||
return
|
||||
if(brainmob && brainmob.key)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/brain/say(message)
|
||||
/mob/living/brain/say(message, language)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
@@ -7,16 +7,17 @@
|
||||
return
|
||||
else
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/brain/get_spans()
|
||||
return ..() | SPAN_ROBOT
|
||||
|
||||
/mob/living/brain/radio(message, message_mode, list/spans)
|
||||
/mob/living/brain/radio(message, message_mode, list/spans, language)
|
||||
if(message_mode && istype(container, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/R = container
|
||||
if(R.radio)
|
||||
R.radio.talk_into(src, message, , spans)
|
||||
R.radio.talk_into(src, message, , get_spans(), language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/mob/living/brain/lingcheck()
|
||||
@@ -24,4 +25,12 @@
|
||||
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
return message
|
||||
|
||||
/mob/living/brain/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(istype(container, /obj/item/device/mmi/posibrain/soul_vessel))
|
||||
. = has_language(dt) && ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -11,15 +11,13 @@
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
languages_spoken = ALIEN
|
||||
languages_understood = ALIEN
|
||||
sight = SEE_MOBS
|
||||
see_in_dark = 4
|
||||
verb_say = "hisses"
|
||||
initial_languages = list(/datum/language/xenocommon)
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
devourable = 1
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
@@ -111,7 +109,7 @@ Des: Gives the client of the alien an image on each infected mob.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/alien/proc/AddInfectionImages()
|
||||
if (client)
|
||||
for (var/mob/living/C in mob_list)
|
||||
for (var/mob/living/C in GLOB.mob_list)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/obj/item/organ/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/body_egg/alien_embryo)
|
||||
if(A)
|
||||
|
||||
@@ -74,7 +74,8 @@ In all, this is a lot like the monkey code. /N
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
switch(M.melee_damage_type)
|
||||
if(BRUTE)
|
||||
@@ -89,7 +90,6 @@ In all, this is a lot like the monkey code. /N
|
||||
adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/datum/emote/living/alien
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/alien)
|
||||
|
||||
/datum/emote/living/alien/gnarl
|
||||
key = "gnarl"
|
||||
key_third_person = "gnarls"
|
||||
message = "gnarls and shows its teeth..."
|
||||
|
||||
/datum/emote/living/alien/hiss
|
||||
key = "hiss"
|
||||
key_third_person = "hisses"
|
||||
message_alien = "hisses."
|
||||
message_larva = "hisses softly."
|
||||
|
||||
/datum/emote/living/alien/hiss/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(. && isalienadult(user))
|
||||
playsound(user.loc, "hiss", 40, 1, 1)
|
||||
|
||||
/datum/emote/living/alien/roar
|
||||
key = "roar"
|
||||
key_third_person = "roars"
|
||||
message_alien = "roars"
|
||||
message_larva = "softly roars"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/alien/roar/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(. && isalienadult(user))
|
||||
playsound(user.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
|
||||
@@ -87,7 +87,7 @@ Doesn't work on other aliens/AI.*/
|
||||
log_say("AlienWhisper: [key_name(user)]->[M.key] : [msg]")
|
||||
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...</span>[msg]")
|
||||
to_chat(user, "<span class='noticealien'>You said: \"[msg]\" to [M]</span>")
|
||||
for(var/ded in dead_mob_list)
|
||||
for(var/ded in GLOB.dead_mob_list)
|
||||
if(!isobserver(ded))
|
||||
continue
|
||||
var/follow_link_user = FOLLOW_LINK(ded, user)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/C in living_mob_list)
|
||||
for(var/mob/living/carbon/C in GLOB.living_mob_list)
|
||||
if(C == src) //Make sure not to proc it on ourselves.
|
||||
continue
|
||||
var/obj/item/organ/alien/hivenode/node = C.getorgan(/obj/item/organ/alien/hivenode)
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
|
||||
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
|
||||
/proc/get_alien_type(var/alienpath)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in living_mob_list)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list)
|
||||
if(!istype(A, alienpath))
|
||||
continue
|
||||
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/Initialize()
|
||||
//there should only be one queen
|
||||
for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in living_mob_list)
|
||||
for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in GLOB.living_mob_list)
|
||||
if(Q == src)
|
||||
continue
|
||||
if(Q.stat == DEAD)
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/S in player_list)
|
||||
for(var/mob/S in GLOB.player_list)
|
||||
if(!S.stat && S.hivecheck())
|
||||
to_chat(S, rendered)
|
||||
if(S in dead_mob_list)
|
||||
if(S in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(S, src)
|
||||
to_chat(S, "[link] [rendered]")
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ Proc: AddInfectionImages(C)
|
||||
Des: Adds the infection image to all aliens for this embryo
|
||||
----------------------------------------*/
|
||||
/obj/item/organ/body_egg/alien_embryo/AddInfectionImages()
|
||||
for(var/mob/living/carbon/alien/alien in player_list)
|
||||
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
|
||||
if(alien.client)
|
||||
var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]")
|
||||
alien.client.images += I
|
||||
@@ -127,7 +127,7 @@ Proc: RemoveInfectionImage(C)
|
||||
Des: Removes all images from the mob infected by this embryo
|
||||
----------------------------------------*/
|
||||
/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages()
|
||||
for(var/mob/living/carbon/alien/alien in player_list)
|
||||
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
|
||||
if(alien.client)
|
||||
for(var/image/I in alien.client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == owner)
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
|
||||
var/const/MAX_IMPREGNATION_TIME = 150
|
||||
#define MIN_IMPREGNATION_TIME 100 //time it takes to impregnate someone
|
||||
#define MAX_IMPREGNATION_TIME 150
|
||||
|
||||
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
|
||||
var/const/MAX_ACTIVE_TIME = 400
|
||||
#define MIN_ACTIVE_TIME 200 //time between being dropped and going idle
|
||||
#define MAX_ACTIVE_TIME 400
|
||||
|
||||
/obj/item/clothing/mask/facehugger
|
||||
name = "alien"
|
||||
@@ -152,14 +152,6 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
// probiscis-blocker handling
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
if(target.wear_mask)
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(W.flags & NODROP)
|
||||
return FALSE
|
||||
if(!istype(W,/obj/item/clothing/mask/facehugger))
|
||||
target.dropItemToGround(W)
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -168,6 +160,12 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return FALSE
|
||||
|
||||
if(target.wear_mask)
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(!istype(W,/obj/item/clothing/mask/facehugger) && target.dropItemToGround(W))
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
forceMove(target)
|
||||
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
|
||||
// early returns and validity checks done: attach.
|
||||
|
||||
@@ -522,6 +522,7 @@
|
||||
return
|
||||
|
||||
sight = initial(sight)
|
||||
lighting_alpha = initial(lighting_alpha)
|
||||
var/obj/item/organ/eyes/E = getorganslot("eye_sight")
|
||||
if(!E)
|
||||
update_tint()
|
||||
@@ -529,6 +530,8 @@
|
||||
see_invisible = E.see_invisible
|
||||
see_in_dark = E.see_in_dark
|
||||
sight |= E.sight_flags
|
||||
if(!isnull(E.lighting_alpha))
|
||||
lighting_alpha = E.lighting_alpha
|
||||
|
||||
if(client.eye != src)
|
||||
var/atom/A = client.eye
|
||||
@@ -543,6 +546,8 @@
|
||||
see_invisible = G.invis_override
|
||||
else
|
||||
see_invisible = min(G.invis_view, see_invisible)
|
||||
if(!isnull(G.lighting_alpha))
|
||||
lighting_alpha = min(lighting_alpha, G.lighting_alpha)
|
||||
if(dna)
|
||||
for(var/X in dna.mutations)
|
||||
var/datum/mutation/M = X
|
||||
@@ -552,11 +557,12 @@
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
. = ..()
|
||||
|
||||
|
||||
//to recalculate and update the mob's total tint from tinted equipment it's wearing.
|
||||
/mob/living/carbon/proc/update_tint()
|
||||
if(!tinted_weldhelh)
|
||||
if(!GLOB.tinted_weldhelh)
|
||||
return
|
||||
tinttotal = get_total_tint()
|
||||
if(tinttotal >= TINT_BLIND)
|
||||
|
||||
@@ -44,4 +44,7 @@
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
//Gets filled up in create_bodyparts()
|
||||
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
|
||||
var/icon_render_key = ""
|
||||
var/static/list/limb_icon_cache = list()
|
||||
@@ -19,12 +19,6 @@
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
|
||||
|
||||
var/const/NO_SLIP_WHEN_WALKING = 1
|
||||
var/const/SLIDE = 2
|
||||
var/const/GALOSHES_DONT_HELP = 4
|
||||
var/const/SLIDE_ICE = 8
|
||||
|
||||
/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
|
||||
if(movement_type & FLYING)
|
||||
return 0
|
||||
|
||||
@@ -147,8 +147,8 @@
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1)
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
emote("deathgasp")
|
||||
|
||||
. = ..()
|
||||
if(ticker && ticker.mode)
|
||||
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
if(SSticker && SSticker.mode)
|
||||
SSticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
|
||||
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
|
||||
for(var/mob/M in src)
|
||||
@@ -35,7 +35,7 @@
|
||||
if(org_zone == "chest")
|
||||
O.Remove(src)
|
||||
O.forceMove(get_turf(src))
|
||||
O.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
O.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
else
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
@@ -44,11 +44,11 @@
|
||||
continue
|
||||
I.Remove(src)
|
||||
I.forceMove(get_turf(src))
|
||||
I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
|
||||
|
||||
/mob/living/carbon/spread_bodyparts()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.drop_limb()
|
||||
BP.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
BP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
@@ -10,8 +10,11 @@
|
||||
else
|
||||
new /obj/effect/gibspawner/humanbodypartless(loc, viruses, dna)
|
||||
|
||||
/mob/living/carbon/human/spawn_dust()
|
||||
new /obj/effect/decal/remains/human(loc)
|
||||
/mob/living/carbon/human/spawn_dust(just_ash = FALSE)
|
||||
if(just_ash)
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
else
|
||||
new /obj/effect/decal/remains/human(loc)
|
||||
|
||||
/mob/living/carbon/human/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
@@ -29,7 +32,7 @@
|
||||
|
||||
dna.species.spec_death(gibbed, src)
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
if(SSticker && SSticker.mode)
|
||||
sql_report_death(src)
|
||||
if(mind && mind.devilinfo)
|
||||
INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
if(!key)
|
||||
var/foundghost = 0
|
||||
if(mind)
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
if(G.mind == mind)
|
||||
foundghost = 1
|
||||
if (G.can_reenter_corpse == 0)
|
||||
@@ -257,9 +257,6 @@
|
||||
msg += "[t_He] looks like a drunken mess.\n"
|
||||
if(91.01 to INFINITY)
|
||||
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
|
||||
for (var/I in src.vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
msg += B.get_examine_msg()
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
@@ -292,7 +289,7 @@
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH)
|
||||
var/perpname = get_face_name(get_id_name(""))
|
||||
if(perpname)
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.general)
|
||||
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general)
|
||||
if(R)
|
||||
msg += "<span class='deptradio'>Rank:</span> [R.fields["rank"]]<br>"
|
||||
msg += "<a href='?src=\ref[src];hud=1;photo_front=1'>\[Front photo\]</a> "
|
||||
@@ -310,7 +307,7 @@
|
||||
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health_r]\]</a>"
|
||||
health_r = R.fields["m_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health_r]\]</a><br>"
|
||||
R = find_record("name", perpname, data_core.medical)
|
||||
R = find_record("name", perpname, GLOB.data_core.medical)
|
||||
if(R)
|
||||
msg += "<a href='?src=\ref[src];hud=m;evaluation=1'>\[Medical evaluation\]</a><br>"
|
||||
|
||||
@@ -320,7 +317,7 @@
|
||||
//|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
|
||||
var/criminal = "None"
|
||||
|
||||
R = find_record("name", perpname, data_core.security)
|
||||
R = find_record("name", perpname, GLOB.data_core.security)
|
||||
if(R)
|
||||
criminal = R.fields["criminal"]
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/mob/living/carbon/human/proc/examine_nutrition()
|
||||
var/message = ""
|
||||
var/nutrition_examine = round(nutrition)
|
||||
var/t_He = "It" //capitalised for use at the start of each line.
|
||||
var/t_His = "Its"
|
||||
var/t_his = "its"
|
||||
var/t_is = "is"
|
||||
var/t_has = "has"
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_his = "his"
|
||||
t_His = "His"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_his = "her"
|
||||
t_His = "Her"
|
||||
if(PLURAL)
|
||||
t_He = "They"
|
||||
t_his = "their"
|
||||
t_His = "Their"
|
||||
t_is = "are"
|
||||
t_has = "have"
|
||||
if(NEUTER)
|
||||
t_He = "It"
|
||||
t_his = "its"
|
||||
t_His = "Its"
|
||||
switch(nutrition_examine)
|
||||
if(0 to 49)
|
||||
message = "<span class='warning'>[t_He] [t_is] starving! You can hear [t_his] stomach snarling from across the room!</span>\n"
|
||||
if(50 to 99)
|
||||
message = "<span class='warning'>[t_He] [t_is] extremely hungry. A deep growl occasionally rumbles from [t_his] empty stomach.</span>\n"
|
||||
if(100 to 499)
|
||||
return message //Well that's pretty normal, really.
|
||||
if(500 to 864) // Fat.
|
||||
message = "[t_He] [t_has] a stuffed belly, bloated fat and round from eating too much.\n"
|
||||
if(1200 to 1934) // One person fully digested.
|
||||
message = "<span class='warning'>[t_He] [t_is] sporting a large, round, sagging stomach. It's contains at least their body weight worth of glorping slush.</span>\n"
|
||||
if(1935 to 3004) // Two people.
|
||||
message = "<span class='warning'>[t_He] [t_is] engorged with a huge stomach that sags and wobbles as they move. [t_He] must have consumed at least twice their body weight. It looks incredibly soft.</span>\n"
|
||||
if(3005 to 4074) // Three people.
|
||||
message = "<span class='warning'>[t_His] stomach is firmly packed with digesting slop. [t_He] must have eaten at least a few times worth their body weight! It looks hard for them to stand, and [t_his] gut jiggles when they move.</span>\n"
|
||||
if(4075 to 10000) // Four or more people.
|
||||
message = "<span class='warning'>[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!</span>\n"
|
||||
return message
|
||||
|
||||
/mob/living/carbon/human/proc/examine_bellies()
|
||||
var/message = ""
|
||||
|
||||
for (var/I in src.vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
message += B.get_examine_msg()
|
||||
|
||||
return message
|
||||
@@ -17,6 +17,9 @@
|
||||
args[1] = FALSE
|
||||
Initialize(arglist(args))
|
||||
|
||||
/mob/living/carbon/human/dummy/Life()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/Initialize()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
@@ -39,6 +42,8 @@
|
||||
|
||||
handcrafting = new()
|
||||
|
||||
grant_language(/datum/language/common) // ME TARZAN, YOU JANEBOT
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/create_internal_organs()
|
||||
@@ -298,7 +303,7 @@
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/perpname = get_face_name(get_id_name(""))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud))
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.general)
|
||||
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general)
|
||||
if(href_list["photo_front"] || href_list["photo_side"])
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
@@ -388,7 +393,7 @@
|
||||
if (!G.emagged)
|
||||
if(H.wear_id)
|
||||
var/list/access = H.wear_id.GetAccess()
|
||||
if(access_sec_doors in access)
|
||||
if(GLOB.access_sec_doors in access)
|
||||
allowed_access = H.get_authentification_name()
|
||||
else
|
||||
allowed_access = "@%&ERROR_%$*"
|
||||
@@ -399,7 +404,7 @@
|
||||
return
|
||||
|
||||
if(perpname)
|
||||
R = find_record("name", perpname, data_core.security)
|
||||
R = find_record("name", perpname, GLOB.data_core.security)
|
||||
if(R)
|
||||
if(href_list["status"])
|
||||
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged", "Cancel")
|
||||
@@ -447,8 +452,8 @@
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
data_core.addMinorCrime(R.fields["id"], crime)
|
||||
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
GLOB.data_core.addMinorCrime(R.fields["id"], crime)
|
||||
to_chat(usr, "<span class='notice'>Successfully added a minor crime.</span>")
|
||||
return
|
||||
if("Major Crime")
|
||||
@@ -462,8 +467,8 @@
|
||||
return
|
||||
else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
data_core.addMajorCrime(R.fields["id"], crime)
|
||||
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
GLOB.data_core.addMajorCrime(R.fields["id"], crime)
|
||||
to_chat(usr, "<span class='notice'>Successfully added a major crime.</span>")
|
||||
return
|
||||
|
||||
@@ -494,7 +499,7 @@
|
||||
var/counter = 1
|
||||
while(R.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1)
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
|
||||
to_chat(usr, "<span class='notice'>Successfully added comment.</span>")
|
||||
return
|
||||
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
||||
@@ -581,7 +586,7 @@
|
||||
|
||||
//Check for weapons
|
||||
if(judgebot.weaponscheck)
|
||||
if(!idcard || !(access_weapons in idcard.access))
|
||||
if(!idcard || !(GLOB.access_weapons in idcard.access))
|
||||
for(var/obj/item/I in held_items)
|
||||
if(judgebot.check_for_weapons(I))
|
||||
threatcount += 4
|
||||
@@ -591,7 +596,7 @@
|
||||
//Check for arrest warrant
|
||||
if(judgebot.check_records)
|
||||
var/perpname = get_face_name(get_id_name())
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.security)
|
||||
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security)
|
||||
if(R && R.fields["criminal"])
|
||||
switch(R.fields["criminal"])
|
||||
if("*Arrest*")
|
||||
@@ -765,7 +770,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/replace_records_name(oldname,newname) // Only humans have records right now, move this up if changed.
|
||||
for(var/list/L in list(data_core.general,data_core.medical,data_core.security,data_core.locked))
|
||||
for(var/list/L in list(GLOB.data_core.general,GLOB.data_core.medical,GLOB.data_core.security,GLOB.data_core.locked))
|
||||
var/datum/data/record/R = find_record("name", oldname, L)
|
||||
if(R)
|
||||
R.fields["name"] = newname
|
||||
@@ -855,7 +860,7 @@
|
||||
if(7) // Pride
|
||||
log_game("[src] was influenced by the sin of pride.")
|
||||
O = new /datum/objective/sintouched/pride
|
||||
ticker.mode.sintouched += src.mind
|
||||
SSticker.mode.sintouched += src.mind
|
||||
src.mind.objectives += O
|
||||
src.mind.announce_objectives()
|
||||
|
||||
@@ -920,12 +925,15 @@
|
||||
return
|
||||
if(buckled) //NO INFINITE STACKING!!
|
||||
return
|
||||
if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
||||
M.visible_message("<span class='boldwarning'>[M] can't hang onto [src]!</span>")
|
||||
return
|
||||
if(iscarbon(M) && (!riding_datum.equip_buckle_inhands(M, 2))) //MAKE SURE THIS IS LAST!!
|
||||
M.visible_message("<span class='boldwarning'>[M] can't climb onto [src] because [M.p_their()] hands are full!</span>")
|
||||
if(M.stat != CONSCIOUS)
|
||||
return
|
||||
if(iscarbon(M))
|
||||
if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
||||
M.visible_message("<span class='boldwarning'>[M] can't hang onto [src]!</span>")
|
||||
return
|
||||
if(!riding_datum.equip_buckle_inhands(M, 2)) //MAKE SURE THIS IS LAST!!
|
||||
M.visible_message("<span class='boldwarning'>[M] can't climb onto [src] because [M.p_their()] hands are full!</span>")
|
||||
return
|
||||
. = ..(M, force, check_loc)
|
||||
stop_pulling()
|
||||
|
||||
|
||||
@@ -160,8 +160,8 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
|
||||
vore_attack(user, pulling)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling))
|
||||
devour_mob(pulling)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -302,13 +302,14 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
return FALSE
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "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("chest")
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
var/global/default_martial_art = new/datum/martial_art
|
||||
/mob/living/carbon/human
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
initial_languages = list(/datum/language/common)
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
pressure_resistance = 25
|
||||
@@ -43,6 +41,7 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
|
||||
var/datum/martial_art/martial_art = null
|
||||
var/static/default_martial_art = new/datum/martial_art
|
||||
|
||||
var/name_override //For temporary visible name changes
|
||||
|
||||
@@ -50,4 +49,4 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
var/datum/personal_crafting/handcrafting
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime)
|
||||
can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)
|
||||
+56
-80
@@ -67,10 +67,7 @@
|
||||
//modules
|
||||
var/list/functions = list("nearbyscan","combat","shitcurity","chatter")
|
||||
var/restrictedJob = 0
|
||||
var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing
|
||||
var/alternateProcessing = 1
|
||||
var/forceProcess = 0
|
||||
var/processTime = 8
|
||||
var/lastProc = 0
|
||||
var/walkdebug = 0 //causes sparks in our path target. used for debugging
|
||||
var/debugexamine = 0 //If we show debug info in our examine
|
||||
@@ -85,6 +82,7 @@
|
||||
var/traitorScale = 0 // our ability as a traitor
|
||||
var/traitorType = 0
|
||||
|
||||
var/voice_saved = FALSE
|
||||
|
||||
/// SNPC voice handling
|
||||
|
||||
@@ -96,6 +94,8 @@
|
||||
knownStrings = list()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/saveVoice()
|
||||
if(voice_saved)
|
||||
return
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
S["knownStrings"] << knownStrings
|
||||
|
||||
@@ -145,8 +145,7 @@
|
||||
retal_target = potentialAssault
|
||||
..()
|
||||
|
||||
|
||||
/client/proc/resetSNPC(var/mob/A in SSnpc.botPool_l)
|
||||
/client/proc/resetSNPC(var/mob/A in SSnpcpool.processing)
|
||||
set name = "Reset SNPC"
|
||||
set desc = "Reset the SNPC"
|
||||
set category = "Debug"
|
||||
@@ -163,24 +162,7 @@
|
||||
T.retal = 0
|
||||
T.doing = 0
|
||||
|
||||
/client/proc/toggleSNPC(var/mob/A in SSnpc.botPool_l)
|
||||
set name = "Toggle SNPC Proccessing Mode"
|
||||
set desc = "Toggle SNPC Proccessing Mode"
|
||||
set category = "Debug"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
if(A)
|
||||
if(!istype(A,/mob/living/carbon/human/interactive))
|
||||
return
|
||||
var/mob/living/carbon/human/interactive/T = A
|
||||
if(T)
|
||||
T.alternateProcessing = !T.alternateProcessing
|
||||
T.forceProcess = 1
|
||||
to_chat(usr, "[T]'s processing has been switched to [T.alternateProcessing ? "High Profile" : "Low Profile"]")
|
||||
|
||||
/client/proc/customiseSNPC(var/mob/A in SSnpc.botPool_l)
|
||||
/client/proc/customiseSNPC(var/mob/A in SSnpcpool.processing)
|
||||
set name = "Customize SNPC"
|
||||
set desc = "Customise the SNPC"
|
||||
set category = "Debug"
|
||||
@@ -216,7 +198,7 @@
|
||||
T.doSetup()
|
||||
if(prob(25))
|
||||
var/list/validchoices = list()
|
||||
for(var/mob/living/carbon/human/M in mob_list)
|
||||
for(var/mob/living/carbon/human/M in GLOB.mob_list)
|
||||
validchoices += M
|
||||
var/mob/living/carbon/human/chosen = pick(validchoices)
|
||||
var/datum/dna/toDoppel = chosen.dna
|
||||
@@ -241,7 +223,7 @@
|
||||
if(shouldDoppel)
|
||||
if(shouldDoppel == "Yes")
|
||||
var/list/validchoices = list()
|
||||
for(var/mob/living/carbon/human/M in mob_list)
|
||||
for(var/mob/living/carbon/human/M in GLOB.mob_list)
|
||||
validchoices += M
|
||||
|
||||
var/mob/living/carbon/human/chosen = input("Which crewmember?") as null|anything in validchoices
|
||||
@@ -366,14 +348,14 @@
|
||||
|
||||
switch(traitorType)
|
||||
if(SNPC_BRUTE) // SMASH KILL RAAARGH
|
||||
traitorTarget = pick(mob_list)
|
||||
traitorTarget = pick(GLOB.mob_list)
|
||||
if(SNPC_STEALTH) // Shhh we is sneekies
|
||||
var/A = pick(typesof(/datum/objective_item/steal) - /datum/objective_item/steal)
|
||||
var/datum/objective_item/steal/S = new A
|
||||
traitorTarget = locate(S.targetitem) in world
|
||||
if(SNPC_MARTYR) // MY LIFE FOR SPESZUL
|
||||
var/targetType = pick(/obj/machinery/gravity_generator/main/station,/obj/machinery/power/smes/engineering,/obj/machinery/telecomms/hub)
|
||||
traitorTarget = locate(targetType) in machines
|
||||
traitorTarget = locate(targetType) in GLOB.machines
|
||||
if(SNPC_PSYCHO) // YOU'RE LIKE A FLESH BICYLE AND I WANT TO DISMANTLE YOU
|
||||
traitorTarget = null
|
||||
|
||||
@@ -390,7 +372,7 @@
|
||||
|
||||
doSetup()
|
||||
|
||||
SSnpc.insertBot(src)
|
||||
START_PROCESSING(SSnpcpool, src)
|
||||
|
||||
loadVoice()
|
||||
|
||||
@@ -400,8 +382,9 @@
|
||||
attitude += rand(-10,10)
|
||||
slyness += rand(-10,10)
|
||||
|
||||
doProcess()
|
||||
|
||||
/mob/living/carbon/human/interactive/Destroy()
|
||||
SSnpcpool.stop_processing(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/retalTarget(var/target)
|
||||
var/mob/living/carbon/human/M = target
|
||||
@@ -533,39 +516,22 @@
|
||||
/mob/living/carbon/human/interactive/proc/targetRange(towhere)
|
||||
return get_dist(get_turf(towhere), get_turf(src))
|
||||
|
||||
/mob/living/carbon/human/interactive/Life()
|
||||
..()
|
||||
if(ticker.current_state == GAME_STATE_FINISHED)
|
||||
/mob/living/carbon/human/interactive/proc/InteractiveProcess()
|
||||
if(SSticker.current_state == GAME_STATE_FINISHED)
|
||||
saveVoice()
|
||||
if(!alternateProcessing || forceProcess || world.time > lastProc + processTime)
|
||||
doProcess()
|
||||
doProcess()
|
||||
|
||||
/mob/living/carbon/human/interactive/death()
|
||||
saveVoice()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/interactive/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/living/carbon/human/interactive/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
|
||||
if(speaker != src)
|
||||
knownStrings |= html_decode(raw_message)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/doProcess()
|
||||
set waitfor = 0
|
||||
forceProcess = 0
|
||||
lastProc = world.time
|
||||
|
||||
if(shouldUseDynamicProc)
|
||||
var/isSeen = 0
|
||||
for(var/mob/living/carbon/human/A in orange(12,src))
|
||||
if(A.client)
|
||||
isSeen = 1
|
||||
alternateProcessing = isSeen
|
||||
if(alternateProcessing)
|
||||
forceProcess = 1
|
||||
|
||||
if(IsDeadOrIncap())
|
||||
walk(src,0)
|
||||
return
|
||||
set waitfor = FALSE
|
||||
//---------------------------
|
||||
//---- interest flow control
|
||||
if(interest < 0 || inactivity_period < 0)
|
||||
@@ -579,7 +545,7 @@
|
||||
//VIEW FUNCTIONS
|
||||
|
||||
//doorscan is now integrated into life and runs before all other procs
|
||||
for(var/dir in alldirs)
|
||||
for(var/dir in GLOB.alldirs)
|
||||
var/turf/T = get_step(src,dir)
|
||||
if(T)
|
||||
for(var/obj/machinery/door/D in T.contents)
|
||||
@@ -587,10 +553,13 @@
|
||||
if(istype(D,/obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/AL = D
|
||||
if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through
|
||||
inactivity_period = 20
|
||||
AL.panel_open = 1
|
||||
AL.update_icon()
|
||||
AL.shock(src,(100 - smartness)/2)
|
||||
sleep(5)
|
||||
if(QDELETED(AL))
|
||||
return
|
||||
AL.unbolt()
|
||||
if(!AL.wires.is_cut(WIRE_BOLTS))
|
||||
AL.wires.cut(WIRE_BOLTS)
|
||||
@@ -599,9 +568,15 @@
|
||||
if(!AL.wires.is_cut(WIRE_POWER2))
|
||||
AL.wires.cut(WIRE_POWER2)
|
||||
sleep(5)
|
||||
if(QDELETED(AL))
|
||||
return
|
||||
AL.panel_open = 0
|
||||
AL.update_icon()
|
||||
D.open()
|
||||
D.open(2) //crowbar force
|
||||
else
|
||||
D.open()
|
||||
else
|
||||
D.open()
|
||||
|
||||
if(update_hands)
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
@@ -633,7 +608,7 @@
|
||||
//proc functions
|
||||
for(var/Proc in functions)
|
||||
if(!IsDeadOrIncap())
|
||||
callfunction(Proc)
|
||||
INVOKE_ASYNC(src, Proc)
|
||||
|
||||
|
||||
//target interaction stays hardcoded
|
||||
@@ -649,8 +624,8 @@
|
||||
if(istype(TARGET, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = TARGET
|
||||
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor))
|
||||
inactivity_period = 10
|
||||
D.open()
|
||||
//sleep(15)
|
||||
var/turf/T = get_step(get_step(D.loc,dir),dir) //recursion yo
|
||||
tryWalk(T)
|
||||
//THIEVING SKILLS
|
||||
@@ -672,15 +647,8 @@
|
||||
insert_into_backpack()
|
||||
//---------FASHION
|
||||
if(istype(TARGET,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = TARGET
|
||||
drop_item()
|
||||
spawn(5)
|
||||
take_to_slot(C,1)
|
||||
if(!equip_to_appropriate_slot(C))
|
||||
var/obj/item/I = get_item_by_slot(C)
|
||||
dropItemToGround(I)
|
||||
spawn(5)
|
||||
equip_to_appropriate_slot(C)
|
||||
dressup(TARGET)
|
||||
update_hands = 1
|
||||
if(MYPDA in src.loc || MYID in src.loc)
|
||||
if(MYPDA in src.loc)
|
||||
@@ -738,8 +706,19 @@
|
||||
TARGET = traitorTarget
|
||||
tryWalk(TARGET)
|
||||
LAST_TARGET = TARGET
|
||||
if(alternateProcessing)
|
||||
addtimer(CALLBACK(src, .proc/doProcess), processTime)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/dressup(obj/item/clothing/C)
|
||||
set waitfor = FALSE
|
||||
inactivity_period = 12
|
||||
sleep(5)
|
||||
if(!QDELETED(C) && !QDELETED(src))
|
||||
take_to_slot(C,1)
|
||||
if(!equip_to_appropriate_slot(C))
|
||||
var/obj/item/I = get_item_by_slot(C)
|
||||
dropItemToGround(I)
|
||||
sleep(5)
|
||||
if(!QDELETED(src) && !QDELETED(C))
|
||||
equip_to_appropriate_slot(C)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/favouredObjIn(var/list/inList)
|
||||
var/list/outList = list()
|
||||
@@ -751,11 +730,6 @@
|
||||
outList = inList
|
||||
return outList
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/callfunction(Proc)
|
||||
set waitfor = 0
|
||||
spawn(0)
|
||||
call(src,Proc)(src)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget, override = 0)
|
||||
if(restrictedJob && !override) // we're a job that has to stay in our home
|
||||
if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob))))
|
||||
@@ -1133,7 +1107,7 @@
|
||||
|
||||
for(var/mob/living/carbon/human/C in nearby)
|
||||
var/perpname = C.get_face_name(C.get_id_name())
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.security)
|
||||
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security)
|
||||
if(R && R.fields["criminal"])
|
||||
switch(R.fields["criminal"])
|
||||
if("*Arrest*")
|
||||
@@ -1143,7 +1117,8 @@
|
||||
for(var/obj/item/I in allContents)
|
||||
if(istype(I,/obj/item/weapon/restraints))
|
||||
I.attack(TARGET,src) // go go bluespace restraint launcher!
|
||||
sleep(25)
|
||||
inactivity_period = 25
|
||||
break
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/clowning(obj)
|
||||
if(shouldModulePass())
|
||||
@@ -1225,7 +1200,7 @@
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
M.attack(C,src)
|
||||
sleep(25)
|
||||
inactivity_period = 25
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
else if(shouldTryHeal == 2)
|
||||
@@ -1237,7 +1212,7 @@
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
HPS.attack(C,src)
|
||||
sleep(25)
|
||||
inactivity_period = 25
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
|
||||
@@ -1265,7 +1240,7 @@
|
||||
tryWalk(TC)
|
||||
else
|
||||
S.afterattack(TC,src)
|
||||
sleep(25)
|
||||
inactivity_period = 25
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/customEmote(var/text)
|
||||
visible_message("<span class='notice'>[text]</span>")
|
||||
@@ -1354,7 +1329,7 @@
|
||||
var/choice = pick(1,2)
|
||||
if(choice == 1)
|
||||
tryWalk(get_turf(D))
|
||||
sleep(get_dist(src,D))
|
||||
inactivity_period = get_dist(src,D)
|
||||
D.attackby(RP,src)
|
||||
else
|
||||
cookingwithmagic(D)
|
||||
@@ -1364,7 +1339,7 @@
|
||||
var/choice = pick(1,2)
|
||||
if(choice == 1)
|
||||
tryWalk(get_turf(D))
|
||||
sleep(get_dist(src,D))
|
||||
inactivity_period = get_dist(src,D)
|
||||
FD.attackby(KK,src)
|
||||
else
|
||||
cookingwithmagic(FD)
|
||||
@@ -1374,7 +1349,7 @@
|
||||
var/choice = pick(1,2)
|
||||
if(choice == 1)
|
||||
tryWalk(get_turf(D))
|
||||
sleep(get_dist(src,D))
|
||||
inactivity_period = get_dist(src,D)
|
||||
CB.attackby(RP,src)
|
||||
else
|
||||
cookingwithmagic(CB)
|
||||
@@ -1384,7 +1359,7 @@
|
||||
var/choice = pick(1,2)
|
||||
if(choice == 1)
|
||||
tryWalk(get_turf(D))
|
||||
sleep(get_dist(src,D))
|
||||
inactivity_period = get_dist(src,D)
|
||||
PD.attackby(KK,src)
|
||||
else
|
||||
cookingwithmagic(PD)
|
||||
@@ -1533,6 +1508,7 @@
|
||||
G.attack_self(src)
|
||||
if(prob(smartness))
|
||||
npcDrop(G,1)
|
||||
inactivity_period = 15
|
||||
sleep(15)
|
||||
throw_item(TARGET)
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
clear_fullscreen("nearsighted")
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
|
||||
update_sight()
|
||||
update_inv_glasses()
|
||||
if(slot_gloves)
|
||||
@@ -141,13 +141,13 @@
|
||||
|
||||
return not_handled //For future deeper overrides
|
||||
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force)
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop)
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
return
|
||||
|
||||
if(I == wear_suit)
|
||||
if(s_store)
|
||||
if(s_store && invdrop)
|
||||
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
|
||||
if(wear_suit.breakouttime) //when unequipping a straightjacket
|
||||
update_action_buttons_icon() //certain action buttons may be usable again.
|
||||
@@ -156,17 +156,18 @@
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else if(I == w_uniform)
|
||||
if(r_store)
|
||||
dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop.
|
||||
if(l_store)
|
||||
dropItemToGround(l_store, TRUE)
|
||||
if(wear_id)
|
||||
dropItemToGround(wear_id)
|
||||
if(belt)
|
||||
dropItemToGround(belt)
|
||||
if(invdrop)
|
||||
if(r_store)
|
||||
dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop.
|
||||
if(l_store)
|
||||
dropItemToGround(l_store, TRUE)
|
||||
if(wear_id)
|
||||
dropItemToGround(wear_id)
|
||||
if(belt)
|
||||
dropItemToGround(belt)
|
||||
w_uniform = null
|
||||
update_suit_sensors()
|
||||
update_inv_w_uniform()
|
||||
update_inv_w_uniform(invdrop)
|
||||
else if(I == gloves)
|
||||
gloves = null
|
||||
update_inv_gloves()
|
||||
@@ -180,7 +181,7 @@
|
||||
if(G.vision_correction)
|
||||
if(disabilities & NEARSIGHT)
|
||||
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
|
||||
update_sight()
|
||||
update_inv_glasses()
|
||||
else if(I == ears)
|
||||
|
||||
@@ -57,8 +57,6 @@
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(ismob(loc))
|
||||
return ONE_ATMOSPHERE //hopefully won't murderficate people in your guts by going for a spacewalk
|
||||
else
|
||||
return pressure
|
||||
|
||||
@@ -98,7 +96,7 @@
|
||||
if(!dna.species.breathe(src))
|
||||
..()
|
||||
#define HUMAN_MAX_OXYLOSS 3
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30)
|
||||
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
|
||||
|
||||
var/L = getorganslot("lungs")
|
||||
@@ -141,8 +139,6 @@
|
||||
|
||||
/mob/living/carbon/human/proc/get_thermal_protection()
|
||||
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
|
||||
if(ismob(loc))
|
||||
thermal_protection = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT //because lazy and insulated by being inside someone
|
||||
if(wear_suit)
|
||||
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
thermal_protection += (wear_suit.max_heat_protection_temperature*0.7)
|
||||
@@ -252,9 +248,6 @@
|
||||
if(dna.check_mutation(COLDRES))
|
||||
return 1 //Fully protected from the cold.
|
||||
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy and being inside somemone insulates you from space
|
||||
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
/mob/living/carbon/human/say_quote(input, spans)
|
||||
if(!input)
|
||||
return "says, \"...\"" //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
|
||||
/mob/living/carbon/human/say_quote(input, spans, message_mode)
|
||||
verb_say = dna.species.say_mod
|
||||
. = ..()
|
||||
if(src.slurring)
|
||||
input = attach_spans(input, spans)
|
||||
return "slurs, \"[input]\""
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/treat_message(message)
|
||||
message = dna.species.handle_speech(message,src)
|
||||
@@ -75,7 +73,7 @@
|
||||
if(!istype(dongle)) return 0
|
||||
if(dongle.translate_binary) return 1
|
||||
|
||||
/mob/living/carbon/human/radio(message, message_mode, list/spans)
|
||||
/mob/living/carbon/human/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
@@ -83,17 +81,17 @@
|
||||
switch(message_mode)
|
||||
if(MODE_HEADSET)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, , spans)
|
||||
ears.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_DEPARTMENT)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(message_mode in radiochannels)
|
||||
if(message_mode in GLOB.radiochannels)
|
||||
if(ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
|
||||
var/face_y_offset = 0
|
||||
var/hair_y_offset = 0
|
||||
|
||||
var/hair_color = null // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
@@ -69,8 +73,6 @@
|
||||
var/fixed_mut_color3 = ""
|
||||
var/whitelisted = 0 //Is this species restricted to certain players?
|
||||
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
|
||||
var/lang_spoken = HUMAN
|
||||
var/lang_understood = HUMAN
|
||||
|
||||
///////////
|
||||
// PROCS //
|
||||
@@ -90,21 +92,21 @@
|
||||
|
||||
var/randname
|
||||
if(gender == MALE)
|
||||
randname = pick(first_names_male)
|
||||
randname = pick(GLOB.first_names_male)
|
||||
else
|
||||
randname = pick(first_names_female)
|
||||
randname = pick(GLOB.first_names_female)
|
||||
|
||||
if(lastname)
|
||||
randname += " [lastname]"
|
||||
else
|
||||
randname += " [pick(last_names)]"
|
||||
randname += " [pick(GLOB.last_names)]"
|
||||
|
||||
return randname
|
||||
|
||||
|
||||
//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)
|
||||
if(rank in command_positions)
|
||||
if(rank in GLOB.command_positions)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -205,7 +207,7 @@
|
||||
facialhair_hidden = TRUE
|
||||
|
||||
if(H.facial_hair_style && (FACEHAIR in species_traits) && (!facialhair_hidden || dynamic_fhair_suffix))
|
||||
S = facial_hair_styles_list[H.facial_hair_style]
|
||||
S = GLOB.facial_hair_styles_list[H.facial_hair_style]
|
||||
if(S)
|
||||
|
||||
//List of all valid dynamic_fhair_suffixes
|
||||
@@ -262,7 +264,7 @@
|
||||
standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained", "layer" = -HAIR_LAYER)
|
||||
|
||||
else if(H.hair_style && (HAIR in species_traits))
|
||||
S = hair_styles_list[H.hair_style]
|
||||
S = GLOB.hair_styles_list[H.hair_style]
|
||||
if(S)
|
||||
|
||||
//List of all valid dynamic_hair_suffixes
|
||||
@@ -295,6 +297,7 @@
|
||||
img_hair.color = forced_colour
|
||||
img_hair.alpha = hair_alpha
|
||||
|
||||
img_hair.pixel_y += hair_y_offset
|
||||
standing += img_hair
|
||||
|
||||
if(standing.len)
|
||||
@@ -311,33 +314,36 @@
|
||||
|
||||
|
||||
// eyes
|
||||
var/has_eyes = (H.getorgan(/obj/item/organ/eyes) && HD)
|
||||
var/has_eyes = TRUE
|
||||
|
||||
if(!has_eyes)
|
||||
if(!H.getorgan(/obj/item/organ/eyes) && HD)
|
||||
standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "eyes_missing", "layer" = -BODY_LAYER)
|
||||
has_eyes = FALSE
|
||||
|
||||
if(!HUSK)
|
||||
if(!(H.disabilities & HUSK))
|
||||
// lipstick
|
||||
if(H.lip_style && (LIPS in species_traits) && HD)
|
||||
var/image/lips = image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[H.lip_style]", "layer" = -BODY_LAYER)
|
||||
lips.color = H.lip_color
|
||||
lips.pixel_y += face_y_offset
|
||||
standing += lips
|
||||
|
||||
// eyes
|
||||
if((EYECOLOR in species_traits) && HD && has_eyes)
|
||||
var/image/img_eyes = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes", "layer" = -BODY_LAYER)
|
||||
img_eyes.color = "#" + H.eye_color
|
||||
img_eyes.pixel_y += face_y_offset
|
||||
standing += img_eyes
|
||||
|
||||
//Underwear, Undershirts & Socks
|
||||
/*This will be refactored at a later date
|
||||
if(H.underwear)
|
||||
var/datum/sprite_accessory/underwear/underwear = underwear_list[H.underwear]
|
||||
var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear]
|
||||
if(underwear)
|
||||
standing += image("icon"=underwear.icon, "icon_state"="[underwear.icon_state]", "layer"=-BODY_LAYER)
|
||||
|
||||
if(H.undershirt)
|
||||
var/datum/sprite_accessory/undershirt/undershirt = undershirt_list[H.undershirt]
|
||||
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt]
|
||||
if(undershirt)
|
||||
if(H.dna.species.sexes && H.gender == FEMALE)
|
||||
standing += wear_female_version("[undershirt.icon_state]", undershirt.icon, BODY_LAYER)
|
||||
@@ -345,7 +351,7 @@
|
||||
standing += image("icon"=undershirt.icon, "icon_state"="[undershirt.icon_state]", "layer"=-BODY_LAYER)
|
||||
|
||||
if(H.socks && H.get_num_legs() >= 2 && !(DIGITIGRADE in species_traits))
|
||||
var/datum/sprite_accessory/socks/socks = socks_list[H.socks]
|
||||
var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks]
|
||||
if(socks)
|
||||
standing += image("icon"=socks.icon, "icon_state"="[socks.icon_state]", "layer"=-BODY_LAYER)
|
||||
*/
|
||||
@@ -495,53 +501,53 @@
|
||||
var/datum/sprite_accessory/S
|
||||
switch(bodypart)
|
||||
if("tail_lizard")
|
||||
S = tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
S = GLOB.tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("waggingtail_lizard")
|
||||
S.= animated_tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
S.= GLOB.animated_tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("tail_human")
|
||||
S = tails_list_human[H.dna.features["tail_human"]]
|
||||
S = GLOB.tails_list_human[H.dna.features["tail_human"]]
|
||||
if("waggingtail_human")
|
||||
S.= animated_tails_list_human[H.dna.features["tail_human"]]
|
||||
S.= GLOB.animated_tails_list_human[H.dna.features["tail_human"]]
|
||||
if("spines")
|
||||
S = spines_list[H.dna.features["spines"]]
|
||||
S = GLOB.spines_list[H.dna.features["spines"]]
|
||||
if("waggingspines")
|
||||
S.= animated_spines_list[H.dna.features["spines"]]
|
||||
S.= GLOB.animated_spines_list[H.dna.features["spines"]]
|
||||
if("snout")
|
||||
S = snouts_list[H.dna.features["snout"]]
|
||||
S = GLOB.snouts_list[H.dna.features["snout"]]
|
||||
if("frills")
|
||||
S = frills_list[H.dna.features["frills"]]
|
||||
S = GLOB.frills_list[H.dna.features["frills"]]
|
||||
if("horns")
|
||||
S = horns_list[H.dna.features["horns"]]
|
||||
S = GLOB.horns_list[H.dna.features["horns"]]
|
||||
if("ears")
|
||||
S = ears_list[H.dna.features["ears"]]
|
||||
S = GLOB.ears_list[H.dna.features["ears"]]
|
||||
if("body_markings")
|
||||
S = body_markings_list[H.dna.features["body_markings"]]
|
||||
S = GLOB.body_markings_list[H.dna.features["body_markings"]]
|
||||
if("wings")
|
||||
S = wings_list[H.dna.features["wings"]]
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = wings_open_list[H.dna.features["wings"]]
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("legs")
|
||||
S = legs_list[H.dna.features["legs"]]
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
|
||||
//Mammal Bodyparts (Canid/Felid, others maybe in the future)
|
||||
if("mam_tail")
|
||||
S = mam_tails_list[H.dna.features["mam_tail"]]
|
||||
S = GLOB.mam_tails_list[H.dna.features["mam_tail"]]
|
||||
if("mam_waggingtail")
|
||||
S.= mam_tails_animated_list[H.dna.features["mam_tail"]]
|
||||
S.= GLOB.mam_tails_animated_list[H.dna.features["mam_tail"]]
|
||||
if("mam_body_markings")
|
||||
S = mam_body_markings_list[H.dna.features["mam_body_markings"]]
|
||||
S = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]]
|
||||
if("mam_ears")
|
||||
S = mam_ears_list[H.dna.features["mam_ears"]]
|
||||
S = GLOB.mam_ears_list[H.dna.features["mam_ears"]]
|
||||
if("taur")
|
||||
S = taur_list[H.dna.features["taur"]]
|
||||
S = GLOB.taur_list[H.dna.features["taur"]]
|
||||
|
||||
//Xeno Bodyparts
|
||||
if("xenodorsal")
|
||||
S = xeno_dorsal_list[H.dna.features["xenodorsal"]]
|
||||
S = GLOB.xeno_dorsal_list[H.dna.features["xenodorsal"]]
|
||||
if("xenohead")
|
||||
S = xeno_head_list[H.dna.features["xenohead"]]
|
||||
S = GLOB.xeno_head_list[H.dna.features["xenohead"]]
|
||||
if("xenotail")
|
||||
S = xeno_tail_list[H.dna.features["xenotail"]]
|
||||
S = GLOB.xeno_tail_list[H.dna.features["xenotail"]]
|
||||
|
||||
//Slimecoon Bodyparts
|
||||
/* if("slimecoontail")
|
||||
@@ -1035,6 +1041,8 @@
|
||||
return 1
|
||||
|
||||
/datum/species/proc/go_bald(mob/living/carbon/human/H)
|
||||
if(QDELETED(H)) //may be called from a timer
|
||||
return
|
||||
H.facial_hair_style = "Shaved"
|
||||
H.hair_style = "Bald"
|
||||
H.update_hair()
|
||||
@@ -1198,9 +1206,9 @@
|
||||
target.visible_message("<span class='danger'>[user] has weakened [target]!</span>", \
|
||||
"<span class='userdanger'>[user] has weakened [target]!</span>")
|
||||
target.apply_effect(4, WEAKEN, armor_block)
|
||||
target.forcesay(hit_appends)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
else if(target.lying)
|
||||
target.forcesay(hit_appends)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
|
||||
|
||||
|
||||
@@ -1223,7 +1231,6 @@
|
||||
return 1
|
||||
else
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
add_logs(user, target, "disarmed")
|
||||
|
||||
if(target.w_uniform)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
@@ -1234,24 +1241,26 @@
|
||||
target.visible_message("<span class='danger'>[user] has pushed [target]!</span>",
|
||||
"<span class='userdanger'>[user] has pushed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
|
||||
target.forcesay(hit_appends)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
add_logs(user, target, "disarmed", " pushing them to the ground")
|
||||
|
||||
return
|
||||
|
||||
var/talked = 0 // BubbleWrap
|
||||
|
||||
if(randn <= 60)
|
||||
//BubbleWrap: Disarming breaks a pull
|
||||
var/obj/item/I = null
|
||||
if(target.pulling)
|
||||
to_chat(target, "<span class='warning'>[user] has broken [target]'s grip on [target.pulling]!</span>")
|
||||
talked = 1
|
||||
target.stop_pulling()
|
||||
//End BubbleWrap
|
||||
|
||||
if(!talked) //BubbleWrap
|
||||
else
|
||||
I = target.get_active_held_item()
|
||||
if(target.drop_item())
|
||||
target.visible_message("<span class='danger'>[user] has disarmed [target]!</span>", \
|
||||
"<span class='userdanger'>[user] has disarmed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
I = null
|
||||
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(user, target, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
return
|
||||
|
||||
|
||||
@@ -1347,7 +1356,7 @@
|
||||
H.adjust_blurriness(10)
|
||||
|
||||
if(prob(I.force + ((100 - H.health)/2)) && H != user)
|
||||
ticker.mode.remove_revolutionary(H.mind)
|
||||
SSticker.mode.remove_revolutionary(H.mind)
|
||||
|
||||
if(bloody) //Apply blood
|
||||
if(H.wear_mask)
|
||||
@@ -1376,7 +1385,7 @@
|
||||
H.update_inv_w_uniform()
|
||||
|
||||
if(Iforce > 10 || Iforce >= 5 && prob(33))
|
||||
H.forcesay(hit_appends) //forcesay checks stat already.
|
||||
H.forcesay(GLOB.hit_appends) //forcesay checks stat already.
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
|
||||
@@ -1480,7 +1489,7 @@
|
||||
H.apply_damage(HEAT_DAMAGE_LEVEL_3*heatmod, BURN)
|
||||
else
|
||||
H.apply_damage(HEAT_DAMAGE_LEVEL_2*heatmod, BURN)
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !(mutations_list[COLDRES] in H.dna.mutations))
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !(GLOB.mutations_list[COLDRES] in H.dna.mutations))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to 260)
|
||||
H.throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
|
||||
@@ -14,6 +14,8 @@ datum/species/mammal
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/mammal/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//AVIAN//
|
||||
/datum/species/avian
|
||||
@@ -32,6 +34,9 @@ datum/species/mammal
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/avian/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//AQUATIC//
|
||||
/datum/species/aquatic
|
||||
name = "Aquatic"
|
||||
@@ -48,6 +53,10 @@ datum/species/mammal
|
||||
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/aquatic/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//INSECT//
|
||||
/datum/species/insect
|
||||
name = "Insect"
|
||||
@@ -65,6 +74,8 @@ datum/species/mammal
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/insect/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
//HERBIVOROUS//
|
||||
|
||||
//EXOTIC//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/species/golem
|
||||
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
|
||||
name = "Golem"
|
||||
id = "iron"
|
||||
id = "iron golem"
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
|
||||
speedmod = 2
|
||||
armor = 55
|
||||
@@ -12,6 +12,7 @@
|
||||
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform)
|
||||
nojumpsuit = 1
|
||||
sexes = 1
|
||||
damage_overlay_type = ""
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem
|
||||
// To prevent golem subtypes from overwhelming the odds when random species
|
||||
// changes, only the Random Golem type can be chosen
|
||||
@@ -21,6 +22,21 @@
|
||||
fixed_mut_color = "aaa"
|
||||
var/info_text = "As an <span class='danger'>Iron Golem</span>, you don't have any special traits."
|
||||
|
||||
var/prefix = "Iron"
|
||||
var/list/special_names
|
||||
|
||||
/datum/species/golem/random_name(gender,unique,lastname)
|
||||
var/golem_surname = pick(GLOB.golem_names)
|
||||
// 3% chance that our golem has a human surname, because
|
||||
// cultural contamination
|
||||
if(prob(3))
|
||||
golem_surname = pick(GLOB.last_names)
|
||||
else if(special_names && prob(5))
|
||||
golem_surname = pick(special_names)
|
||||
|
||||
var/golem_name = "[prefix] [golem_surname]"
|
||||
return golem_name
|
||||
|
||||
/datum/species/golem/random
|
||||
name = "Random Golem"
|
||||
blacklisted = FALSE
|
||||
@@ -36,21 +52,24 @@
|
||||
|
||||
/datum/species/golem/adamantine
|
||||
name = "Adamantine Golem"
|
||||
id = "adamantine"
|
||||
id = "adamantine golem"
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
|
||||
fixed_mut_color = "4ed"
|
||||
info_text = "As an <span class='danger'>Adamantine Golem</span>, you don't have any special traits."
|
||||
prefix = "Adamantine"
|
||||
|
||||
//Explodes on death
|
||||
/datum/species/golem/plasma
|
||||
name = "Plasma Golem"
|
||||
id = "plasma"
|
||||
id = "plasma golem"
|
||||
fixed_mut_color = "a3d"
|
||||
meat = /obj/item/weapon/ore/plasma
|
||||
//Can burn and takes damage from heat
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
|
||||
info_text = "As a <span class='danger'>Plasma Golem</span>, you explode on death!"
|
||||
burnmod = 1.5
|
||||
prefix = "Plasma"
|
||||
special_names = list("Flood","Fire","Bar","Man")
|
||||
|
||||
/datum/species/golem/plasma/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
explosion(get_turf(H),0,1,2,flame_range = 5)
|
||||
@@ -60,35 +79,40 @@
|
||||
//Harder to hurt
|
||||
/datum/species/golem/diamond
|
||||
name = "Diamond Golem"
|
||||
id = "diamond"
|
||||
id = "diamond golem"
|
||||
fixed_mut_color = "0ff"
|
||||
armor = 70 //up from 55
|
||||
meat = /obj/item/weapon/ore/diamond
|
||||
info_text = "As a <span class='danger'>Diamond Golem</span>, you are more resistant than the average golem."
|
||||
prefix = "Diamond"
|
||||
special_names = list("Back")
|
||||
|
||||
//Faster but softer and less armoured
|
||||
/datum/species/golem/gold
|
||||
name = "Gold Golem"
|
||||
id = "gold"
|
||||
id = "gold golem"
|
||||
fixed_mut_color = "cc0"
|
||||
speedmod = 1
|
||||
armor = 25 //down from 55
|
||||
meat = /obj/item/weapon/ore/gold
|
||||
info_text = "As a <span class='danger'>Gold Golem</span>, you are faster but less resistant than the average golem."
|
||||
prefix = "Golden"
|
||||
|
||||
//Heavier, thus higher chance of stunning when punching
|
||||
/datum/species/golem/silver
|
||||
name = "Silver Golem"
|
||||
id = "silver"
|
||||
id = "silver golem"
|
||||
fixed_mut_color = "ddd"
|
||||
punchstunthreshold = 9 //60% chance, from 40%
|
||||
meat = /obj/item/weapon/ore/silver
|
||||
info_text = "As a <span class='danger'>Silver Golem</span>, your attacks are heavier and have a higher chance of stunning."
|
||||
prefix = "Silver"
|
||||
special_names = list("Surfer", "Chariot", "Lining")
|
||||
|
||||
//Harder to stun, deals more damage, but it's even slower
|
||||
/datum/species/golem/plasteel
|
||||
name = "Plasteel Golem"
|
||||
id = "plasteel"
|
||||
id = "plasteel golem"
|
||||
fixed_mut_color = "bbb"
|
||||
stunmod = 0.40
|
||||
punchdamagelow = 12
|
||||
@@ -99,15 +123,17 @@
|
||||
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
|
||||
attack_verb = "smash"
|
||||
attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard
|
||||
prefix = "Plasteel"
|
||||
|
||||
//Immune to ash storms
|
||||
/datum/species/golem/titanium
|
||||
name = "Titanium Golem"
|
||||
id = "titanium"
|
||||
id = "titanium golem"
|
||||
fixed_mut_color = "fff"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
info_text = "As a <span class='danger'>Titanium Golem</span>, you are immune to ash storms, and slightly more resistant to burn damage."
|
||||
burnmod = 0.9
|
||||
prefix = "Titanium"
|
||||
|
||||
/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
@@ -120,11 +146,12 @@
|
||||
//Immune to ash storms and lava
|
||||
/datum/species/golem/plastitanium
|
||||
name = "Plastitanium Golem"
|
||||
id = "plastitanium"
|
||||
id = "plastitanium golem"
|
||||
fixed_mut_color = "888"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
info_text = "As a <span class='danger'>Plastitanium Golem</span>, you are immune to both ash storms and lava, and slightly more resistant to burn damage."
|
||||
burnmod = 0.8
|
||||
prefix = "Plastitanium"
|
||||
|
||||
/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
@@ -139,12 +166,14 @@
|
||||
//Fast and regenerates... but can only speak like an abductor
|
||||
/datum/species/golem/alloy
|
||||
name = "Alien Alloy Golem"
|
||||
id = "alloy"
|
||||
id = "alloy golem"
|
||||
fixed_mut_color = "333"
|
||||
meat = /obj/item/stack/sheet/mineral/abductor
|
||||
mutant_organs = list(/obj/item/organ/tongue/abductor) //abductor tongue
|
||||
speedmod = 1 //faster
|
||||
info_text = "As an <span class='danger'>Alloy Golem</span>, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems."
|
||||
prefix = "Alien"
|
||||
special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown
|
||||
|
||||
//Regenerates because self-repairing super-advanced alien tech
|
||||
/datum/species/golem/alloy/spec_life(mob/living/carbon/human/H)
|
||||
@@ -157,7 +186,7 @@
|
||||
//Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races
|
||||
/datum/species/golem/wood
|
||||
name = "Wood Golem"
|
||||
id = "wood"
|
||||
id = "wood golem"
|
||||
fixed_mut_color = "49311c"
|
||||
meat = /obj/item/stack/sheet/mineral/wood
|
||||
//Can burn and take damage from heat
|
||||
@@ -166,6 +195,13 @@
|
||||
burnmod = 1.25
|
||||
heatmod = 1.5
|
||||
info_text = "As a <span class='danger'>Wooden Golem</span>, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness."
|
||||
prefix = "Wooden"
|
||||
|
||||
/datum/species/golem/wood/random_name(gender,unique,lastname)
|
||||
var/plant_name = pick("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", \
|
||||
"Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper")
|
||||
var/golem_name = "[prefix] [plant_name]"
|
||||
return golem_name
|
||||
|
||||
/datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
@@ -204,13 +240,14 @@
|
||||
//Radioactive
|
||||
/datum/species/golem/uranium
|
||||
name = "Uranium Golem"
|
||||
id = "uranium"
|
||||
id = "uranium golem"
|
||||
fixed_mut_color = "7f0"
|
||||
meat = /obj/item/weapon/ore/uranium
|
||||
info_text = "As an <span class='danger'>Uranium Golem</span>, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected."
|
||||
|
||||
var/last_event = 0
|
||||
var/active = null
|
||||
prefix = "Uranium"
|
||||
|
||||
/datum/species/golem/uranium/spec_life(mob/living/carbon/human/H)
|
||||
if(!active)
|
||||
@@ -224,7 +261,7 @@
|
||||
//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death.
|
||||
/datum/species/golem/sand
|
||||
name = "Sand Golem"
|
||||
id = "sand"
|
||||
id = "sand golem"
|
||||
fixed_mut_color = "ffdc8f"
|
||||
meat = /obj/item/weapon/ore/glass //this is sand
|
||||
armor = 0
|
||||
@@ -232,6 +269,7 @@
|
||||
brutemod = 0.25
|
||||
info_text = "As a <span class='danger'>Sand Golem</span>, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery."
|
||||
attack_sound = 'sound/effects/shovel_dig.ogg'
|
||||
prefix = "Sand"
|
||||
|
||||
/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='danger'>[H] turns into a pile of sand!</span>")
|
||||
@@ -253,7 +291,7 @@
|
||||
//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death.
|
||||
/datum/species/golem/glass
|
||||
name = "Glass Golem"
|
||||
id = "glass"
|
||||
id = "glass golem"
|
||||
fixed_mut_color = "5a96b4aa" //transparent body
|
||||
meat = /obj/item/weapon/shard
|
||||
armor = 0
|
||||
@@ -261,6 +299,7 @@
|
||||
burnmod = 0.25
|
||||
info_text = "As a <span class='danger'>Glass Golem</span>, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery."
|
||||
attack_sound = 'sound/effects/Glassbr2.ogg'
|
||||
prefix = "Glass"
|
||||
|
||||
/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
playsound(H, "shatter", 70, 1)
|
||||
@@ -295,12 +334,14 @@
|
||||
//Teleports when hit or when it wants to
|
||||
/datum/species/golem/bluespace
|
||||
name = "Bluespace Golem"
|
||||
id = "bluespace"
|
||||
id = "bluespace golem"
|
||||
fixed_mut_color = "33f"
|
||||
meat = /obj/item/weapon/ore/bluespace_crystal
|
||||
info_text = "As a <span class='danger'>Bluespace Golem</span>, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance."
|
||||
attack_verb = "bluespace punch"
|
||||
attack_sound = 'sound/effects/phasein.ogg'
|
||||
prefix = "Bluespace"
|
||||
special_names = list("Crystal", "Polycrystal")
|
||||
|
||||
var/datum/action/innate/unstable_teleport/unstable_teleport
|
||||
var/teleport_cooldown = 100
|
||||
@@ -384,7 +425,7 @@
|
||||
//honk
|
||||
/datum/species/golem/bananium
|
||||
name = "Bananium Golem"
|
||||
id = "bananium"
|
||||
id = "bananium golem"
|
||||
fixed_mut_color = "ff0"
|
||||
say_mod = "honks"
|
||||
punchdamagelow = 0
|
||||
@@ -394,6 +435,7 @@
|
||||
info_text = "As a <span class='danger'>Bananium Golem</span>, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
|
||||
attack_verb = "honk"
|
||||
attack_sound = 'sound/items/AirHorn2.ogg'
|
||||
prefix = "Bananium"
|
||||
|
||||
var/last_honk = 0
|
||||
var/honkooldown = 0
|
||||
@@ -401,6 +443,11 @@
|
||||
var/banana_cooldown = 100
|
||||
var/active = null
|
||||
|
||||
/datum/species/golem/bananium/random_name(gender,unique,lastname)
|
||||
var/clown_name = pick(GLOB.clown_names)
|
||||
var/golem_name = "[uppertext(clown_name)]"
|
||||
return golem_name
|
||||
|
||||
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
|
||||
@@ -449,7 +496,7 @@
|
||||
|
||||
/datum/species/golem/runic
|
||||
name = "Runic Golem"
|
||||
id = "runic"
|
||||
id = "runic golem"
|
||||
limbs_id = "cultgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder God Nar'Sie."
|
||||
@@ -459,6 +506,12 @@
|
||||
var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze
|
||||
var/obj/effect/proc_holder/spell/targeted/dominate/dominate
|
||||
|
||||
/datum/species/golem/runic/random_name(gender,unique,lastname)
|
||||
var/edgy_first_name = pick("Razor","Blood","Dark","Evil","Cold","Pale","Black","Silent","Chaos","Deadly")
|
||||
var/edgy_last_name = pick("Edge","Night","Death","Razor","Blade","Steel","Calamity","Twilight","Shadow","Nightmare") //dammit Razor Razor
|
||||
var/golem_name = "[edgy_first_name] [edgy_last_name]"
|
||||
return golem_name
|
||||
|
||||
/datum/species/golem/runic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.faction |= "cult"
|
||||
@@ -489,3 +542,100 @@
|
||||
H.adjustFireLoss(-4)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
|
||||
/datum/species/golem/cloth
|
||||
name = "Cloth Golem"
|
||||
id = "cloth golem"
|
||||
limbs_id = "clothgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Cloth Golem</span>, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable."
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER) //no mutcolors, and can burn
|
||||
armor = 15 //feels no pain, but not too resistant
|
||||
burnmod = 2 // don't get burned
|
||||
speedmod = 1 // not as heavy as stone
|
||||
punchdamagelow = 4
|
||||
punchstunthreshold = 7
|
||||
punchdamagehigh = 8 // not as heavy as stone
|
||||
prefix = "Cloth"
|
||||
|
||||
/datum/species/golem/cloth/random_name(gender,unique,lastname)
|
||||
var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \
|
||||
"Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh
|
||||
var/golem_name = "[pharaoh_name] \Roman[rand(1,99)]"
|
||||
return golem_name
|
||||
|
||||
/datum/species/golem/cloth/spec_life(mob/living/carbon/human/H)
|
||||
if(H.fire_stacks < 1)
|
||||
H.adjust_fire_stacks(1) //always prone to burning
|
||||
..()
|
||||
|
||||
/datum/species/golem/cloth/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(gibbed)
|
||||
return
|
||||
if(H.on_fire)
|
||||
H.visible_message("<span class='danger'>[H] burns into ash!</span>")
|
||||
H.dust(just_ash = TRUE)
|
||||
return
|
||||
|
||||
H.visible_message("<span class='danger'>[H] falls apart into a pile of bandages!</span>")
|
||||
new /obj/structure/cloth_pile(get_turf(H), H)
|
||||
..()
|
||||
|
||||
/obj/structure/cloth_pile
|
||||
name = "pile of bandages"
|
||||
desc = "It emits a strange aura, as if there was still life within it..."
|
||||
obj_integrity = 50
|
||||
max_integrity = 50
|
||||
armor = list(melee = 90, bullet = 90, laser = 25, energy = 80, bomb = 50, bio = 100, fire = -50, acid = -50)
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "pile_bandages"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
var/revive_time = 900
|
||||
var/mob/living/carbon/human/cloth_golem
|
||||
|
||||
/obj/structure/cloth_pile/Initialize(mapload, mob/living/carbon/human/H)
|
||||
if(!QDELETED(H) && is_species(H, /datum/species/golem/cloth))
|
||||
H.unequip_everything()
|
||||
H.forceMove(src)
|
||||
cloth_golem = H
|
||||
to_chat(cloth_golem, "<span class='notice'>You start gathering your life energy, preparing to rise again...</span>")
|
||||
addtimer(CALLBACK(src, .proc/revive), revive_time)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/cloth_pile/Destroy()
|
||||
if(cloth_golem)
|
||||
QDEL_NULL(cloth_golem)
|
||||
return ..()
|
||||
|
||||
/obj/structure/cloth_pile/burn()
|
||||
visible_message("<span class='danger'>[src] burns into ash!</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
..()
|
||||
|
||||
/obj/structure/cloth_pile/proc/revive()
|
||||
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
|
||||
return
|
||||
if(cloth_golem.suiciding || cloth_golem.disabilities & NOCLONE)
|
||||
QDEL_NULL(cloth_golem)
|
||||
return
|
||||
|
||||
invisibility = INVISIBILITY_MAXIMUM //disappear before the animation
|
||||
new /obj/effect/overlay/temp/mummy_animation(get_turf(src))
|
||||
if(cloth_golem.revive(full_heal = TRUE, admin_revive = TRUE))
|
||||
cloth_golem.grab_ghost() //won't pull if it's a suicide
|
||||
sleep(20)
|
||||
cloth_golem.forceMove(get_turf(src))
|
||||
cloth_golem.visible_message("<span class='danger'>[src] rises and reforms into [cloth_golem]!</span>","<span class='userdanger'>You reform into yourself!</span>")
|
||||
cloth_golem = null
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/cloth_pile/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params)
|
||||
. = ..()
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
return
|
||||
|
||||
if(P.is_hot())
|
||||
visible_message("<span class='danger'>[src] bursts into flames!</span>")
|
||||
fire_act()
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
if((!features["tail_human"] || features["tail_human"] == "None") && (!features["ears"] || features["ears"] == "None"))
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
//Curiosity killed the cat's wagging tail.
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
exotic_blood = "slimejelly"
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
@@ -226,7 +227,7 @@
|
||||
else
|
||||
ui_interact(owner)
|
||||
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = conscious_state)
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.conscious_state)
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,FACEHAIR)
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
|
||||
mutant_organs = list(/obj/item/organ/tongue/lizard)
|
||||
coldmod = 1.5
|
||||
heatmod = 0.67
|
||||
default_features = list("mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "taur" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
@@ -26,6 +28,9 @@
|
||||
|
||||
return randname
|
||||
|
||||
/datum/species/lizard/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//I wag in death
|
||||
/datum/species/lizard/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -38,4 +43,4 @@
|
||||
name = "Ash Walker"
|
||||
id = "ashlizard"
|
||||
limbs_id = "lizard"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,NOBREATH,NOGUNS,DIGITIGRADE)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,NOBREATH,NOGUNS,DIGITIGRADE)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_state"="plasmaman")
|
||||
|
||||
/datum/species/plasmaman
|
||||
name = "Plasmaman"
|
||||
id = "plasmaman"
|
||||
@@ -52,7 +50,7 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_
|
||||
return 0
|
||||
|
||||
/datum/species/plasmaman/qualifies_for_rank(rank, list/features)
|
||||
if(rank in security_positions)
|
||||
if(rank in GLOB.security_positions)
|
||||
return 0
|
||||
if(rank == "Clown" || rank == "Mime")//No funny bussiness
|
||||
return 0
|
||||
|
||||
@@ -99,7 +99,7 @@ There are several things that need to be remembered:
|
||||
/* --------------------------------------- */
|
||||
//vvvvvv UPDATE_INV PROCS vvvvvv
|
||||
|
||||
/mob/living/carbon/human/update_inv_w_uniform()
|
||||
/mob/living/carbon/human/update_inv_w_uniform(invdrop = TRUE)
|
||||
remove_overlay(UNIFORM_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
@@ -138,7 +138,7 @@ There are several things that need to be remembered:
|
||||
|
||||
overlays_standing[UNIFORM_LAYER] = standing
|
||||
|
||||
else if(!(dna && dna.species.nojumpsuit))
|
||||
else if(!(dna && dna.species.nojumpsuit) && invdrop)
|
||||
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
|
||||
for(var/obj/item/thing in list(r_store, l_store, wear_id, belt)) //
|
||||
dropItemToGround(thing)
|
||||
@@ -274,7 +274,7 @@ There are several things that need to be remembered:
|
||||
client.screen += shoes //add it to client's screen
|
||||
update_observer_view(shoes,1)
|
||||
var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi')
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
|
||||
apply_overlay(SHOES_LAYER)
|
||||
|
||||
@@ -392,10 +392,10 @@ There are several things that need to be remembered:
|
||||
|
||||
/proc/wear_female_version(t_color, icon, layer, type)
|
||||
var/index = t_color
|
||||
var/icon/female_clothing_icon = female_clothing_icons[index]
|
||||
var/icon/female_clothing_icon = GLOB.female_clothing_icons[index]
|
||||
if(!female_clothing_icon) //Create standing/laying icons if they don't exist
|
||||
generate_female_clothing(index,t_color,icon,type)
|
||||
var/standing = image("icon"=female_clothing_icons["[t_color]"], "layer"=-layer)
|
||||
var/standing = image("icon"=GLOB.female_clothing_icons["[t_color]"], "layer"=-layer)
|
||||
return(standing)
|
||||
|
||||
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
/mob/living/carbon/human/whisper(message as text)
|
||||
/mob/living/carbon/human/whisper_verb(message as text)
|
||||
whisper(message)
|
||||
|
||||
/mob/living/carbon/human/whisper(message, datum/language/language=null)
|
||||
if(!IsVocal())
|
||||
return
|
||||
if(!message)
|
||||
return
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
|
||||
@@ -44,9 +49,11 @@
|
||||
message = Ellipsis(message, 10, 1)
|
||||
|
||||
message = treat_message(message)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/list/listening_dead = list()
|
||||
for(var/mob/M in player_list)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTWHISPER) || (get_dist(M, src) <= 7)))
|
||||
listening_dead |= M
|
||||
|
||||
@@ -71,14 +78,14 @@
|
||||
for(var/atom/movable/AM in listening)
|
||||
if(istype(AM,/obj/item/device/radio))
|
||||
continue
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
AM.Hear(rendered, src, language, message, , spans)
|
||||
|
||||
message = stars(message)
|
||||
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] [whispers], <span class='message'>\"[attach_spans(message, spans)]\"</span></span>"
|
||||
for(var/atom/movable/AM in eavesdropping)
|
||||
if(istype(AM,/obj/item/device/radio))
|
||||
continue
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
AM.Hear(rendered, src, language, message, , spans)
|
||||
|
||||
if(critical) //Dying words.
|
||||
succumb(1)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
//Start of a breath chain, calls breathe()
|
||||
/mob/living/carbon/handle_breathing()
|
||||
if(SSmob.times_fired%4==2 || failed_last_breath)
|
||||
if(SSmobs.times_fired%4==2 || failed_last_breath)
|
||||
breathe() //Breathe per 4 ticks, unless suffocating
|
||||
else
|
||||
if(istype(loc, /obj/))
|
||||
@@ -47,8 +47,6 @@
|
||||
if(loc)
|
||||
environment = loc.return_air()
|
||||
|
||||
if(ismob(loc)) return
|
||||
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(health <= HEALTH_THRESHOLD_CRIT || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
|
||||
@@ -132,7 +130,7 @@
|
||||
if(prob(20))
|
||||
emote("gasp")
|
||||
if(O2_partialpressure > 0)
|
||||
var/ratio = safe_oxy_min/O2_partialpressure
|
||||
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
||||
adjustOxyLoss(min(5*ratio, 3))
|
||||
failed_last_breath = 1
|
||||
oxygen_used = breath_gases["o2"][MOLES]*ratio
|
||||
@@ -255,7 +253,7 @@
|
||||
dna.previous.Remove("blood_type")
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
continue
|
||||
HM = mutations_list[mut]
|
||||
HM = GLOB.mutations_list[mut]
|
||||
HM.force_lose(src)
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
|
||||
@@ -294,7 +292,7 @@
|
||||
stomach_contents.Remove(M)
|
||||
qdel(M)
|
||||
continue
|
||||
if(SSmob.times_fired%3==1)
|
||||
if(SSmobs.times_fired%3==1)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
var/pickpocketing = FALSE
|
||||
var/disposing_body = FALSE
|
||||
var/obj/machinery/disposal/bodyDisposal = null
|
||||
var/next_battle_screech = 0
|
||||
var/battle_screech_cooldown = 50
|
||||
|
||||
/mob/living/carbon/monkey/proc/IsStandingStill()
|
||||
return resisting || pickpocketing || disposing_body
|
||||
@@ -59,6 +61,12 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/monkey/proc/battle_screech()
|
||||
if(next_battle_screech < world.time)
|
||||
emote(pick("roar","screech"))
|
||||
for(var/mob/living/carbon/monkey/M in view(7,src))
|
||||
M.next_battle_screech = world.time + battle_screech_cooldown
|
||||
|
||||
/mob/living/carbon/monkey/proc/equip_item(var/obj/item/I)
|
||||
|
||||
if(I.loc == src)
|
||||
@@ -197,7 +205,7 @@
|
||||
for(var/mob/living/L in around)
|
||||
if( should_target(L) )
|
||||
if(L.stat == CONSCIOUS)
|
||||
emote(pick("roar","screech"))
|
||||
battle_screech()
|
||||
retaliate(L)
|
||||
return TRUE
|
||||
else if(bodyDisposal)
|
||||
@@ -241,7 +249,7 @@
|
||||
var/list/around = view(src, MONKEY_ENEMY_VISION)
|
||||
for(var/mob/living/carbon/monkey/M in around)
|
||||
if(M.mode == MONKEY_IDLE && prob(MONKEY_RECRUIT_PROB))
|
||||
M.emote(pick("roar","screech"))
|
||||
M.battle_screech()
|
||||
M.target = target
|
||||
M.mode = MONKEY_HUNT
|
||||
|
||||
@@ -406,7 +414,7 @@
|
||||
enemies[L] += MONKEY_HATRED_AMOUNT
|
||||
|
||||
if(a_intent != INTENT_HARM)
|
||||
emote(pick("roar","screech"))
|
||||
battle_screech()
|
||||
a_intent = INTENT_HARM
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/L)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(stat == CONSCIOUS)
|
||||
if(!handle_combat())
|
||||
if(prob(33) && canmove && isturf(loc) && !pulledby)
|
||||
step(src, pick(cardinal))
|
||||
step(src, pick(GLOB.cardinal))
|
||||
if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
else
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
name = "monkey"
|
||||
voice_name = "monkey"
|
||||
verb_say = "chimpers"
|
||||
initial_languages = list(/datum/language/monkey)
|
||||
icon = 'icons/mob/monkey.dmi'
|
||||
icon_state = ""
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
languages_spoken = MONKEY
|
||||
languages_understood = MONKEY
|
||||
ventcrawler = VENTCRAWLER_NUDE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
unique_name = 1
|
||||
devourable = 1
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
|
||||
@@ -160,4 +158,4 @@
|
||||
if(prob(10))
|
||||
var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src)
|
||||
equip_to_slot_or_del(helmet,slot_head)
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
|
||||
@@ -117,26 +117,33 @@
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
if (M.a_intent == INTENT_DISARM)
|
||||
var/obj/item/I = null
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Weaken(10)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
I = get_active_held_item()
|
||||
if(drop_item())
|
||||
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "disarmed")
|
||||
else
|
||||
I = null//did not manage to actually disarm the item, gross but no time to refactor
|
||||
|
||||
add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "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("chest")
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/Life()
|
||||
if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
if(SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory(0)
|
||||
..()
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/monkey/update_hud_neck(obj/item/I)
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
I.screen_loc = ui_monkey_mask
|
||||
I.screen_loc = ui_monkey_neck
|
||||
client.screen += I
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
|
||||
@@ -28,3 +28,15 @@
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
. |= I.get_held_item_speechspans(src)
|
||||
|
||||
/mob/living/carbon/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(has_language(dt))
|
||||
var/obj/item/organ/tongue/T = getorganslot("tongue")
|
||||
if(T)
|
||||
. = T.can_speak_in_language(dt)
|
||||
else
|
||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
||||
else
|
||||
. = FALSE
|
||||
|
||||
@@ -276,12 +276,6 @@
|
||||
See RemieRichards on irc.rizon.net #coderbus
|
||||
*/
|
||||
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/mob/living/carbon
|
||||
var/icon_render_key = ""
|
||||
|
||||
|
||||
//produces a key based on the mob's limbs
|
||||
|
||||
/mob/living/carbon/proc/generate_icon_render_key()
|
||||
|
||||
@@ -26,20 +26,20 @@
|
||||
/mob/living/proc/spread_bodyparts()
|
||||
return
|
||||
|
||||
/mob/living/dust()
|
||||
/mob/living/dust(just_ash = FALSE)
|
||||
death(1)
|
||||
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
|
||||
dust_animation()
|
||||
spawn_dust()
|
||||
spawn_dust(just_ash)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/proc/dust_animation()
|
||||
return
|
||||
|
||||
/mob/living/proc/spawn_dust()
|
||||
/mob/living/proc/spawn_dust(just_ash = FALSE)
|
||||
new /obj/effect/decal/cleanable/ash(loc)
|
||||
|
||||
|
||||
@@ -55,9 +55,9 @@
|
||||
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
|
||||
if(mind)
|
||||
mind.store_memory("Time of death: [tod]", 0)
|
||||
living_mob_list -= src
|
||||
GLOB.living_mob_list -= src
|
||||
if(!gibbed)
|
||||
dead_mob_list += src
|
||||
GLOB.dead_mob_list += src
|
||||
paralysis = 0
|
||||
stunned = 0
|
||||
weakened = 0
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
param = copytext(act, custom_param + 1, length(act) + 1)
|
||||
act = copytext(act, 1, custom_param)
|
||||
|
||||
var/datum/emote/E = emote_list[act]
|
||||
var/datum/emote/E
|
||||
E = E.emote_list[act]
|
||||
if(!E)
|
||||
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
|
||||
return
|
||||
@@ -426,10 +427,12 @@
|
||||
var/list/keys = list()
|
||||
var/list/message = list("Available emotes, you can use them with say \"*emote\": ")
|
||||
|
||||
var/datum/emote/E
|
||||
var/list/emote_list = E.emote_list
|
||||
for(var/e in emote_list)
|
||||
if(e in keys)
|
||||
continue
|
||||
var/datum/emote/E = emote_list[e]
|
||||
E = emote_list[e]
|
||||
if(E.can_run_emote(user, TRUE))
|
||||
keys += E.key
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
return
|
||||
if(!loc)
|
||||
if(client)
|
||||
for(var/obj/effect/landmark/error/E in landmarks_list)
|
||||
for(var/obj/effect/landmark/error/E in GLOB.landmarks_list)
|
||||
loc = E.loc
|
||||
break
|
||||
message_admins("[key_name_admin(src)] was found to have no .loc with an attached client, if the cause is unknown it would be wise to ask how this was accomplished.")
|
||||
@@ -40,9 +40,6 @@
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
// Vore code for belly processes
|
||||
handle_internal_contents()
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
|
||||
if(machine)
|
||||
@@ -70,7 +67,7 @@
|
||||
if(!digitaldisguise)
|
||||
src.digitaldisguise = image(loc = src)
|
||||
src.digitaldisguise.override = 1
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
|
||||
AI.client.images |= src.digitaldisguise
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
. = ..()
|
||||
generateStaticOverlay()
|
||||
if(staticOverlays.len)
|
||||
for(var/mob/living/simple_animal/drone/D in player_list)
|
||||
for(var/mob/living/simple_animal/drone/D in GLOB.player_list)
|
||||
if(D && D.seeStatic)
|
||||
if(D.staticChoice in staticOverlays)
|
||||
D.staticOverlays |= staticOverlays[D.staticChoice]
|
||||
@@ -13,10 +13,12 @@
|
||||
if(unique_name)
|
||||
name = "[name] ([rand(1, 1000)])"
|
||||
real_name = name
|
||||
var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
medhud.add_to_hud(src)
|
||||
faction += "\ref[src]"
|
||||
|
||||
language_menu = new(src)
|
||||
|
||||
|
||||
/mob/living/prepare_huds()
|
||||
..()
|
||||
@@ -33,7 +35,7 @@
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
QDEL_NULL(riding_datum)
|
||||
|
||||
for(var/mob/living/simple_animal/drone/D in player_list)
|
||||
for(var/mob/living/simple_animal/drone/D in GLOB.player_list)
|
||||
for(var/image/I in staticOverlays)
|
||||
D.staticOverlays.Remove(I)
|
||||
D.client.images.Remove(I)
|
||||
@@ -41,6 +43,8 @@
|
||||
staticOverlays.len = 0
|
||||
remove_from_all_data_huds()
|
||||
|
||||
QDEL_NULL(language_menu)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/ghostize(can_reenter_corpse = 1)
|
||||
@@ -342,8 +346,8 @@
|
||||
if(full_heal)
|
||||
fully_heal(admin_revive)
|
||||
if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain)
|
||||
dead_mob_list -= src
|
||||
living_mob_list += src
|
||||
GLOB.dead_mob_list -= src
|
||||
GLOB.living_mob_list += src
|
||||
suiciding = 0
|
||||
stat = UNCONSCIOUS //the mob starts unconscious,
|
||||
blind_eyes(1)
|
||||
@@ -480,7 +484,7 @@
|
||||
newdir = NORTH
|
||||
else if(newdir == 12) //E + W
|
||||
newdir = EAST
|
||||
if((newdir in cardinal) && (prob(50)))
|
||||
if((newdir in GLOB.cardinal) && (prob(50)))
|
||||
newdir = turn(get_dir(T, src.loc), 180)
|
||||
if(!blood_exists)
|
||||
new /obj/effect/decal/cleanable/trail_holder(src.loc)
|
||||
@@ -546,9 +550,6 @@
|
||||
if(buckled && last_special <= world.time)
|
||||
resist_buckle()
|
||||
|
||||
// climbing out of a gut
|
||||
if(attempt_vr(src,"vore_process_resist",args)) return TRUE
|
||||
|
||||
//Breaking out of a container (Locker, sleeper, cryo...)
|
||||
else if(isobj(loc))
|
||||
var/obj/C = loc
|
||||
@@ -598,7 +599,7 @@
|
||||
return name
|
||||
|
||||
/mob/living/update_gravity(has_gravity,override = 0)
|
||||
if(!ticker || !ticker.mode)
|
||||
if(!SSticker || !SSticker.mode)
|
||||
return
|
||||
if(has_gravity)
|
||||
clear_alert("weightless")
|
||||
@@ -668,7 +669,8 @@
|
||||
if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE))
|
||||
if(temporarilyRemoveItemFromInventory(what))
|
||||
if(where_list)
|
||||
who.put_in_hand(what, where_list[2])
|
||||
if(!who.put_in_hand(what, where_list[2]))
|
||||
what.forceMove(get_turf(who))
|
||||
else
|
||||
who.equip_to_slot(what, where, TRUE)
|
||||
|
||||
@@ -725,14 +727,14 @@
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
if(ticker && ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(SSticker && SSticker.mode)
|
||||
for(var/datum/gang/G in SSticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = ticker.mode
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||
stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/living/cancel_camera()
|
||||
..()
|
||||
@@ -802,9 +804,6 @@
|
||||
setStaminaLoss(health - 2)
|
||||
update_health_hud()
|
||||
|
||||
/mob/proc/update_sight()
|
||||
return
|
||||
|
||||
/mob/living/proc/owns_soul()
|
||||
if(mind)
|
||||
return mind.soulOwner == mind
|
||||
@@ -910,13 +909,14 @@
|
||||
|
||||
// used by secbot and monkeys Crossed
|
||||
/mob/living/proc/knockOver(var/mob/living/carbon/C)
|
||||
C.visible_message("<span class='warning'>[pick( \
|
||||
"[C] dives out of [src]'s way!", \
|
||||
"[C] stumbles over [src]!", \
|
||||
"[C] jumps out of [src]'s path!", \
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
if(C.key) //save us from monkey hordes
|
||||
C.visible_message("<span class='warning'>[pick( \
|
||||
"[C] dives out of [src]'s way!", \
|
||||
"[C] stumbles over [src]!", \
|
||||
"[C] jumps out of [src]'s path!", \
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
C.Weaken(2)
|
||||
|
||||
/mob/living/post_buckle_mob(mob/living/M)
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src || anchored)
|
||||
if(user == src || anchored || !isturf(user.loc))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src)
|
||||
user.start_pulling(src, supress_message)
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
|
||||
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
if(!SSticker || !SSticker.mode)
|
||||
to_chat(M, "You cannot attack people before the game has started.")
|
||||
return
|
||||
|
||||
@@ -244,10 +244,6 @@
|
||||
return 0
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
to_chat(M, "No attacking people at spawn, you jackass.")
|
||||
return 0
|
||||
|
||||
switch(M.a_intent)
|
||||
if ("help")
|
||||
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/mob/living
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
sight = 0
|
||||
see_in_dark = 2
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD)
|
||||
@@ -74,4 +72,7 @@
|
||||
var/list/implants = null
|
||||
var/tesla_ignore = FALSE
|
||||
|
||||
var/datum/riding/riding_datum
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
var/datum/language_menu/language_menu
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
mind.show_memory(src, 0)
|
||||
|
||||
//Round specific stuff
|
||||
if(ticker && ticker.mode)
|
||||
switch(ticker.mode.name)
|
||||
if(SSticker && SSticker.mode)
|
||||
switch(SSticker.mode.name)
|
||||
if("sandbox")
|
||||
CanBuild()
|
||||
|
||||
|
||||
+198
-100
@@ -1,70 +1,69 @@
|
||||
var/list/department_radio_keys = list(
|
||||
":r" = "right hand", "#r" = "right hand", ".r" = "right hand",
|
||||
":l" = "left hand", "#l" = "left hand", ".l" = "left hand",
|
||||
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", "#h" = "department", ".h" = "department",
|
||||
":c" = "Command", "#c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", "#n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering",
|
||||
":s" = "Security", "#s" = "Security", ".s" = "Security",
|
||||
":w" = "whisper", "#w" = "whisper", ".w" = "whisper",
|
||||
":b" = "binary", "#b" = "binary", ".b" = "binary",
|
||||
":a" = "alientalk", "#a" = "alientalk", ".a" = "alientalk",
|
||||
":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate",
|
||||
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", "#v" = "Service", ".v" = "Service",
|
||||
":o" = "AI Private", "#o" = "AI Private", ".o" = "AI Private",
|
||||
":g" = "changeling", "#g" = "changeling", ".g" = "changeling",
|
||||
":y" = "Centcom", "#y" = "Centcom", ".y" = "Centcom",
|
||||
":x" = "cords", "#x" = "cords", ".x" = "cords",
|
||||
":p" = "admin", "#p" = "admin", ".p" = "admin",
|
||||
":d" = "deadmin", "#d" = "deadmin", ".d" = "deadmin",
|
||||
GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
":r" = "right hand", ".r" = "right hand",
|
||||
":l" = "left hand", ".l" = "left hand",
|
||||
":i" = "intercom", ".i" = "intercom",
|
||||
":h" = "department", ".h" = "department",
|
||||
":c" = "Command", ".c" = "Command",
|
||||
":n" = "Science", ".n" = "Science",
|
||||
":m" = "Medical", ".m" = "Medical",
|
||||
":e" = "Engineering", ".e" = "Engineering",
|
||||
":s" = "Security", ".s" = "Security",
|
||||
":b" = "binary", ".b" = "binary",
|
||||
":a" = "alientalk", ".a" = "alientalk",
|
||||
":t" = "Syndicate", ".t" = "Syndicate",
|
||||
":u" = "Supply", ".u" = "Supply",
|
||||
":v" = "Service", ".v" = "Service",
|
||||
":o" = "AI Private", ".o" = "AI Private",
|
||||
":g" = "changeling", ".g" = "changeling",
|
||||
":y" = "Centcom", ".y" = "Centcom",
|
||||
":x" = "cords", ".x" = "cords",
|
||||
":p" = "admin", ".p" = "admin",
|
||||
":d" = "deadmin", ".d" = "deadmin",
|
||||
|
||||
":R" = "right hand", "#R" = "right hand", ".R" = "right hand",
|
||||
":L" = "left hand", "#L" = "left hand", ".L" = "left hand",
|
||||
":I" = "intercom", "#I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", "#H" = "department", ".H" = "department",
|
||||
":C" = "Command", "#C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", "#N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", "#M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering",
|
||||
":S" = "Security", "#S" = "Security", ".S" = "Security",
|
||||
":W" = "whisper", "#W" = "whisper", ".W" = "whisper",
|
||||
":B" = "binary", "#B" = "binary", ".B" = "binary",
|
||||
":A" = "alientalk", "#A" = "alientalk", ".A" = "alientalk",
|
||||
":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate",
|
||||
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", "#V" = "Service", ".V" = "Service",
|
||||
":O" = "AI Private", "#O" = "AI Private", ".O" = "AI Private",
|
||||
":G" = "changeling", "#G" = "changeling", ".G" = "changeling",
|
||||
":Y" = "Centcom", "#Y" = "Centcom", ".Y" = "Centcom",
|
||||
":X" = "cords", "#X" = "cords", ".X" = "cords",
|
||||
":P" = "admin", "#P" = "admin", ".P" = "admin",
|
||||
":D" = "deadmin", "#D" = "deadmin", ".D" = "deadmin",
|
||||
":R" = "right hand", ".R" = "right hand",
|
||||
":L" = "left hand", ".L" = "left hand",
|
||||
":I" = "intercom", ".I" = "intercom",
|
||||
":H" = "department", ".H" = "department",
|
||||
":C" = "Command", ".C" = "Command",
|
||||
":N" = "Science", ".N" = "Science",
|
||||
":M" = "Medical", ".M" = "Medical",
|
||||
":E" = "Engineering", ".E" = "Engineering",
|
||||
":S" = "Security", ".S" = "Security",
|
||||
":B" = "binary", ".B" = "binary",
|
||||
":A" = "alientalk", ".A" = "alientalk",
|
||||
":T" = "Syndicate", ".T" = "Syndicate",
|
||||
":U" = "Supply", ".U" = "Supply",
|
||||
":V" = "Service", ".V" = "Service",
|
||||
":O" = "AI Private", ".O" = "AI Private",
|
||||
":G" = "changeling", ".G" = "changeling",
|
||||
":Y" = "Centcom", ".Y" = "Centcom",
|
||||
":X" = "cords", ".X" = "cords",
|
||||
":P" = "admin", ".P" = "admin",
|
||||
":D" = "deadmin", ".D" = "deadmin",
|
||||
|
||||
//kinda localization -- rastaf0
|
||||
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
|
||||
":ê" = "right hand", "#ê" = "right hand", ".ê" = "right hand",
|
||||
":ä" = "left hand", "#ä" = "left hand", ".ä" = "left hand",
|
||||
":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom",
|
||||
":ð" = "department", "#ð" = "department", ".ð" = "department",
|
||||
":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command",
|
||||
":ò" = "Science", "#ò" = "Science", ".ò" = "Science",
|
||||
":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical",
|
||||
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
|
||||
":û" = "Security", "#û" = "Security", ".û" = "Security",
|
||||
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
|
||||
":è" = "binary", "#è" = "binary", ".è" = "binary",
|
||||
":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk",
|
||||
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
|
||||
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
|
||||
":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling"
|
||||
)
|
||||
":ê" = "right hand", ".ê" = "right hand",
|
||||
":ä" = "left hand", ".ä" = "left hand",
|
||||
":ø" = "intercom", ".ø" = "intercom",
|
||||
":ð" = "department", ".ð" = "department",
|
||||
":ñ" = "Command", ".ñ" = "Command",
|
||||
":ò" = "Science", ".ò" = "Science",
|
||||
":ü" = "Medical", ".ü" = "Medical",
|
||||
":ó" = "Engineering", ".ó" = "Engineering",
|
||||
":û" = "Security", ".û" = "Security",
|
||||
":è" = "binary", ".è" = "binary",
|
||||
":ô" = "alientalk", ".ô" = "alientalk",
|
||||
":å" = "Syndicate", ".å" = "Syndicate",
|
||||
":é" = "Supply", ".é" = "Supply",
|
||||
":ï" = "changeling", ".ï" = "changeling"))
|
||||
|
||||
var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null)
|
||||
var/static/list/crit_allowed_modes = list(MODE_WHISPER = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE)
|
||||
var/static/list/unconscious_allowed_modes = list(MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE)
|
||||
|
||||
var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE)
|
||||
|
||||
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE)
|
||||
if(sanitize)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
if(!message || message == "")
|
||||
@@ -72,8 +71,9 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
var/message_mode = get_message_mode(message)
|
||||
var/original_message = message
|
||||
var/in_critical = InCritical()
|
||||
|
||||
if(message_mode == MODE_HEADSET || message_mode == MODE_ROBOT)
|
||||
if(one_character_prefix[message_mode])
|
||||
message = copytext(message, 2)
|
||||
else if(message_mode)
|
||||
message = copytext(message, 3)
|
||||
@@ -94,34 +94,79 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
say_dead(original_message)
|
||||
return
|
||||
|
||||
if(check_emote(original_message))
|
||||
if(check_emote(original_message) || !can_speak_basic(original_message))
|
||||
return
|
||||
|
||||
if(!can_speak_basic(original_message)) //Stat is seperate so I can handle whispers properly.
|
||||
return
|
||||
if(in_critical)
|
||||
if(!(crit_allowed_modes[message_mode]))
|
||||
return
|
||||
else if(stat == UNCONSCIOUS)
|
||||
if(!(unconscious_allowed_modes[message_mode]))
|
||||
return
|
||||
|
||||
if(stat && !(message_mode in crit_allowed_modes))
|
||||
return
|
||||
// language comma detection.
|
||||
var/datum/language/message_language = get_message_language(message)
|
||||
if(message_language)
|
||||
// No, you cannot speak in xenocommon just because you know the key
|
||||
if(can_speak_in_language(message_language))
|
||||
language = message_language
|
||||
message = copytext(message, 3)
|
||||
|
||||
if(handle_inherent_channels(message, message_mode)) //Hiveminds, binary chat & holopad.
|
||||
// Trim the space if they said ",0 I LOVE LANGUAGES"
|
||||
if(findtext(message, " ", 1, 2))
|
||||
message = copytext(message, 2)
|
||||
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
|
||||
// Detection of language needs to be before inherent channels, because
|
||||
// AIs use inherent channels for the holopad. Most inherent channels
|
||||
// ignore the language argument however.
|
||||
|
||||
if(handle_inherent_channels(message, message_mode, language)) //Hiveminds, binary chat & holopad.
|
||||
return
|
||||
|
||||
if(!can_speak_vocal(message))
|
||||
to_chat(src, "<span class='warning'>You find yourself unable to speak!</span>")
|
||||
return
|
||||
|
||||
if(message_mode != MODE_WHISPER) //whisper() calls treat_message(); double process results in "hisspering"
|
||||
message = treat_message(message)
|
||||
var/message_range = 7
|
||||
|
||||
var/succumbed = FALSE
|
||||
|
||||
if(message_mode == MODE_WHISPER)
|
||||
message_range = 1
|
||||
spans |= SPAN_ITALICS
|
||||
log_whisper("[src.name]/[src.key] : [message]")
|
||||
if(in_critical)
|
||||
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
|
||||
// If we cut our message short, abruptly end it with a-..
|
||||
var/message_len = length(message)
|
||||
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
|
||||
message = Ellipsis(message, 10, 1)
|
||||
message_mode = MODE_WHISPER_CRIT
|
||||
succumbed = TRUE
|
||||
else
|
||||
log_say("[name]/[key] : [message]")
|
||||
|
||||
message = treat_message(message)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
spans += get_spans()
|
||||
|
||||
if(language)
|
||||
var/datum/language/L = GLOB.language_datums[language]
|
||||
if(!istype(L))
|
||||
L = new language
|
||||
GLOB.language_datums[language] = L
|
||||
|
||||
spans |= L.spans
|
||||
|
||||
//Log what we've said with an associated timestamp, using the list's len for safety/to prevent overwriting messages
|
||||
log_message(message, INDIVIDUAL_SAY_LOG)
|
||||
|
||||
var/message_range = 7
|
||||
var/radio_return = radio(message, message_mode, spans)
|
||||
if(radio_return & NOPASS) //There's a whisper() message_mode, no need to continue the proc if that is called
|
||||
return
|
||||
if(radio_return & ITALICS)
|
||||
spans |= SPAN_ITALICS
|
||||
if(radio_return & REDUCE_RANGE)
|
||||
@@ -137,12 +182,15 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(pressure < ONE_ATMOSPHERE*0.4) //Thin air, let's italicise the message
|
||||
spans |= SPAN_ITALICS
|
||||
|
||||
send_speech(message, message_range, src, bubble_type, spans)
|
||||
send_speech(message, message_range, src, bubble_type, spans, language, message_mode)
|
||||
|
||||
if(succumbed)
|
||||
succumb(1)
|
||||
to_chat(src, compose_message(src, language, message, , spans, message_mode))
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
return 1
|
||||
|
||||
/mob/living/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
if(!client)
|
||||
return
|
||||
var/deaf_message
|
||||
@@ -154,20 +202,38 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
else
|
||||
deaf_message = "<span class='notice'>You can't hear yourself!</span>"
|
||||
deaf_type = 2 // Since you should be able to hear yourself without looking
|
||||
if(!(message_langs & languages_understood) || force_compose) //force_compose is so AIs don't end up without their hrefs.
|
||||
message = compose_message(speaker, message_langs, raw_message, radio_freq, spans)
|
||||
|
||||
// Recompose message for AI hrefs, language incomprehension.
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
show_message(message, 2, deaf_message, deaf_type)
|
||||
return message
|
||||
|
||||
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
|
||||
var/list/listening = get_hearers_in_view(message_range, source)
|
||||
for(var/mob/M in player_list)
|
||||
/mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode)
|
||||
var/static/list/eavesdropping_modes = list(MODE_WHISPER = TRUE, MODE_WHISPER_CRIT = TRUE)
|
||||
var/eavesdrop_range = 0
|
||||
if(eavesdropping_modes[message_mode])
|
||||
eavesdrop_range = EAVESDROP_EXTRA_RANGE
|
||||
var/list/listening = get_hearers_in_view(message_range+eavesdrop_range, source)
|
||||
var/list/the_dead = list()
|
||||
for(var/_M in GLOB.player_list)
|
||||
var/mob/M = _M
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
the_dead[M] = TRUE
|
||||
|
||||
var/rendered = compose_message(src, languages_spoken, message, , spans)
|
||||
for(var/atom/movable/AM in listening)
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
var/eavesdropping
|
||||
var/eavesrendered
|
||||
if(eavesdrop_range)
|
||||
eavesdropping = stars(message)
|
||||
eavesrendered = compose_message(src, message_language, eavesdropping, , spans, message_mode)
|
||||
|
||||
var/rendered = compose_message(src, message_language, message, , spans, message_mode)
|
||||
for(var/_AM in listening)
|
||||
var/atom/movable/AM = _AM
|
||||
if(eavesdrop_range && get_dist(source, AM) > message_range && !(the_dead[AM]))
|
||||
AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mode)
|
||||
else
|
||||
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
|
||||
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
@@ -176,8 +242,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
spawn(0)
|
||||
flick_overlay(I, speech_bubble_recipients, 30)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30)
|
||||
|
||||
/mob/proc/binarycheck()
|
||||
return 0
|
||||
@@ -216,16 +281,32 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/proc/get_message_mode(message)
|
||||
if(copytext(message, 1, 2) == ";")
|
||||
return MODE_HEADSET
|
||||
else if(copytext(message, 1, 2) == "#")
|
||||
return MODE_WHISPER
|
||||
else if(length(message) > 2)
|
||||
return department_radio_keys[copytext(message, 1, 3)]
|
||||
return GLOB.department_radio_keys[copytext(message, 1, 3)]
|
||||
|
||||
/mob/living/proc/get_message_language(message)
|
||||
var/static/list/langlist
|
||||
if(!langlist)
|
||||
langlist = subtypesof(/datum/language)
|
||||
|
||||
if(copytext(message, 1, 2) == ",")
|
||||
var/key = copytext(message, 2, 3)
|
||||
for(var/ld in langlist)
|
||||
var/datum/language/LD = ld
|
||||
if(initial(LD.key) == key)
|
||||
return LD
|
||||
return null
|
||||
|
||||
/mob/living/proc/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_CHANGELING)
|
||||
switch(lingcheck())
|
||||
if(3)
|
||||
var/msg = "<i><font color=#800040><b>[src.mind]:</b> [message]</font></i>"
|
||||
for(var/mob/M in mob_list)
|
||||
if(M in dead_mob_list)
|
||||
for(var/_M in GLOB.mob_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, src)
|
||||
to_chat(M, "[link] [msg]")
|
||||
else
|
||||
@@ -240,8 +321,9 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(2)
|
||||
var/msg = "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
|
||||
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
|
||||
for(var/mob/M in mob_list)
|
||||
if(M in dead_mob_list)
|
||||
for(var/_M in GLOB.mob_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, src)
|
||||
to_chat(M, "[link] [msg]")
|
||||
else
|
||||
@@ -287,32 +369,28 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
return message
|
||||
|
||||
/mob/living/proc/radio(message, message_mode, list/spans)
|
||||
/mob/living/proc/radio(message, message_mode, list/spans, language)
|
||||
switch(message_mode)
|
||||
if(MODE_R_HAND)
|
||||
for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
|
||||
if (r_hand)
|
||||
return r_hand.talk_into(src, message, , spans)
|
||||
return r_hand.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
if(MODE_L_HAND)
|
||||
for(var/obj/item/l_hand in get_held_items_for_side("l", all = TRUE))
|
||||
if (l_hand)
|
||||
return l_hand.talk_into(src, message, , spans)
|
||||
return l_hand.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_INTERCOM)
|
||||
for (var/obj/item/device/radio/intercom/I in view(1, null))
|
||||
I.talk_into(src, message, , spans)
|
||||
I.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_BINARY)
|
||||
if(binarycheck())
|
||||
robot_talk(message)
|
||||
return ITALICS | REDUCE_RANGE //Does not return 0 since this is only reached by humans, not borgs or AIs.
|
||||
|
||||
if(MODE_WHISPER)
|
||||
whisper(message)
|
||||
return NOPASS
|
||||
return 0
|
||||
|
||||
/mob/living/lingcheck() //1 is ling w/ no hivemind. 2 is ling w/hivemind. 3 is ling victim being linked into hivemind.
|
||||
@@ -324,10 +402,30 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
return 3
|
||||
return 0
|
||||
|
||||
/mob/living/say_quote(input, list/spans)
|
||||
/mob/living/say_quote(input, list/spans, message_mode)
|
||||
var/tempinput = attach_spans(input, spans)
|
||||
if(message_mode == MODE_WHISPER)
|
||||
return "[verb_whisper], \"[tempinput]\""
|
||||
if(message_mode == MODE_WHISPER_CRIT)
|
||||
return "[verb_whisper] in [p_their()] last breath, \"[tempinput]\""
|
||||
if (stuttering)
|
||||
return "stammers, \"[tempinput]\""
|
||||
if (getBrainLoss() >= 60)
|
||||
return "gibbers, \"[tempinput]\""
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/get_default_language()
|
||||
if(selected_default_language)
|
||||
if(has_language(selected_default_language))
|
||||
return selected_default_language
|
||||
else
|
||||
selected_default_language = null
|
||||
|
||||
. = ..()
|
||||
|
||||
/mob/living/proc/open_language_menu(mob/user)
|
||||
language_menu.ui_interact(user)
|
||||
|
||||
/mob/living/whisper(message as text)
|
||||
say("#[message]")
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#define CALL_BOT_COOLDOWN 900
|
||||
var/list/ai_list = list()
|
||||
|
||||
//Not sure why this is necessary...
|
||||
/proc/AutoUpdateAI(obj/subject)
|
||||
var/is_in_use = 0
|
||||
if (subject!=null)
|
||||
for(var/A in ai_list)
|
||||
for(var/A in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/M = A
|
||||
if ((M.client && M.machine == subject))
|
||||
is_in_use = 1
|
||||
@@ -22,7 +21,6 @@ var/list/ai_list = list()
|
||||
canmove = 0
|
||||
status_flags = CANSTUN|CANPUSH
|
||||
a_intent = INTENT_HARM //so we always get pushed instead of trying to swap
|
||||
force_compose = 1 //This ensures that the AI always composes it's own hear message. Needed for hrefs and job display.
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
|
||||
see_in_dark = 8
|
||||
med_hud = DATA_HUD_MEDICAL_BASIC
|
||||
@@ -84,6 +82,10 @@ var/list/ai_list = list()
|
||||
var/obj/machinery/camera/portable/builtInCamera
|
||||
|
||||
var/obj/structure/AIcore/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
|
||||
var/chnotify = 0
|
||||
|
||||
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
|
||||
..()
|
||||
@@ -138,22 +140,24 @@ var/list/ai_list = list()
|
||||
radio = new /obj/item/device/radio/headset/ai(src)
|
||||
aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
|
||||
|
||||
deploy_action.Grant(src)
|
||||
|
||||
if(isturf(loc))
|
||||
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
|
||||
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall,\
|
||||
/mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/set_automatic_say_channel)
|
||||
|
||||
ai_list += src
|
||||
shuttle_caller_list += src
|
||||
GLOB.ai_list += src
|
||||
GLOB.shuttle_caller_list += src
|
||||
|
||||
builtInCamera = new /obj/machinery/camera/portable(src)
|
||||
builtInCamera.network = list("SS13")
|
||||
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
ai_list -= src
|
||||
shuttle_caller_list -= src
|
||||
GLOB.ai_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
malfhack = null
|
||||
@@ -247,13 +251,16 @@ var/list/ai_list = list()
|
||||
for(var/mob/living/silicon/robot/R in connected_robots)
|
||||
borg_area = get_area(R)
|
||||
var/robot_status = "Nominal"
|
||||
if(R.stat || !R.client)
|
||||
if(R.shell)
|
||||
robot_status = "AI SHELL"
|
||||
else if(R.stat || !R.client)
|
||||
robot_status = "OFFLINE"
|
||||
else if(!R.cell || R.cell.charge <= 0)
|
||||
robot_status = "DEPOWERED"
|
||||
//Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
|
||||
stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \
|
||||
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
|
||||
Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]"))
|
||||
stat(null, text("AI shell beacons detected: [LAZYLEN(GLOB.available_ai_shells)]")) //Count of total AI shells
|
||||
else
|
||||
stat(null, text("Systems nonfunctional"))
|
||||
|
||||
@@ -293,7 +300,7 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/proc/ai_roster()
|
||||
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
|
||||
|
||||
dat += data_core.get_manifest()
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
dat += "</body></html>"
|
||||
|
||||
src << browse(dat, "window=airoster")
|
||||
@@ -315,7 +322,7 @@ var/list/ai_list = list()
|
||||
|
||||
// hack to display shuttle timer
|
||||
if(!EMERGENCY_IDLE_OR_RECALLED)
|
||||
var/obj/machinery/computer/communications/C = locate() in machines
|
||||
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
|
||||
if(C)
|
||||
C.post_status("shuttle")
|
||||
|
||||
@@ -363,7 +370,7 @@ var/list/ai_list = list()
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
if (href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
|
||||
switchCamera(locate(href_list["switchcamera"])) in GLOB.cameranet.cameras
|
||||
if (href_list["showalerts"])
|
||||
ai_alerts()
|
||||
#ifdef AI_VOX
|
||||
@@ -403,14 +410,14 @@ var/list/ai_list = list()
|
||||
if(call_bot_cooldown > world.time)
|
||||
to_chat(src, "<span class='danger'>Error: Your last call bot command is still processing, please wait for the bot to finish calculating a route.</span>")
|
||||
return
|
||||
Bot = locate(href_list["callbot"]) in living_mob_list
|
||||
Bot = locate(href_list["callbot"]) in GLOB.living_mob_list
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
|
||||
waypoint_mode = 1
|
||||
to_chat(src, "<span class='notice'>Set your waypoint by clicking on a valid location free of obstructions.</span>")
|
||||
return
|
||||
if(href_list["interface"]) //Remotely connect to a bot!
|
||||
Bot = locate(href_list["interface"]) in living_mob_list
|
||||
Bot = locate(href_list["interface"]) in GLOB.living_mob_list
|
||||
if(!Bot || Bot.remote_disabled || src.control_disabled)
|
||||
return
|
||||
Bot.attack_ai(src)
|
||||
@@ -423,7 +430,7 @@ var/list/ai_list = list()
|
||||
if(controlled_mech)
|
||||
to_chat(src, "<span class='warning'>You are already loaded into an onboard computer!</span>")
|
||||
return
|
||||
if(!cameranet.checkCameraVis(M))
|
||||
if(!GLOB.cameranet.checkCameraVis(M))
|
||||
to_chat(src, "<span class='warning'>Exosuit is no longer near active cameras.</span>")
|
||||
return
|
||||
if(lacks_power())
|
||||
@@ -470,7 +477,7 @@ var/list/ai_list = list()
|
||||
d += "<A HREF=?src=\ref[src];botrefresh=1>Query network status</A><br>"
|
||||
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='30%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
|
||||
|
||||
for (Bot in living_mob_list)
|
||||
for (Bot in GLOB.living_mob_list)
|
||||
if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
|
||||
bot_area = get_area(Bot)
|
||||
var/bot_mode = Bot.get_mode()
|
||||
@@ -492,7 +499,7 @@ var/list/ai_list = list()
|
||||
//The target must be in view of a camera or near the core.
|
||||
if(turf_check in range(get_turf(src)))
|
||||
call_bot(turf_check)
|
||||
else if(cameranet && cameranet.checkTurfVis(turf_check))
|
||||
else if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(turf_check))
|
||||
call_bot(turf_check)
|
||||
else
|
||||
to_chat(src, "<span class='danger'>Selected location is not visible.</span>")
|
||||
@@ -582,7 +589,7 @@ var/list/ai_list = list()
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
|
||||
@@ -601,7 +608,7 @@ var/list/ai_list = list()
|
||||
if(isnull(network))
|
||||
network = old_network // If nothing is selected
|
||||
else
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(network in C.network)
|
||||
@@ -625,7 +632,7 @@ var/list/ai_list = list()
|
||||
return //won't work if dead
|
||||
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer", "Dorfy", "Blue Glow", "Red Glow")
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
for (var/obj/machinery/M in machines) //change status
|
||||
for (var/obj/machinery/M in GLOB.machines) //change status
|
||||
if(istype(M, /obj/machinery/ai_status_display))
|
||||
var/obj/machinery/ai_status_display/AISD = M
|
||||
AISD.emotion = emote
|
||||
@@ -652,7 +659,7 @@ var/list/ai_list = list()
|
||||
if("Crew Member")
|
||||
var/list/personnel_list = list()
|
||||
|
||||
for(var/datum/data/record/t in data_core.locked)//Look in data core locked.
|
||||
for(var/datum/data/record/t in GLOB.data_core.locked)//Look in data core locked.
|
||||
personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image.
|
||||
|
||||
if(personnel_list.len)
|
||||
@@ -791,12 +798,13 @@ var/list/ai_list = list()
|
||||
if(!..())
|
||||
return
|
||||
if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
|
||||
if(!mind)
|
||||
to_chat(user, "<span class='warning'>No intelligence patterns detected.</span>" )
|
||||
return
|
||||
if(!can_be_carded)
|
||||
to_chat(user, "<span class='boldwarning'>Transfer failed.</span>")
|
||||
return
|
||||
disconnect_shell() //If the AI is controlling a borg, force the player back to core!
|
||||
if(!mind)
|
||||
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.
|
||||
ai_restore_power()//So the AI initially has power.
|
||||
@@ -818,12 +826,12 @@ var/list/ai_list = list()
|
||||
//stop AIs from leaving windows open and using then after they lose vision
|
||||
//apc_override is needed here because AIs use their own APC when powerless
|
||||
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
|
||||
if(M && cameranet && !cameranet.checkTurfVis(get_turf_pixel(M)) && !apc_override)
|
||||
if(M && GLOB.cameranet && !GLOB.cameranet.checkTurfVis(get_turf_pixel(M)) && !apc_override)
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
raw_message = lang_treat(speaker, message_langs, raw_message, spans)
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
raw_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
|
||||
var/name_used = speaker.GetVoice()
|
||||
var/rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> <span class='message'>[raw_message]</span></span></i>"
|
||||
show_message(rendered, 2)
|
||||
@@ -907,6 +915,69 @@ var/list/ai_list = list()
|
||||
to_chat(src, "Hack complete. \The [apc] is now under your exclusive control.")
|
||||
apc.update_icon()
|
||||
|
||||
/mob/living/silicon/ai/verb/deploy_to_shell(var/mob/living/silicon/robot/target)
|
||||
set category = "AI Commands"
|
||||
set name = "Deploy to Shell"
|
||||
|
||||
if(stat || lacks_power() || control_disabled)
|
||||
to_chat(src, "<span class='danger'>Wireless networking module is offline.</span>")
|
||||
return
|
||||
|
||||
var/list/possible = list()
|
||||
|
||||
for(var/borgie in GLOB.available_ai_shells)
|
||||
var/mob/living/silicon/robot/R = borgie
|
||||
if(R.shell && !R.deployed && (R.stat != DEAD) && (!R.connected_ai ||(R.connected_ai == src)))
|
||||
possible += R
|
||||
|
||||
if(!LAZYLEN(possible))
|
||||
to_chat(src, "No usable AI shell beacons detected.")
|
||||
|
||||
if(!target || !(target in possible)) //If the AI is looking for a new shell, or its pre-selected shell is no longer valid
|
||||
target = input(src, "Which body to control?") as null|anything in possible
|
||||
|
||||
if (!target || target.stat == DEAD || target.deployed || !(!target.connected_ai ||(target.connected_ai == src)))
|
||||
return
|
||||
|
||||
else if(mind)
|
||||
soullink(/datum/soullink/sharedbody, src, target)
|
||||
deployed_shell = target
|
||||
target.deploy_init(src)
|
||||
mind.transfer_to(target)
|
||||
diag_hud_set_deployed()
|
||||
|
||||
/datum/action/innate/deploy_shell
|
||||
name = "Deploy to AI Shell"
|
||||
desc = "Wirelessly control a specialized cyborg shell."
|
||||
button_icon_state = "ai_shell"
|
||||
|
||||
/datum/action/innate/deploy_shell/Trigger()
|
||||
var/mob/living/silicon/ai/AI = owner
|
||||
if(!AI)
|
||||
return
|
||||
AI.deploy_to_shell()
|
||||
|
||||
/datum/action/innate/deploy_last_shell
|
||||
name = "Reconnect to shell"
|
||||
desc = "Reconnect to the most recently used AI shell."
|
||||
button_icon_state = "ai_last_shell"
|
||||
var/mob/living/silicon/robot/last_used_shell
|
||||
|
||||
/datum/action/innate/deploy_last_shell/Trigger()
|
||||
if(!owner)
|
||||
return
|
||||
if(last_used_shell)
|
||||
var/mob/living/silicon/ai/AI = owner
|
||||
AI.deploy_to_shell(last_used_shell)
|
||||
else
|
||||
Remove(owner) //If the last shell is blown, destroy it.
|
||||
|
||||
/mob/living/silicon/ai/proc/disconnect_shell()
|
||||
if(deployed_shell) //Forcibly call back AI in event of things such as damage, EMP or power loss.
|
||||
to_chat(src, "<span class='danger'>Your remote connection has been reset!</span>")
|
||||
deployed_shell.undeploy()
|
||||
diag_hud_set_deployed()
|
||||
|
||||
/mob/living/silicon/ai/resist()
|
||||
return
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
if(!SSticker || !SSticker.mode)
|
||||
to_chat(M, "You cannot attack people before the game has started.")
|
||||
return
|
||||
..()
|
||||
@@ -22,6 +22,7 @@
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/emp_act(severity)
|
||||
disconnect_shell()
|
||||
if (prob(30))
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(eyeobj)
|
||||
eyeobj.setLoc(get_turf(src))
|
||||
|
||||
shuttle_caller_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
|
||||
ShutOffDoomsdayDevice()
|
||||
@@ -35,7 +35,7 @@
|
||||
if(nuking)
|
||||
set_security_level("red")
|
||||
nuking = FALSE
|
||||
for(var/obj/item/weapon/pinpointer/P in pinpointer_list)
|
||||
for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
|
||||
P.nuke_warning = FALSE
|
||||
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
/mob/living/silicon/ai/examine(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] <EM>[src]</EM>!\n"
|
||||
if (src.stat == DEAD)
|
||||
if (stat == DEAD)
|
||||
msg += "<span class='deadsay'>It appears to be powered-down.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>"
|
||||
if (src.getBruteLoss())
|
||||
if (src.getBruteLoss() < 30)
|
||||
if (getBruteLoss())
|
||||
if (getBruteLoss() < 30)
|
||||
msg += "It looks slightly dented.\n"
|
||||
else
|
||||
msg += "<B>It looks severely dented!</B>\n"
|
||||
if (src.getFireLoss())
|
||||
if (src.getFireLoss() < 30)
|
||||
if (getFireLoss())
|
||||
if (getFireLoss() < 30)
|
||||
msg += "It looks slightly charred.\n"
|
||||
else
|
||||
msg += "<B>Its casing is melted and heat-warped!</B>\n"
|
||||
msg += "</span>"
|
||||
if (shunted == 0 && !src.client)
|
||||
if(deployed_shell)
|
||||
msg += "The wireless networking light is blinking.\n"
|
||||
else if (!shunted && !client)
|
||||
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
var/const/CHUNK_SIZE = 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
|
||||
#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
/datum/cameranet
|
||||
var/name = "Camera Net" // Name to show for VV and stat()
|
||||
@@ -66,7 +66,7 @@ var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
if(!SSticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
@@ -151,7 +151,7 @@ var/datum/cameranet/cameranet = new()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat(name, statclick.update("Cameras: [cameranet.cameras.len] | Chunks: [cameranet.chunks.len]"))
|
||||
stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]"))
|
||||
|
||||
// Debug verb for VVing the chunk that the turf is in.
|
||||
/*
|
||||
|
||||
@@ -173,4 +173,5 @@
|
||||
t.obscured.plane = LIGHTING_PLANE+1
|
||||
obscured += t.obscured
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
#undef UPDATE_BUFFER
|
||||
#undef CHUNK_SIZE
|
||||
@@ -21,7 +21,7 @@
|
||||
return
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
cameranet.visibility(src)
|
||||
GLOB.cameranet.visibility(src)
|
||||
if(ai.client)
|
||||
ai.client.eye = src
|
||||
update_parallax_contents()
|
||||
@@ -104,6 +104,6 @@
|
||||
acceleration = !acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
|
||||
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
|
||||
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
|
||||
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans)
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
|
||||
update_stat()
|
||||
diag_hud_set_health()
|
||||
disconnect_shell()
|
||||
|
||||
/mob/living/silicon/ai/update_stat()
|
||||
if(status_flags & GODMODE)
|
||||
@@ -90,6 +91,7 @@
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/start_RestorePowerRoutine()
|
||||
@@ -146,7 +148,7 @@
|
||||
to_chat(src, "Receiving control information from APC.")
|
||||
sleep(2)
|
||||
apc_override = 1
|
||||
theAPC.ui_interact(src, state = conscious_state)
|
||||
theAPC.ui_interact(src, state = GLOB.conscious_state)
|
||||
apc_override = 0
|
||||
aiRestorePowerRoutine = POWER_RESTORATION_APC_FOUND
|
||||
sleep(50)
|
||||
@@ -163,6 +165,7 @@
|
||||
update_sight()
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_lose_power()
|
||||
disconnect_shell()
|
||||
aiRestorePowerRoutine = POWER_RESTORATION_START
|
||||
blind_eyes(1)
|
||||
update_sight()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
client.images += blood
|
||||
|
||||
if(stat != DEAD)
|
||||
for(var/obj/machinery/ai_status_display/O in machines) //change status
|
||||
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
|
||||
O.mode = 1
|
||||
O.emotion = "Neutral"
|
||||
view_core()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/silicon/ai/say(message)
|
||||
/mob/living/silicon/ai/say(message, language)
|
||||
if(parent && istype(parent) && parent.stat != 2) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
parent.say(message)
|
||||
parent.say(message, language)
|
||||
return
|
||||
..(message)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/mob/living/silicon/ai/IsVocal()
|
||||
return !config.silent_ai
|
||||
|
||||
/mob/living/silicon/ai/radio(message, message_mode, list/spans)
|
||||
/mob/living/silicon/ai/radio(message, message_mode, list/spans, language)
|
||||
if(!radio_enabled || aiRestorePowerRoutine || stat) //AI cannot speak if radio is disabled (via intellicard) or depowered.
|
||||
to_chat(src, "<span class='danger'>Your radio transmitter is offline!</span>")
|
||||
return 0
|
||||
@@ -29,17 +29,17 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/handle_inherent_channels(message, message_mode)
|
||||
/mob/living/silicon/ai/handle_inherent_channels(message, message_mode, language)
|
||||
. = ..()
|
||||
if(.)
|
||||
return .
|
||||
|
||||
if(message_mode == MODE_HOLOPAD)
|
||||
holopad_talk(message)
|
||||
holopad_talk(message, language)
|
||||
return 1
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(message)
|
||||
/mob/living/silicon/ai/proc/holopad_talk(message, language)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
message = trim(message)
|
||||
@@ -49,20 +49,15 @@
|
||||
|
||||
var/obj/machinery/holopad/T = current
|
||||
if(istype(T) && T.masters[src])//If there is a hologram and its master is the user.
|
||||
send_speech(message, 7, T, "robot", get_spans())
|
||||
send_speech(message, 7, T, "robot", get_spans(), language)
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return
|
||||
|
||||
|
||||
// Make sure that the code compiles with AI_VOX undefined
|
||||
#ifdef AI_VOX
|
||||
|
||||
var/announcing_vox = 0 // Stores the time of the last announcement
|
||||
var/const/VOX_CHANNEL = 200
|
||||
var/const/VOX_DELAY = 600
|
||||
|
||||
#define VOX_DELAY 600
|
||||
/mob/living/silicon/ai/verb/announcement_help()
|
||||
|
||||
set name = "Announcement Help"
|
||||
@@ -79,10 +74,10 @@ var/const/VOX_DELAY = 600
|
||||
<font class='bad'>WARNING:</font><BR>Misuse of the announcement system will get you job banned.<HR>"
|
||||
|
||||
var/index = 0
|
||||
for(var/word in vox_sounds)
|
||||
for(var/word in GLOB.vox_sounds)
|
||||
index++
|
||||
dat += "<A href='?src=\ref[src];say_word=[word]'>[capitalize(word)]</A>"
|
||||
if(index != vox_sounds.len)
|
||||
if(index != GLOB.vox_sounds.len)
|
||||
dat += " / "
|
||||
|
||||
var/datum/browser/popup = new(src, "announce_help", "Announcement Help", 500, 400)
|
||||
@@ -91,6 +86,7 @@ var/const/VOX_DELAY = 600
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/announcement()
|
||||
var/static/announcing_vox = 0 // Stores the time of the last announcement
|
||||
if(announcing_vox > world.time)
|
||||
to_chat(src, "<span class='notice'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>")
|
||||
return
|
||||
@@ -120,7 +116,7 @@ var/const/VOX_DELAY = 600
|
||||
if(!word)
|
||||
words -= word
|
||||
continue
|
||||
if(!vox_sounds[word])
|
||||
if(!GLOB.vox_sounds[word])
|
||||
incorrect_words += word
|
||||
|
||||
if(incorrect_words.len)
|
||||
@@ -147,16 +143,16 @@ var/const/VOX_DELAY = 600
|
||||
|
||||
word = lowertext(word)
|
||||
|
||||
if(vox_sounds[word])
|
||||
if(GLOB.vox_sounds[word])
|
||||
|
||||
var/sound_file = vox_sounds[word]
|
||||
var/sound/voice = sound(sound_file, wait = 1, channel = VOX_CHANNEL)
|
||||
var/sound_file = GLOB.vox_sounds[word]
|
||||
var/sound/voice = sound(sound_file, wait = 1, channel = CHANNEL_VOX)
|
||||
voice.status = SOUND_STREAM
|
||||
|
||||
// If there is no single listener, broadcast to everyone in the same z level
|
||||
if(!only_listener)
|
||||
// Play voice for all mobs in the z level
|
||||
for(var/mob/M in player_list)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client && !M.ear_deaf && (M.client.prefs.toggles & SOUND_ANNOUNCEMENTS))
|
||||
var/turf/T = get_turf(M)
|
||||
if(T.z == z_level)
|
||||
@@ -167,3 +163,12 @@ var/const/VOX_DELAY = 600
|
||||
return 0
|
||||
|
||||
#endif
|
||||
|
||||
/mob/living/silicon/ai/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(is_servant_of_ratvar(src))
|
||||
// Ratvarian AIs can only speak Ratvarian
|
||||
. = ispath(dt, /datum/language/ratvar) && has_language(dt)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Dynamically loading it has bad results with sounds overtaking each other, even with the wait variable.
|
||||
#ifdef AI_VOX
|
||||
|
||||
var/list/vox_sounds = list("," = 'sound/vox_fem/,.ogg',
|
||||
GLOBAL_LIST_INIT(vox_sounds, list("," = 'sound/vox_fem/,.ogg',
|
||||
"." = 'sound/vox_fem/..ogg',
|
||||
"a" = 'sound/vox_fem/a.ogg',
|
||||
"abortions" = 'sound/vox_fem/abortions.ogg',
|
||||
@@ -713,6 +713,5 @@ var/list/vox_sounds = list("," = 'sound/vox_fem/,.ogg',
|
||||
"z" = 'sound/vox_fem/z.ogg',
|
||||
"zero" = 'sound/vox_fem/zero.ogg',
|
||||
"zone" = 'sound/vox_fem/zone.ogg',
|
||||
"zulu" = 'sound/vox_fem/zulu.ogg',
|
||||
)
|
||||
"zulu" = 'sound/vox_fem/zulu.ogg'))
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/silicon/Login()
|
||||
if(mind && ticker && ticker.mode)
|
||||
ticker.mode.remove_cultist(mind, 0, 0)
|
||||
ticker.mode.remove_revolutionary(mind, 0)
|
||||
ticker.mode.remove_gangster(mind, remove_bosses=1)
|
||||
if(mind && SSticker && SSticker.mode)
|
||||
SSticker.mode.remove_cultist(mind, 0, 0)
|
||||
SSticker.mode.remove_revolutionary(mind, 0)
|
||||
SSticker.mode.remove_gangster(mind, remove_bosses=1)
|
||||
..()
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
stat = DEAD
|
||||
canmove = 0
|
||||
card.removePersonality()
|
||||
if(holoform)
|
||||
card.forceMove(loc)
|
||||
update_sight()
|
||||
clear_fullscreens()
|
||||
|
||||
//New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here.
|
||||
living_mob_list -= src
|
||||
GLOB.living_mob_list -= src
|
||||
ghostize()
|
||||
qdel(src)
|
||||
@@ -78,13 +78,13 @@
|
||||
. += slowdown
|
||||
|
||||
/mob/living/silicon/pai/Destroy()
|
||||
pai_list -= src
|
||||
GLOB.pai_list -= src
|
||||
..()
|
||||
|
||||
/mob/living/silicon/pai/Initialize()
|
||||
var/obj/item/device/paicard/P = loc
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
pai_list += src
|
||||
GLOB.pai_list += src
|
||||
make_laws()
|
||||
canmove = 0
|
||||
if(!istype(P)) //when manually spawning a pai, we create a card to put it into.
|
||||
@@ -110,10 +110,13 @@
|
||||
var/datum/action/innate/pai/chassis/AC = new /datum/action/innate/pai/chassis
|
||||
var/datum/action/innate/pai/rest/AR = new /datum/action/innate/pai/rest
|
||||
var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light
|
||||
|
||||
var/datum/action/language_menu/ALM = new
|
||||
AS.Grant(src)
|
||||
AC.Grant(src)
|
||||
AR.Grant(src)
|
||||
AL.Grant(src)
|
||||
ALM.Grant(src)
|
||||
emittersemicd = TRUE
|
||||
addtimer(CALLBACK(src, .proc/emittercool), 600)
|
||||
|
||||
|
||||
@@ -102,4 +102,4 @@
|
||||
|
||||
/mob/living/silicon/pai/movement_delay()
|
||||
. = ..()
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(temp)
|
||||
left_part = temp
|
||||
else if(src.stat == 2) // Show some flavor text if the pAI is dead
|
||||
left_part = "<b><font color=red>ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ</font></b>"
|
||||
left_part = "<b><font color=red>�Rr�R �a�� ��Rr����o�</font></b>"
|
||||
right_part = "<pre>Program index hash not found</pre>"
|
||||
|
||||
else
|
||||
@@ -220,18 +220,18 @@
|
||||
// Accessing medical records
|
||||
if("medicalrecord")
|
||||
if(subscreen == 1)
|
||||
medicalActive1 = find_record("id", href_list["med_rec"], data_core.general)
|
||||
medicalActive1 = find_record("id", href_list["med_rec"], GLOB.data_core.general)
|
||||
if(medicalActive1)
|
||||
medicalActive2 = find_record("id", href_list["med_rec"], data_core.medical)
|
||||
medicalActive2 = find_record("id", href_list["med_rec"], GLOB.data_core.medical)
|
||||
if(!medicalActive2)
|
||||
medicalActive1 = null
|
||||
temp = "Unable to locate requested security record. Record may have been deleted, or never have existed."
|
||||
|
||||
if("securityrecord")
|
||||
if(subscreen == 1)
|
||||
securityActive1 = find_record("id", href_list["sec_rec"], data_core.general)
|
||||
securityActive1 = find_record("id", href_list["sec_rec"], GLOB.data_core.general)
|
||||
if(securityActive1)
|
||||
securityActive2 = find_record("id", href_list["sec_rec"], data_core.security)
|
||||
securityActive2 = find_record("id", href_list["sec_rec"], GLOB.data_core.security)
|
||||
if(!securityActive2)
|
||||
securityActive1 = null
|
||||
temp = "Unable to locate requested security record. Record may have been deleted, or never have existed."
|
||||
@@ -241,7 +241,7 @@
|
||||
if(secHUD)
|
||||
add_sec_hud()
|
||||
else
|
||||
var/datum/atom_hud/sec = huds[sec_hud]
|
||||
var/datum/atom_hud/sec = GLOB.huds[sec_hud]
|
||||
sec.remove_hud_from(src)
|
||||
if("medicalhud")
|
||||
if(href_list["toggle"])
|
||||
@@ -249,13 +249,13 @@
|
||||
if(medHUD)
|
||||
add_med_hud()
|
||||
else
|
||||
var/datum/atom_hud/med = huds[med_hud]
|
||||
var/datum/atom_hud/med = GLOB.huds[med_hud]
|
||||
med.remove_hud_from(src)
|
||||
if("translator")
|
||||
if(href_list["toggle"])
|
||||
var/on_already = ((languages_understood == ALL) && (languages_spoken == ALL))
|
||||
languages_spoken = on_already ? (HUMAN | ROBOT) : ALL
|
||||
languages_understood = on_already ? (HUMAN | ROBOT) : ALL
|
||||
if(!HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
grant_all_languages(TRUE)
|
||||
// this is PERMAMENT.
|
||||
if("doorjack")
|
||||
if(href_list["jack"])
|
||||
if(src.cable && src.cable.machine)
|
||||
@@ -313,7 +313,8 @@
|
||||
if(s == "medical HUD")
|
||||
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Medical Analysis Suite</a>[(src.medHUD) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "universal translator")
|
||||
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[((languages_spoken == ALL) && (languages_understood == ALL)) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[translator_on ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "projection array")
|
||||
dat += "<a href='byond://?src=\ref[src];software=projectionarray;sub=0'>Projection Array</a> <br>"
|
||||
if(s == "camera jack")
|
||||
@@ -413,8 +414,8 @@
|
||||
// Crew Manifest
|
||||
/mob/living/silicon/pai/proc/softwareManifest()
|
||||
. += "<h2>Crew Manifest</h2><br><br>"
|
||||
if(data_core.general)
|
||||
for(var/datum/data/record/t in sortRecord(data_core.general))
|
||||
if(GLOB.data_core.general)
|
||||
for(var/datum/data/record/t in sortRecord(GLOB.data_core.general))
|
||||
. += "[t.fields["name"]] - [t.fields["rank"]]<BR>"
|
||||
. += "</body></html>"
|
||||
return .
|
||||
@@ -424,16 +425,16 @@
|
||||
switch(subscreen)
|
||||
if(0)
|
||||
. += "<h3>Medical Records</h3><HR>"
|
||||
if(data_core.general)
|
||||
for(var/datum/data/record/R in sortRecord(data_core.general))
|
||||
if(GLOB.data_core.general)
|
||||
for(var/datum/data/record/R in sortRecord(GLOB.data_core.general))
|
||||
. += "<A href='?src=\ref[src];med_rec=[R.fields["id"]];software=medicalrecord;sub=1'>[R.fields["id"]]: [R.fields["name"]]<BR>"
|
||||
if(1)
|
||||
. += "<CENTER><B>Medical Record</B></CENTER><BR>"
|
||||
if(medicalActive1 in data_core.general)
|
||||
if(medicalActive1 in GLOB.data_core.general)
|
||||
. += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]<BR>\nSex: [medicalActive1.fields["sex"]]<BR>\nAge: [medicalActive1.fields["age"]]<BR>\nFingerprint: [medicalActive1.fields["fingerprint"]]<BR>\nPhysical Status: [medicalActive1.fields["p_stat"]]<BR>\nMental Status: [medicalActive1.fields["m_stat"]]<BR>"
|
||||
else
|
||||
. += "<pre>Requested medical record not found.</pre><BR>"
|
||||
if(medicalActive2 in data_core.medical)
|
||||
if(medicalActive2 in GLOB.data_core.medical)
|
||||
. += "<BR>\n<CENTER><B>Medical Data</B></CENTER><BR>\nBlood Type: <A href='?src=\ref[src];field=blood_type'>[medicalActive2.fields["blood_type"]]</A><BR>\nDNA: <A href='?src=\ref[src];field=b_dna'>[medicalActive2.fields["b_dna"]]</A><BR>\n<BR>\nMinor Disabilities: <A href='?src=\ref[src];field=mi_dis'>[medicalActive2.fields["mi_dis"]]</A><BR>\nDetails: <A href='?src=\ref[src];field=mi_dis_d'>[medicalActive2.fields["mi_dis_d"]]</A><BR>\n<BR>\nMajor Disabilities: <A href='?src=\ref[src];field=ma_dis'>[medicalActive2.fields["ma_dis"]]</A><BR>\nDetails: <A href='?src=\ref[src];field=ma_dis_d'>[medicalActive2.fields["ma_dis_d"]]</A><BR>\n<BR>\nAllergies: <A href='?src=\ref[src];field=alg'>[medicalActive2.fields["alg"]]</A><BR>\nDetails: <A href='?src=\ref[src];field=alg_d'>[medicalActive2.fields["alg_d"]]</A><BR>\n<BR>\nCurrent Diseases: <A href='?src=\ref[src];field=cdi'>[medicalActive2.fields["cdi"]]</A> (per disease info placed in log/comment section)<BR>\nDetails: <A href='?src=\ref[src];field=cdi_d'>[medicalActive2.fields["cdi_d"]]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[src];field=notes'>[medicalActive2.fields["notes"]]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>"
|
||||
else
|
||||
. += "<pre>Requested medical record not found.</pre><BR>"
|
||||
@@ -446,16 +447,16 @@
|
||||
switch(subscreen)
|
||||
if(0)
|
||||
. += "<h3>Security Records</h3><HR>"
|
||||
if(data_core.general)
|
||||
for(var/datum/data/record/R in sortRecord(data_core.general))
|
||||
if(GLOB.data_core.general)
|
||||
for(var/datum/data/record/R in sortRecord(GLOB.data_core.general))
|
||||
. += "<A href='?src=\ref[src];sec_rec=[R.fields["id"]];software=securityrecord;sub=1'>[R.fields["id"]]: [R.fields["name"]]<BR>"
|
||||
if(1)
|
||||
. += "<h3>Security Record</h3>"
|
||||
if(securityActive1 in data_core.general)
|
||||
if(securityActive1 in GLOB.data_core.general)
|
||||
. += "Name: <A href='?src=\ref[src];field=name'>[securityActive1.fields["name"]]</A> ID: <A href='?src=\ref[src];field=id'>[securityActive1.fields["id"]]</A><BR>\nSex: <A href='?src=\ref[src];field=sex'>[securityActive1.fields["sex"]]</A><BR>\nAge: <A href='?src=\ref[src];field=age'>[securityActive1.fields["age"]]</A><BR>\nRank: <A href='?src=\ref[src];field=rank'>[securityActive1.fields["rank"]]</A><BR>\nFingerprint: <A href='?src=\ref[src];field=fingerprint'>[securityActive1.fields["fingerprint"]]</A><BR>\nPhysical Status: [securityActive1.fields["p_stat"]]<BR>\nMental Status: [securityActive1.fields["m_stat"]]<BR>"
|
||||
else
|
||||
. += "<pre>Requested security record not found,</pre><BR>"
|
||||
if(securityActive2 in data_core.security)
|
||||
if(securityActive2 in GLOB.data_core.security)
|
||||
. += "<BR>\nSecurity Data<BR>\nCriminal Status: [securityActive2.fields["criminal"]]<BR>\n<BR>\nMinor Crimes: <A href='?src=\ref[src];field=mi_crim'>[securityActive2.fields["mi_crim"]]</A><BR>\nDetails: <A href='?src=\ref[src];field=mi_crim_d'>[securityActive2.fields["mi_crim_d"]]</A><BR>\n<BR>\nMajor Crimes: <A href='?src=\ref[src];field=ma_crim'>[securityActive2.fields["ma_crim"]]</A><BR>\nDetails: <A href='?src=\ref[src];field=ma_crim_d'>[securityActive2.fields["ma_crim_d"]]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[src];field=notes'>[securityActive2.fields["notes"]]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>"
|
||||
else
|
||||
. += "<pre>Requested security record not found,</pre><BR>"
|
||||
@@ -464,11 +465,10 @@
|
||||
|
||||
// Universal Translator
|
||||
/mob/living/silicon/pai/proc/softwareTranslator()
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
. = {"<h3>Universal Translator</h3><br>
|
||||
When enabled, this device will automatically convert all spoken and written language into a format that any known recipient can understand.<br><br>
|
||||
The device is currently [ ((languages_spoken == ALL) && (languages_understood == ALL)) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>
|
||||
<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Toggle Device</a><br>
|
||||
"}
|
||||
When enabled, this device will permamently be able to speak and understand all known forms of communication.<br><br>
|
||||
The device is currently [translator_on ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>[translator_on ? "" : "<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Activate Translation Module</a><br>"]"}
|
||||
return .
|
||||
|
||||
// Security HUD
|
||||
@@ -599,7 +599,7 @@
|
||||
// Door Jack - supporting proc
|
||||
/mob/living/silicon/pai/proc/hackloop()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
|
||||
if(T.loc)
|
||||
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress in [T.loc].</b></font>")
|
||||
else
|
||||
|
||||
@@ -36,9 +36,11 @@
|
||||
if(is_servant_of_ratvar(src) && user.Adjacent(src) && !stat) //To counter pseudo-stealth by using headlamps
|
||||
msg += "<span class='warning'>Its eyes are glowing a blazing yellow!</span>\n"
|
||||
|
||||
switch(src.stat)
|
||||
switch(stat)
|
||||
if(CONSCIOUS)
|
||||
if(!src.client)
|
||||
if(shell)
|
||||
msg += "It appears to be an [deployed ? "active" : "empty"] AI shell.\n"
|
||||
else if(!client)
|
||||
msg += "It appears to be in stand-by mode.\n" //afk
|
||||
if(UNCONSCIOUS)
|
||||
msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
to_chat(who, "<b>Obey these laws:</b>")
|
||||
laws.show_laws(who)
|
||||
if (is_special_character(src) && connected_ai)
|
||||
if (shell) //AI shell
|
||||
to_chat(who, "<b>Remember, you are an AI remotely controlling your shell, other AIs can be ignored.</b>")
|
||||
else if (is_special_character(src) && connected_ai)
|
||||
to_chat(who, "<b>Remember, [connected_ai.name] is technically your master, but your objective comes first.</b>")
|
||||
else if (connected_ai)
|
||||
to_chat(who, "<b>Remember, [connected_ai.name] is your master, other AIs can be ignored.</b>")
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
update_cell_hud_icon()
|
||||
|
||||
if(syndicate)
|
||||
if(ticker.mode.name == "traitor")
|
||||
for(var/datum/mind/tra in ticker.mode.traitors)
|
||||
if(SSticker.mode.name == "traitor")
|
||||
for(var/datum/mind/tra in SSticker.mode.traitors)
|
||||
if(tra.current)
|
||||
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") //no traitor sprite in that dmi!
|
||||
src.client.images += I
|
||||
@@ -48,7 +48,7 @@
|
||||
if(mind)
|
||||
if(!mind.special_role)
|
||||
mind.special_role = "traitor"
|
||||
ticker.mode.traitors += mind
|
||||
SSticker.mode.traitors += mind
|
||||
|
||||
|
||||
/mob/living/silicon/robot/update_health_hud()
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
regenerate_icons()
|
||||
show_laws(0)
|
||||
if(mind)
|
||||
ticker.mode.remove_revolutionary(mind)
|
||||
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
|
||||
SSticker.mode.remove_revolutionary(mind)
|
||||
SSticker.mode.remove_gangster(mind,1,remove_bosses=1)
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
|
||||
var/obj/item/device/mmi/mmi = null
|
||||
|
||||
var/shell = FALSE
|
||||
var/deployed = FALSE
|
||||
var/mob/living/silicon/ai/mainframe = null
|
||||
var/datum/action/innate/undeployment/undeployment_action = new
|
||||
|
||||
//Hud stuff
|
||||
|
||||
@@ -47,7 +51,7 @@
|
||||
|
||||
var/ident = 0
|
||||
var/locked = 1
|
||||
var/list/req_access = list(access_robotics)
|
||||
var/list/req_access = list(GLOB.access_robotics)
|
||||
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
|
||||
|
||||
@@ -73,7 +77,7 @@
|
||||
|
||||
var/sight_mode = 0
|
||||
var/updating = 0 //portable camera camerachunk update
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
|
||||
|
||||
var/list/upgrades = list()
|
||||
|
||||
@@ -129,8 +133,12 @@
|
||||
update_icons()
|
||||
..()
|
||||
|
||||
//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
|
||||
if(!mmi || !mmi.brainmob)
|
||||
else if(!mmi || !mmi.brainmob)
|
||||
mmi = new (src)
|
||||
mmi.brain = new /obj/item/organ/brain(mmi)
|
||||
mmi.brain.name = "[real_name]'s brain"
|
||||
@@ -159,8 +167,8 @@
|
||||
if(mmi.brainmob)
|
||||
if(mmi.brainmob.stat == DEAD)
|
||||
mmi.brainmob.stat = CONSCIOUS
|
||||
dead_mob_list -= mmi.brainmob
|
||||
living_mob_list += mmi.brainmob
|
||||
GLOB.dead_mob_list -= mmi.brainmob
|
||||
GLOB.living_mob_list += mmi.brainmob
|
||||
mind.transfer_to(mmi.brainmob)
|
||||
mmi.update_icon()
|
||||
else
|
||||
@@ -170,6 +178,8 @@
|
||||
mmi = null
|
||||
if(connected_ai)
|
||||
connected_ai.connected_robots -= src
|
||||
if(shell)
|
||||
GLOB.available_ai_shells -= src
|
||||
qdel(wires)
|
||||
qdel(module)
|
||||
qdel(eye_lights)
|
||||
@@ -204,6 +214,8 @@
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/updatename()
|
||||
if(shell)
|
||||
return
|
||||
var/changed_name = ""
|
||||
if(custom_name)
|
||||
changed_name = custom_name
|
||||
@@ -424,7 +436,9 @@
|
||||
update_icons()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver) && opened && cell) // radio
|
||||
if(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>")
|
||||
@@ -453,6 +467,9 @@
|
||||
if(!cell)
|
||||
to_chat(user, "<span class='warning'>You need to install a power cell to do that!</span>")
|
||||
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>")
|
||||
return
|
||||
if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers
|
||||
emote("buzz-[user.name]")
|
||||
return
|
||||
@@ -594,7 +611,7 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/do_camera_update(oldLoc)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
GLOB.cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Move(a, b, flag)
|
||||
@@ -606,36 +623,6 @@
|
||||
updating = 1
|
||||
addtimer(CALLBACK(src, .proc/do_camera_update, oldLoc), BORG_CAMERA_BUFFER)
|
||||
if(module)
|
||||
if(istype(module, /obj/item/weapon/robot_module/janitor))
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
tile.clean_blood()
|
||||
for(var/A in tile)
|
||||
if(is_cleanable(A))
|
||||
qdel(A)
|
||||
else if(istype(A, /obj/item))
|
||||
var/obj/item/cleaned_item = A
|
||||
cleaned_item.clean_blood()
|
||||
else if(ishuman(A))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head()
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit()
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform()
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes()
|
||||
cleaned_human.clean_blood()
|
||||
cleaned_human.wash_cream()
|
||||
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
|
||||
return
|
||||
|
||||
if(istype(module, /obj/item/weapon/robot_module/miner))
|
||||
if(istype(loc, /turf/open/floor/plating/asteroid))
|
||||
for(var/obj/item/I in held_items)
|
||||
@@ -806,7 +793,7 @@
|
||||
icon_state = "syndie_bloodhound"
|
||||
faction = list("syndicate")
|
||||
bubble_icon = "syndibot"
|
||||
req_access = list(access_syndicate)
|
||||
req_access = list(GLOB.access_syndicate)
|
||||
lawupdate = FALSE
|
||||
scrambledcodes = TRUE // These are rogue borgs.
|
||||
ionpulse = TRUE
|
||||
@@ -829,6 +816,9 @@
|
||||
if(playstyle_string)
|
||||
to_chat(src, playstyle_string)
|
||||
|
||||
/mob/living/silicon/robot/syndicate/ResetModule()
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/syndicate/medical
|
||||
icon_state = "syndi-medi"
|
||||
playstyle_string = "<span class='userdanger'>You are a Syndicate medical cyborg!</span><br>\
|
||||
@@ -843,12 +833,14 @@
|
||||
if(!connected_ai)
|
||||
return
|
||||
switch(notifytype)
|
||||
if(1) //New Cyborg
|
||||
if(NEW_BORG) //New Cyborg
|
||||
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg connection detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
|
||||
if(2) //New Module
|
||||
if(NEW_MODULE) //New Module
|
||||
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.</span><br>")
|
||||
if(3) //New Name
|
||||
if(RENAME) //New Name
|
||||
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].</span><br>")
|
||||
if(AI_SHELL) //New Shell
|
||||
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - New cyborg shell detected: <a href='?src=\ref[connected_ai];track=[html_encode(name)]'>[name]</a></span><br>")
|
||||
|
||||
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close = 0)
|
||||
if(stat || lockcharge || low_power_mode)
|
||||
@@ -889,12 +881,12 @@
|
||||
|
||||
if(sight_mode & BORGMESON)
|
||||
sight |= SEE_TURFS
|
||||
see_invisible = min(see_invisible, SEE_INVISIBLE_MINIMUM)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
|
||||
see_in_dark = 1
|
||||
|
||||
if(sight_mode & BORGMATERIAL)
|
||||
sight |= SEE_OBJS
|
||||
see_invisible = min(see_invisible, SEE_INVISIBLE_MINIMUM)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
see_in_dark = 1
|
||||
|
||||
if(sight_mode & BORGXRAY)
|
||||
@@ -909,6 +901,7 @@
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
/mob/living/silicon/robot/update_stat()
|
||||
if(status_flags & GODMODE)
|
||||
@@ -931,6 +924,7 @@
|
||||
update_headlamp()
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
diag_hud_set_aishell()
|
||||
update_health_hud()
|
||||
|
||||
/mob/living/silicon/robot/revive(full_heal = 0, admin_revive = 0)
|
||||
@@ -940,13 +934,13 @@
|
||||
update_headlamp()
|
||||
if(admin_revive)
|
||||
locked = 1
|
||||
notify_ai(1)
|
||||
notify_ai(NEW_BORG)
|
||||
. = 1
|
||||
|
||||
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
|
||||
..()
|
||||
if(oldname != real_name)
|
||||
notify_ai(3, oldname, newname)
|
||||
notify_ai(RENAME, oldname, newname)
|
||||
if(camera)
|
||||
camera.c_tag = real_name
|
||||
custom_name = newname
|
||||
@@ -967,6 +961,7 @@
|
||||
|
||||
speed = 0
|
||||
ionpulse = FALSE
|
||||
revert_shell()
|
||||
|
||||
return 1
|
||||
|
||||
@@ -985,6 +980,11 @@
|
||||
else
|
||||
status_flags &= ~CANPUSH
|
||||
|
||||
if(module.clean_on_move)
|
||||
flags |= CLEAN_ON_MOVE
|
||||
else
|
||||
flags &= ~CLEAN_ON_MOVE
|
||||
|
||||
hat_offset = module.hat_offset
|
||||
|
||||
magpulse = module.magpulsing
|
||||
@@ -998,6 +998,97 @@
|
||||
new_hat.forceMove(src)
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/proc/make_shell(var/obj/item/borg/upgrade/ai/board)
|
||||
if(!board)
|
||||
upgrades |= new /obj/item/borg/upgrade/ai(src)
|
||||
shell = TRUE
|
||||
braintype = "AI Shell"
|
||||
name = "[designation] AI Shell [rand(100,999)]"
|
||||
real_name = name
|
||||
GLOB.available_ai_shells |= src
|
||||
if(camera)
|
||||
camera.c_tag = real_name //update the camera name too
|
||||
diag_hud_set_aishell()
|
||||
notify_ai(AI_SHELL)
|
||||
|
||||
/mob/living/silicon/robot/proc/revert_shell()
|
||||
if(!shell)
|
||||
return
|
||||
undeploy()
|
||||
for(var/obj/item/borg/upgrade/ai/boris in src)
|
||||
//A player forced reset of a borg would drop the module before this is called, so this is for catching edge cases
|
||||
qdel(boris)
|
||||
shell = FALSE
|
||||
GLOB.available_ai_shells -= src
|
||||
name = "Unformatted Cyborg [rand(100,999)]"
|
||||
real_name = name
|
||||
if(camera)
|
||||
camera.c_tag = real_name
|
||||
diag_hud_set_aishell()
|
||||
|
||||
/mob/living/silicon/robot/proc/deploy_init(var/mob/living/silicon/ai/AI)
|
||||
real_name = "[AI.real_name] shell [rand(100, 999)] - [designation]" //Randomizing the name so it shows up seperately in the shells list
|
||||
name = real_name
|
||||
if(camera)
|
||||
camera.c_tag = real_name //update the camera name too
|
||||
mainframe = AI
|
||||
deployed = TRUE
|
||||
connected_ai = mainframe
|
||||
mainframe.connected_robots |= src
|
||||
lawupdate = TRUE
|
||||
lawsync()
|
||||
if(radio && AI.radio) //AI keeps all channels, including Syndie if it is a Traitor
|
||||
if(AI.radio.syndie)
|
||||
radio.make_syndie()
|
||||
radio.subspace_transmission = TRUE
|
||||
radio.channels = AI.radio.channels
|
||||
for(var/chan in radio.channels)
|
||||
radio.secure_radio_connections[chan] = add_radio(radio, GLOB.radiochannels[chan])
|
||||
|
||||
diag_hud_set_aishell()
|
||||
undeployment_action.Grant(src)
|
||||
|
||||
/datum/action/innate/undeployment
|
||||
name = "Disconnect from shell"
|
||||
desc = "Stop controlling your shell and resume normal core operations."
|
||||
button_icon_state = "ai_core"
|
||||
|
||||
/datum/action/innate/undeployment/Trigger()
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/silicon/robot/R = owner
|
||||
|
||||
R.undeploy()
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/undeploy()
|
||||
|
||||
if(!deployed || !mind || !mainframe)
|
||||
return
|
||||
mainframe.redeploy_action.Grant(mainframe)
|
||||
mainframe.redeploy_action.last_used_shell = src
|
||||
mind.transfer_to(mainframe)
|
||||
deployed = FALSE
|
||||
mainframe.deployed_shell = null
|
||||
undeployment_action.Remove(src)
|
||||
if(radio) //Return radio to normal
|
||||
radio.recalculateChannels()
|
||||
if(camera)
|
||||
camera.c_tag = real_name //update the camera name too
|
||||
diag_hud_set_aishell()
|
||||
mainframe.diag_hud_set_deployed()
|
||||
mainframe.show_laws() //Always remind the AI when switching
|
||||
mainframe = null
|
||||
|
||||
/mob/living/silicon/robot/attack_ai(mob/user)
|
||||
if(shell && (!connected_ai || connected_ai == user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
AI.deploy_to_shell(src)
|
||||
|
||||
/mob/living/silicon/robot/shell
|
||||
shell = TRUE
|
||||
|
||||
/mob/living/silicon/robot/MouseDrop_T(mob/living/M, mob/living/user)
|
||||
. = ..()
|
||||
if(!(M in buckled_mobs) && isliving(M))
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
if (M.a_intent == INTENT_DISARM)
|
||||
if(!(lying))
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if(get_active_held_item())
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
uneq_active()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disabled [src]'s active module!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "disarmed")
|
||||
add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
else
|
||||
Stun(2)
|
||||
step(src,get_dir(M,src))
|
||||
@@ -92,6 +93,8 @@
|
||||
if(locked)
|
||||
to_chat(user, "<span class='notice'>You emag the cover lock.</span>")
|
||||
locked = 0
|
||||
if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them.
|
||||
to_chat(user, "<span class='boldwarning'>[src] seems to be controlled remotely! Emagging the interface may not work as expected.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The cover is already unlocked!</span>")
|
||||
return
|
||||
@@ -125,6 +128,12 @@
|
||||
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
|
||||
return
|
||||
|
||||
if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however.
|
||||
to_chat(user, "<span class='danger'>[src] is remotely controlled! Your emag attempt has triggered a system reset instead!</span>")
|
||||
log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.")
|
||||
ResetModule()
|
||||
return
|
||||
|
||||
SetEmagged(1)
|
||||
SetStunned(3) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
|
||||
lawupdate = 0
|
||||
@@ -132,7 +141,7 @@
|
||||
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
|
||||
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
||||
GLOB.lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
||||
to_chat(src, "<span class='danger'>ALERT: Foreign software detected.</span>")
|
||||
sleep(5)
|
||||
to_chat(src, "<span class='danger'>Initiating diagnostics...</span>")
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
var/can_be_pushed = TRUE
|
||||
var/magpulsing = FALSE
|
||||
var/clean_on_move = FALSE
|
||||
|
||||
var/did_feedback = FALSE
|
||||
var/feedback_key
|
||||
@@ -217,7 +218,7 @@
|
||||
R.SetLockdown(0)
|
||||
R.anchored = FALSE
|
||||
R.notransform = FALSE
|
||||
R.notify_ai(2)
|
||||
R.notify_ai(NEW_MODULE)
|
||||
if(R.hud_used)
|
||||
R.hud_used.update_robot_modules_display()
|
||||
if(feedback_key && !did_feedback)
|
||||
@@ -228,8 +229,17 @@
|
||||
basic_modules = list(
|
||||
/obj/item/device/assembly/flash/cyborg,
|
||||
/obj/item/weapon/reagent_containers/borghypo/epi,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/weldingtool/largetank/cyborg,
|
||||
/obj/item/weapon/wrench/cyborg,
|
||||
/obj/item/weapon/crowbar/cyborg,
|
||||
/obj/item/stack/sheet/metal/cyborg,
|
||||
/obj/item/stack/rods/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/weapon/pickaxe,
|
||||
/obj/item/device/t_scanner/adv_mining_scanner,
|
||||
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg,
|
||||
/obj/item/weapon/soap/nanotrasen,
|
||||
/obj/item/borg/cyborghug)
|
||||
emag_modules = list(/obj/item/weapon/melee/energy/sword/cyborg)
|
||||
@@ -382,6 +392,7 @@
|
||||
moduleselect_icon = "janitor"
|
||||
feedback_key = "cyborg_janitor"
|
||||
hat_offset = -5
|
||||
clean_on_move = TRUE
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/cyborg_drying
|
||||
name = "drying agent spray"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
desig = trim_left(S.designation + " " + S.job)
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/M in player_list)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.binarycheck())
|
||||
if(isAI(M))
|
||||
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='?src=\ref[M];track=[html_encode(name)]'><span class='name'>[name] ([desig])</span></a> <span class='message'>[message_a]</span></span></i>"
|
||||
@@ -33,19 +33,19 @@
|
||||
/mob/living/silicon/lingcheck()
|
||||
return 0 //Borged or AI'd lings can't speak on the ling channel.
|
||||
|
||||
/mob/living/silicon/radio(message, message_mode, list/spans)
|
||||
/mob/living/silicon/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
|
||||
if(message_mode == "robot")
|
||||
if (radio)
|
||||
radio.talk_into(src, message, , spans)
|
||||
radio.talk_into(src, message, , spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
else if(message_mode in radiochannels)
|
||||
else if(message_mode in GLOB.radiochannels)
|
||||
if(radio)
|
||||
radio.talk_into(src, message, message_mode, spans)
|
||||
radio.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/mob/living/silicon
|
||||
gender = NEUTER
|
||||
voice_name = "synthesized voice"
|
||||
languages_spoken = ROBOT | HUMAN
|
||||
languages_understood = ROBOT | HUMAN
|
||||
has_unlimited_silicon_privilege = 1
|
||||
verb_say = "states"
|
||||
verb_ask = "queries"
|
||||
verb_exclaim = "declares"
|
||||
verb_yell = "alarms"
|
||||
initial_languages = list(/datum/language/common, /datum/language/machine)
|
||||
see_in_dark = 8
|
||||
bubble_icon = "machine"
|
||||
weather_immunities = list("ash")
|
||||
@@ -21,8 +20,7 @@
|
||||
var/designation = ""
|
||||
var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all.
|
||||
var/obj/item/device/camera/siliconcam/aicamera = null //photography
|
||||
//hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD)
|
||||
|
||||
var/obj/item/device/radio/borg/radio = null //AIs dont use this but this is at the silicon level to advoid copypasta in say()
|
||||
|
||||
@@ -41,8 +39,8 @@
|
||||
|
||||
/mob/living/silicon/Initialize()
|
||||
..()
|
||||
silicon_mobs += src
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC]
|
||||
GLOB.silicon_mobs += src
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
|
||||
diag_hud.add_to_hud(src)
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
@@ -56,7 +54,7 @@
|
||||
/mob/living/silicon/Destroy()
|
||||
radio = null
|
||||
aicamera = null
|
||||
silicon_mobs -= src
|
||||
GLOB.silicon_mobs -= src
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/contents_explosion(severity, target)
|
||||
@@ -307,8 +305,8 @@
|
||||
else if(Autochan == "None") //Prevents use of the radio for automatic annoucements.
|
||||
radiomod = ""
|
||||
else //For department channels, if any, given by the internal radio.
|
||||
for(var/key in department_radio_keys)
|
||||
if(department_radio_keys[key] == Autochan)
|
||||
for(var/key in GLOB.department_radio_keys)
|
||||
if(GLOB.department_radio_keys[key] == Autochan)
|
||||
radiomod = key
|
||||
break
|
||||
|
||||
@@ -327,23 +325,23 @@
|
||||
return -10
|
||||
|
||||
/mob/living/silicon/proc/remove_med_sec_hud()
|
||||
var/datum/atom_hud/secsensor = huds[sec_hud]
|
||||
var/datum/atom_hud/medsensor = huds[med_hud]
|
||||
var/datum/atom_hud/diagsensor = huds[d_hud]
|
||||
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
|
||||
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
|
||||
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
|
||||
secsensor.remove_hud_from(src)
|
||||
medsensor.remove_hud_from(src)
|
||||
diagsensor.remove_hud_from(src)
|
||||
|
||||
/mob/living/silicon/proc/add_sec_hud()
|
||||
var/datum/atom_hud/secsensor = huds[sec_hud]
|
||||
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
|
||||
secsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/silicon/proc/add_med_hud()
|
||||
var/datum/atom_hud/medsensor = huds[med_hud]
|
||||
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
|
||||
medsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/silicon/proc/add_diag_hud()
|
||||
var/datum/atom_hud/diagsensor = huds[d_hud]
|
||||
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
|
||||
diagsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/silicon/proc/sensor_mode()
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
|
||||
|
||||
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(prob(damage))
|
||||
for(var/mob/living/N in buckled_mobs)
|
||||
@@ -44,7 +45,6 @@
|
||||
adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/silicon/attack_paw(mob/living/user)
|
||||
return attack_hand(user)
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if("grab")
|
||||
if(grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
|
||||
vore_attack(M, pulling)
|
||||
else
|
||||
grabbedby(M)
|
||||
grabbedby(M)
|
||||
|
||||
if("harm", "disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
@@ -63,25 +60,25 @@
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..() && stat != DEAD) //successful larva bite
|
||||
. = ..()
|
||||
if(. && stat != DEAD) //successful larva bite
|
||||
var/damage = rand(5, 10)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
attack_threshold_check(damage)
|
||||
return 1
|
||||
. = attack_threshold_check(damage)
|
||||
if(.)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
|
||||
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
attack_threshold_check(damage, M.melee_damage_type)
|
||||
return 1
|
||||
return attack_threshold_check(damage, M.melee_damage_type)
|
||||
|
||||
/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(15, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 35)
|
||||
attack_threshold_check(damage)
|
||||
return 1
|
||||
return attack_threshold_check(damage)
|
||||
|
||||
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = "melee")
|
||||
var/temp_damage = damage
|
||||
@@ -92,8 +89,10 @@
|
||||
|
||||
if(temp_damage >= 0 && temp_damage <= force_threshold)
|
||||
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
||||
return FALSE
|
||||
else
|
||||
apply_damage(damage, damagetype, null, getarmor(null, armorcheck))
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
|
||||
if(!Proj)
|
||||
@@ -136,4 +135,4 @@
|
||||
visual_effect_icon = ATTACK_EFFECT_PUNCH
|
||||
else
|
||||
visual_effect_icon = ATTACK_EFFECT_SMASH
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
verb_ask = "queries"
|
||||
verb_exclaim = "declares"
|
||||
verb_yell = "alarms"
|
||||
initial_languages = list(/datum/language/common, /datum/language/machine)
|
||||
bubble_icon = "machine"
|
||||
|
||||
faction = list("neutral", "silicon" , "turret")
|
||||
@@ -118,7 +119,7 @@
|
||||
..()
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
//This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
|
||||
access_card.access += access_robotics
|
||||
access_card.access += GLOB.access_robotics
|
||||
set_custom_texts()
|
||||
Radio = new/obj/item/device/radio(src)
|
||||
if(radio_key)
|
||||
@@ -131,7 +132,7 @@
|
||||
|
||||
//Adds bot to the diagnostic HUD system
|
||||
prepare_huds()
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC]
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
|
||||
diag_hud.add_to_hud(src)
|
||||
diag_hud_set_bothealth()
|
||||
diag_hud_set_botstat()
|
||||
@@ -140,6 +141,9 @@
|
||||
//Gives a HUD view to player bots that use a HUD.
|
||||
activate_data_hud()
|
||||
|
||||
grant_language(/datum/language/common)
|
||||
grant_language(/datum/language/machine)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/update_canmove()
|
||||
. = ..()
|
||||
@@ -323,30 +327,29 @@
|
||||
if((!on) || (!message))
|
||||
return
|
||||
if(channel && Radio.channels[channel])// Use radio if we have channel key
|
||||
Radio.talk_into(src, message, channel, get_spans())
|
||||
Radio.talk_into(src, message, channel, get_spans(), get_default_language())
|
||||
else
|
||||
say(message)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/get_spans()
|
||||
return ..() | SPAN_ROBOT
|
||||
|
||||
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans)
|
||||
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
|
||||
switch(message_mode)
|
||||
if(MODE_HEADSET)
|
||||
Radio.talk_into(src, message, , spans)
|
||||
Radio.talk_into(src, message, , spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
if(MODE_DEPARTMENT)
|
||||
Radio.talk_into(src, message, message_mode, spans)
|
||||
Radio.talk_into(src, message, message_mode, spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
if(message_mode in radiochannels)
|
||||
Radio.talk_into(src, message, message_mode, spans)
|
||||
if(message_mode in GLOB.radiochannels)
|
||||
Radio.talk_into(src, message, message_mode, spans, language)
|
||||
return REDUCE_RANGE
|
||||
return 0
|
||||
|
||||
@@ -607,7 +610,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
/mob/living/simple_animal/bot/proc/get_next_patrol_target()
|
||||
// search the beacon list for the next target in the list.
|
||||
for(var/obj/machinery/navbeacon/NB in navbeacons["[z]"])
|
||||
for(var/obj/machinery/navbeacon/NB in GLOB.navbeacons["[z]"])
|
||||
if(NB.location == next_destination) //Does the Beacon location text match the destination?
|
||||
destination = new_destination //We now know the name of where we want to go.
|
||||
patrol_target = NB.loc //Get its location and set it as the target.
|
||||
@@ -615,7 +618,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/bot/proc/find_nearest_beacon()
|
||||
for(var/obj/machinery/navbeacon/NB in navbeacons["[z]"])
|
||||
for(var/obj/machinery/navbeacon/NB in GLOB.navbeacons["[z]"])
|
||||
var/dist = get_dist(src, NB)
|
||||
if(nearest_beacon) //Loop though the beacon net to find the true closest beacon.
|
||||
//Ignore the beacon if were are located on it.
|
||||
@@ -922,5 +925,5 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
//If a bot has its own HUD (for player bots), provide it.
|
||||
if(!data_hud_type)
|
||||
return
|
||||
var/datum/atom_hud/datahud = huds[data_hud_type]
|
||||
var/datum/atom_hud/datahud = GLOB.huds[data_hud_type]
|
||||
datahud.add_hud_to(src)
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
req_one_access = list(access_janitor, access_robotics)
|
||||
req_one_access = list(GLOB.access_janitor, GLOB.access_robotics)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/get_controls(mob/user)
|
||||
|
||||
@@ -419,8 +419,7 @@
|
||||
return
|
||||
build_step++
|
||||
to_chat(user, "<span class='notice'>You complete the Securitron! Beep boop.</span>")
|
||||
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot
|
||||
S.loc = get_turf(src)
|
||||
var/mob/living/simple_animal/bot/secbot/S = new /mob/living/simple_animal/bot/secbot(get_turf(src))
|
||||
S.name = created_name
|
||||
S.baton_type = I.type
|
||||
qdel(I)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
shot_delay = 6//Longer shot delay because JESUS CHRIST
|
||||
check_records = 0//Don't actively target people set to arrest
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
bot_core.req_access = list(access_maint_tunnels, access_theatre)
|
||||
bot_core.req_access = list(GLOB.access_maint_tunnels, GLOB.access_theatre)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
@@ -67,7 +67,7 @@
|
||||
name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
|
||||
|
||||
//SECHUD
|
||||
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/turn_on()
|
||||
|
||||
@@ -387,7 +387,7 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/floorbot
|
||||
req_one_access = list(access_construction, access_robotics)
|
||||
req_one_access = list(GLOB.access_construction, GLOB.access_robotics)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A)
|
||||
if(isturf(A))
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/assess_patient(mob/living/carbon/C)
|
||||
//Time to see if they need medical help!
|
||||
if(C.stat == 2)
|
||||
if(C.stat == DEAD || (C.status_flags & FAKEDEATH))
|
||||
return 0 //welp too late for them!
|
||||
|
||||
if(C.suiciding)
|
||||
@@ -404,7 +404,7 @@
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
if(C.stat == 2)
|
||||
if(C.stat == DEAD || (C.status_flags & FAKEDEATH))
|
||||
var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/mno.ogg',"Live, damnit! LIVE!" = 'sound/voice/mlive.ogg',"I...I've never lost a patient before. Not today, I mean." = 'sound/voice/mlost.ogg')
|
||||
var/message = pick(messagevoice)
|
||||
speak(message)
|
||||
@@ -496,7 +496,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/check_overdose(mob/living/carbon/patient,reagent_id,injection_amount)
|
||||
var/datum/reagent/R = chemical_reagents_list[reagent_id]
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_id]
|
||||
if(!R.overdose_threshold) //Some chems do not have an OD threshold
|
||||
return 0
|
||||
var/current_volume = patient.reagents.get_reagent_amount(reagent_id)
|
||||
@@ -545,4 +545,4 @@
|
||||
declare_cooldown = 0
|
||||
|
||||
/obj/machinery/bot_core/medbot
|
||||
req_one_access =list(access_medical, access_robotics)
|
||||
req_one_access =list(GLOB.access_medical, GLOB.access_robotics)
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
// Navigates via floor navbeacons
|
||||
// Remote Controlled from QM's PDA
|
||||
|
||||
var/global/mulebot_count = 0
|
||||
|
||||
#define SIGH 0
|
||||
#define ANNOYED 1
|
||||
#define DELIGHT 2
|
||||
@@ -58,10 +56,10 @@ var/global/mulebot_count = 0
|
||||
cell.charge = 2000
|
||||
cell.maxcharge = 2000
|
||||
|
||||
spawn(10) // must wait for map loading to finish
|
||||
mulebot_count += 1
|
||||
if(!suffix)
|
||||
set_suffix("#[mulebot_count]")
|
||||
var/static/mulebot_count = 0
|
||||
mulebot_count += 1
|
||||
if(!suffix)
|
||||
set_suffix("#[mulebot_count]")
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/Destroy()
|
||||
unload(0)
|
||||
@@ -165,7 +163,7 @@ var/global/mulebot_count = 0
|
||||
ui_interact(user)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "mulebot", name, 600, 375, master_ui, state)
|
||||
@@ -231,7 +229,7 @@ var/global/mulebot_count = 0
|
||||
if(mode == BOT_IDLE || mode == BOT_DELIVER)
|
||||
start_home()
|
||||
if("destination")
|
||||
var/new_dest = input(user, "Enter Destination:", name, destination) as null|anything in deliverybeacontags
|
||||
var/new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags
|
||||
if(new_dest)
|
||||
set_destination(new_dest)
|
||||
if("setid")
|
||||
@@ -239,7 +237,7 @@ var/global/mulebot_count = 0
|
||||
if(new_id)
|
||||
set_suffix(new_id)
|
||||
if("sethome")
|
||||
var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in deliverybeacontags
|
||||
var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags
|
||||
if(new_home)
|
||||
home_destination = new_home
|
||||
if("unload")
|
||||
@@ -686,7 +684,7 @@ var/global/mulebot_count = 0
|
||||
if(!on || wires.is_cut(WIRE_BEACON))
|
||||
return
|
||||
|
||||
for(var/obj/machinery/navbeacon/NB in deliverybeacons)
|
||||
for(var/obj/machinery/navbeacon/NB in GLOB.deliverybeacons)
|
||||
if(NB.location == new_destination) // if the beacon location matches the set destination
|
||||
// the we will navigate there
|
||||
destination = new_destination
|
||||
@@ -754,4 +752,4 @@ var/global/mulebot_count = 0
|
||||
#undef DELIGHT
|
||||
|
||||
/obj/machinery/bot_core/mulebot
|
||||
req_access = list(access_cargo)
|
||||
req_access = list(GLOB.access_cargo)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user