Merge branch 'master' into turn-both-keys

Conflicts:
	tgui/assets/tgui.js
This commit is contained in:
Jack Edge
2016-07-08 19:49:12 +01:00
136 changed files with 3492 additions and 2343 deletions
+17 -10
View File
@@ -34,7 +34,7 @@
return
/client/proc/create_poll_function()
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice")
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice", "Instant Runoff Voting")|null
var/choice_amount = 0
switch(polltype)
if("Single Option")
@@ -48,6 +48,10 @@
choice_amount = input("How many choices should be allowed?","Select choice amount") as num|null
if(!choice_amount)
return
if ("Instant Runoff Voting")
polltype = POLLTYPE_IRV
else
return 0
var/starttime = SQLtime()
var/endtime = input("Set end time for poll as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than starting time for obvious reasons.", "Set end time", SQLtime()) as text
if(!endtime)
@@ -117,14 +121,15 @@
if(!option)
return pollid
option = sanitizeSQL(option)
var/percentagecalc
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/percentagecalc = 1
if (polltype != POLLTYPE_IRV)
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/minval = 0
var/maxval = 0
var/descmin = ""
@@ -160,9 +165,11 @@
var/err = query_polladd_option.ErrorMsg()
log_game("SQL ERROR adding new poll option to table. Error : \[[err]\]\n")
return pollid
switch(alert(" ",,"Add option","Finish"))
switch(alert(" ",,"Add option","Finish", "Cancel"))
if("Add option")
add_option = 1
if("Finish")
add_option = 0
else
return 0
return pollid
+91 -87
View File
@@ -17,11 +17,11 @@
C << 'sound/effects/adminhelp.ogg'
C << "<font color='red' size='4'><b>- AdminHelp Rejected! -</b></font>"
C << "<font color='red'><b>Your admin help was rejected.</b> The adminhelp verb has been returned to you so that you may try again</font>"
C << "<font color='red'><b>Your admin help was rejected.</b> The adminhelp verb has been returned to you so that you may try again.</font>"
C << "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting."
message_admins("[key_name_admin(usr)] Rejected [C.key]'s admin help. [C.key]'s Adminhelp verb has been returned to them")
log_admin("[key_name(usr)] Rejected [C.key]'s admin help")
message_admins("[key_name_admin(usr)] Rejected [C.key]'s admin help. [C.key]'s Adminhelp verb has been returned to them.")
log_admin("[key_name(usr)] Rejected [C.key]'s admin help.")
else if(href_list["stickyban"])
stickyban(href_list["stickyban"],href_list)
@@ -185,39 +185,39 @@
switch(bantype)
if(BANTYPE_PERMA)
if(!banckey || !banreason)
usr << "Not enough parameters (Requires ckey and reason)"
usr << "Not enough parameters (Requires ckey and reason)."
return
banduration = null
banjob = null
if(BANTYPE_TEMP)
if(!banckey || !banreason || !banduration)
usr << "Not enough parameters (Requires ckey, reason and duration)"
usr << "Not enough parameters (Requires ckey, reason and duration)."
return
banjob = null
if(BANTYPE_JOB_PERMA)
if(!banckey || !banreason || !banjob)
usr << "Not enough parameters (Requires ckey, reason and job)"
usr << "Not enough parameters (Requires ckey, reason and job)."
return
banduration = null
if(BANTYPE_JOB_TEMP)
if(!banckey || !banreason || !banjob || !banduration)
usr << "Not enough parameters (Requires ckey, reason and job)"
usr << "Not enough parameters (Requires ckey, reason and job)."
return
if(BANTYPE_APPEARANCE)
if(!banckey || !banreason)
usr << "Not enough parameters (Requires ckey and reason)"
usr << "Not enough parameters (Requires ckey and reason)."
return
banduration = null
banjob = null
if(BANTYPE_ADMIN_PERMA)
if(!banckey || !banreason)
usr << "Not enough parameters (Requires ckey and reason)"
usr << "Not enough parameters (Requires ckey and reason)."
return
banduration = null
banjob = null
if(BANTYPE_ADMIN_TEMP)
if(!banckey || !banreason || !banduration)
usr << "Not enough parameters (Requires ckey, reason and duration)"
usr << "Not enough parameters (Requires ckey, reason and duration)."
return
banjob = null
@@ -237,7 +237,7 @@
if(bancid)
banreason = "[banreason] (CUSTOM CID)"
else
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob")
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob.")
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
add_note(banckey, banreason, null, usr.ckey, 0)
@@ -255,8 +255,8 @@
if(EMERGENCY_AT_LEAST_DOCKED)
return
SSshuttle.emergency.request()
log_admin("[key_name(usr)] called the Emergency Shuttle")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
log_admin("[key_name(usr)] called the Emergency Shuttle.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station.</span>")
if("2")
if(EMERGENCY_AT_LEAST_DOCKED)
@@ -264,12 +264,12 @@
switch(SSshuttle.emergency.mode)
if(SHUTTLE_CALL)
SSshuttle.emergency.cancel()
log_admin("[key_name(usr)] sent the Emergency Shuttle back")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] sent the Emergency Shuttle back</span>")
log_admin("[key_name(usr)] sent the Emergency Shuttle back.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] sent the Emergency Shuttle back.</span>")
else
SSshuttle.emergency.cancel()
log_admin("[key_name(usr)] called the Emergency Shuttle")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>")
log_admin("[key_name(usr)] called the Emergency Shuttle.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] called the Emergency Shuttle to the station.</span>")
href_list["secrets"] = "check_antagonist"
@@ -280,9 +280,9 @@
var/timer = input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", SSshuttle.emergency.timeLeft() ) as num
SSshuttle.emergency.setTimer(timer*10)
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds")
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds.")
minor_announce("The emergency shuttle will reach its destination in [round(SSshuttle.emergency.timeLeft(600))] minutes.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds.</span>")
href_list["secrets"] = "check_antagonist"
else if(href_list["toggle_continuous"])
@@ -373,7 +373,7 @@
var/mob/M = locate(href_list["mob"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
var/delmob = 0
@@ -383,8 +383,8 @@
if("Yes")
delmob = 1
log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]</span>")
log_admin("[key_name(usr)] has used rudimentary transformation on [key_name(M)]. Transforming to [href_list["simplemake"]].; deletemob=[delmob]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]].; deletemob=[delmob]</span>")
switch(href_list["simplemake"])
if("observer")
@@ -482,13 +482,13 @@
return
minutes = CMinutes + mins
duration = GetExp(minutes)
reason = input(usr,"Please State Reason","Reason",reason2) as message
reason = input(usr,"Please State Reason.","Reason",reason2) as message
if(!reason)
return
if("No")
temp = 0
duration = "Perma"
reason = input(usr,"Please State Reason","Reason",reason2) as message
reason = input(usr,"Please State Reason.","Reason",reason2) as message
if(!reason)
return
@@ -521,17 +521,17 @@
if(banreason)
switch(alert("Reason: '[banreason]' Remove appearance ban?","Please Confirm","Yes","No"))
if("Yes")
ban_unban_log_save("[key_name(usr)] removed [key_name(M)]'s appearance ban")
log_admin("[key_name(usr)] removed [key_name(M)]'s appearance ban")
ban_unban_log_save("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
log_admin("[key_name(usr)] removed [key_name(M)]'s appearance ban.")
feedback_inc("ban_appearance_unban", 1)
DB_ban_unban(M.ckey, BANTYPE_APPEARANCE)
appearance_unban(M)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed [key_name_admin(M)]'s appearance ban.</span>")
M << "<span class='boldannounce'><BIG>[usr.client.ckey] has removed your appearance ban.</BIG></span>"
else switch(alert("Appearance ban [M.ckey]?",,"Yes","No", "Cancel"))
if("Yes")
var/reason = input(usr,"Please State Reason","Reason") as message
var/reason = input(usr,"Please State Reason.","Reason") as message
if(!reason)
return
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
@@ -540,7 +540,7 @@
DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason)
appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] appearance banned [key_name_admin(M)]</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] appearance banned [key_name_admin(M)].</span>")
M << "<span class='boldannounce'><BIG>You have been appearance banned by [usr.client.ckey].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
M << "<span class='danger'>Appearance ban can be lifted only upon request.</span>"
@@ -554,11 +554,11 @@
else if(href_list["jobban2"])
var/mob/M = locate(href_list["jobban2"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(!M.ckey) //sanity
usr << "This mob has no ckey"
usr << "This mob has no ckey."
return
var/dat = ""
@@ -963,14 +963,14 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
var/reason = input(usr,"Please State Reason","Reason") as message
var/reason = input(usr,"Please State Reason.","Reason") as message
if(!reason)
return
var/msg
for(var/job in notbannedlist)
ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes. reason: [reason]")
log_admin("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes")
log_admin("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes.")
feedback_inc("ban_job_tmp",1)
DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job)
if(M.client)
@@ -981,7 +981,7 @@
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>")
M << "<span class='boldannounce'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
M << "<span class='danger'>This jobban will be lifted in [mins] minutes.</span>"
@@ -1004,7 +1004,7 @@
else
msg += ", [job]"
add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].</span>")
M << "<span class='boldannounce'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='boldannounce'>The reason is: [reason]</span>"
M << "<span class='danger'>Jobban can be lifted only upon request.</span>"
@@ -1037,7 +1037,7 @@
else
continue
if(msg)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]</span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg].</span>")
M << "<span class='boldannounce'><BIG>You have been un-jobbanned by [usr.client.ckey] from [msg].</BIG></span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
@@ -1115,7 +1115,7 @@
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
var/reason = input(usr,"Please State Reason","Reason") as message
var/reason = input(usr,"Please State Reason.","Reason") as message
if(!reason)
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
@@ -1135,7 +1135,7 @@
del(M.client)
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
if("No")
var/reason = input(usr,"Please State Reason","Reason") as message
var/reason = input(usr,"Please State Reason.","Reason") as message
if(!reason)
return
switch(alert(usr,"IP ban?",,"Yes","No","Cancel"))
@@ -1272,11 +1272,11 @@
var/mob/living/carbon/human/H = locate(href_list["monkeyone"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
log_admin("[key_name(usr)] attempting to monkeyize [key_name(H)]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]</span>")
log_admin("[key_name(usr)] attempting to monkeyize [key_name(H)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)].</span>")
H.monkeyize()
else if(href_list["humanone"])
@@ -1285,11 +1285,11 @@
var/mob/living/carbon/monkey/Mo = locate(href_list["humanone"])
if(!istype(Mo))
usr << "This can only be used on instances of type /mob/living/carbon/monkey"
usr << "This can only be used on instances of type /mob/living/carbon/monkey."
return
log_admin("[key_name(usr)] attempting to humanize [key_name(Mo)]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(Mo)]</span>")
log_admin("[key_name(usr)] attempting to humanize [key_name(Mo)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(Mo)].</span>")
Mo.humanize()
else if(href_list["corgione"])
@@ -1298,11 +1298,11 @@
var/mob/living/carbon/human/H = locate(href_list["corgione"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
log_admin("[key_name(usr)] attempting to corgize [key_name(H)]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to corgize [key_name_admin(H)]</span>")
log_admin("[key_name(usr)] attempting to corgize [key_name(H)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] attempting to corgize [key_name_admin(H)].</span>")
H.corgize()
@@ -1312,7 +1312,7 @@
var/mob/M = locate(href_list["forcespeech"])
if(!ismob(M))
usr << "this can only be used on instances of type /mob"
usr << "this can only be used on instances of type /mob."
var/speech = input("What will [key_name(M)] say?.", "Force speech", "")// Don't need to sanitize, since it does that in say(), we also trust our admins.
if(!speech)
@@ -1328,10 +1328,10 @@
var/mob/M = locate(href_list["sendtoprison"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(istype(M, /mob/living/silicon/ai))
usr << "This cannot be used on instances of type /mob/living/silicon/ai"
usr << "This cannot be used on instances of type /mob/living/silicon/ai."
return
if(alert(usr, "Send [key_name(M)] to Prison?", "Message", "Yes", "No") != "Yes")
@@ -1376,10 +1376,10 @@
var/mob/M = locate(href_list["tdome1"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(istype(M, /mob/living/silicon/ai))
usr << "This cannot be used on instances of type /mob/living/silicon/ai"
usr << "This cannot be used on instances of type /mob/living/silicon/ai."
return
for(var/obj/item/I in M)
@@ -1406,10 +1406,10 @@
var/mob/M = locate(href_list["tdome2"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(istype(M, /mob/living/silicon/ai))
usr << "This cannot be used on instances of type /mob/living/silicon/ai"
usr << "This cannot be used on instances of type /mob/living/silicon/ai."
return
for(var/obj/item/I in M)
@@ -1436,10 +1436,10 @@
var/mob/M = locate(href_list["tdomeadmin"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(istype(M, /mob/living/silicon/ai))
usr << "This cannot be used on instances of type /mob/living/silicon/ai"
usr << "This cannot be used on instances of type /mob/living/silicon/ai."
return
M.Paralyse(5)
@@ -1459,10 +1459,10 @@
var/mob/M = locate(href_list["tdomeobserve"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
if(istype(M, /mob/living/silicon/ai))
usr << "This cannot be used on instances of type /mob/living/silicon/ai"
usr << "This cannot be used on instances of type /mob/living/silicon/ai."
return
for(var/obj/item/I in M)
@@ -1490,12 +1490,12 @@
var/mob/living/L = locate(href_list["revive"])
if(!istype(L))
usr << "This can only be used on instances of type /mob/living"
usr << "This can only be used on instances of type /mob/living."
return
L.revive(full_heal = 1, admin_revive = 1)
message_admins("<span class='danger'>Admin [key_name_admin(usr)] healed / revived [key_name_admin(L)]!</span>")
log_admin("[key_name(usr)] healed / Revived [key_name(L)]")
log_admin("[key_name(usr)] healed / Revived [key_name(L)].")
else if(href_list["makeai"])
if(!check_rights(R_SPAWN))
@@ -1503,11 +1503,11 @@
var/mob/living/carbon/human/H = locate(href_list["makeai"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
message_admins("<span class='danger'>Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!</span>")
log_admin("[key_name(usr)] AIized [key_name(H)]")
log_admin("[key_name(usr)] AIized [key_name(H)].")
H.AIize()
else if(href_list["makealien"])
@@ -1516,7 +1516,7 @@
var/mob/living/carbon/human/H = locate(href_list["makealien"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
usr.client.cmd_admin_alienize(H)
@@ -1527,7 +1527,7 @@
var/mob/living/carbon/human/H = locate(href_list["makeslime"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
usr.client.cmd_admin_slimeize(H)
@@ -1538,7 +1538,7 @@
var/mob/living/carbon/human/H = locate(href_list["makeblob"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
usr.client.cmd_admin_blobize(H)
@@ -1550,7 +1550,7 @@
var/mob/living/carbon/human/H = locate(href_list["makerobot"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
usr.client.cmd_admin_robotize(H)
@@ -1561,7 +1561,7 @@
var/mob/M = locate(href_list["makeanimal"])
if(istype(M, /mob/new_player))
usr << "This cannot be used on instances of type /mob/new_player"
usr << "This cannot be used on instances of type /mob/new_player."
return
usr.client.cmd_admin_animalize(M)
@@ -1571,8 +1571,8 @@
if(G)
var/newpoints = input("Set [G.name ] Gang's influence.","Set Influence",G.points) as null|num
if(newpoints)
message_admins("[key_name_admin(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints]</span>")
log_admin("[key_name(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints]</span>")
message_admins("[key_name_admin(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints].</span>")
log_admin("[key_name(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints].</span>")
G.points = newpoints
G.message_gangtools("Your gang now has [G.points] influence.")
@@ -1615,7 +1615,7 @@
else if(href_list["adminmoreinfo"])
var/mob/M = locate(href_list["adminmoreinfo"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
usr << "This can only be used on instances of type /mob."
return
var/location_description = ""
@@ -1726,7 +1726,7 @@
var/mob/living/carbon/human/H = locate(href_list["adminspawncookie"])
if(!ishuman(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
H.equip_to_slot_or_del( new /obj/item/weapon/reagent_containers/food/snacks/cookie(H), slot_l_hand )
@@ -1740,8 +1740,8 @@
H.update_inv_r_hand()//To ensure the icon appears in the HUD
else
H.update_inv_l_hand()
log_admin("[key_name(H)] got their cookie, spawned by [key_name(src.owner)]")
message_admins("[key_name(H)] got their cookie, spawned by [key_name(src.owner)]")
log_admin("[key_name(H)] got their cookie, spawned by [key_name(src.owner)].")
message_admins("[key_name(H)] got their cookie, spawned by [key_name(src.owner)].")
feedback_inc("admin_cookies_spawned",1)
H << "<span class='adminnotice'>Your prayers have been answered!! You received the <b>best cookie</b>!</span>"
H << 'sound/effects/pray_chaplain.ogg'
@@ -1756,11 +1756,13 @@
usr << "This can only be used on instances of type /mob/living/carbon/human"
return
if(!istype(H.ears, /obj/item/device/radio/headset))
usr << "The person you are trying to contact is not wearing a headset"
usr << "The person you are trying to contact is not wearing a headset."
return
message_admins("[src.owner] has started answering [key_name(H)]'s Centcomm request.")
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from Centcom", "")
if(!input)
message_admins("[src.owner] decided not to answer [key_name(H)]'s Centcomm request.")
return
src.owner << "You sent [input] to [H] via a secure channel."
@@ -1771,14 +1773,16 @@
else if(href_list["SyndicateReply"])
var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"])
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
usr << "This can only be used on instances of type /mob/living/carbon/human."
return
if(!istype(H.ears, /obj/item/device/radio/headset))
usr << "The person you are trying to contact is not wearing a headset"
usr << "The person you are trying to contact is not wearing a headset."
return
message_admins("[src.owner] has started answering [key_name(H)]'s syndicate request.")
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from The Syndicate", "")
if(!input)
message_admins("[src.owner] decided not to answer [key_name(H)]'s syndicate request.")
return
src.owner << "You sent [input] to [H] via a secure channel."
@@ -1891,10 +1895,10 @@
paths += path
if(!paths)
alert("The path list you sent is empty")
alert("The path list you sent is empty.")
return
if(length(paths) > 5)
alert("Select fewer object types, (max 5)")
alert("Select fewer object types, (max 5).")
return
var/list/offset = splittext(href_list["offset"],",")
@@ -1988,7 +1992,7 @@
src.access_news_network()
else if(href_list["ac_set_channel_name"])
src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")
src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "")
while (findtext(src.admincaster_feed_channel.channel_name," ") == 1)
src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1)
src.access_news_network()
@@ -2006,7 +2010,7 @@
if(src.admincaster_feed_channel.channel_name == "" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]" || check )
src.admincaster_screen=7
else
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
var/choice = alert("Please confirm Feed channel creation.","Network Channel Handler","Confirm","Cancel")
if(choice=="Confirm")
news_network.CreateFeedChannel(src.admincaster_feed_channel.channel_name, src.admin_signature, src.admincaster_feed_channel.locked, 1)
feedback_inc("newscaster_channels",1)
@@ -2018,11 +2022,11 @@
var/list/available_channels = list()
for(var/datum/newscaster/feed_channel/F in news_network.network_channels)
available_channels += F.channel_name
src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel.", "Network Channel Handler") in available_channels )
src.access_news_network()
else if(href_list["ac_set_new_message"])
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story", "Network Channel Handler", ""))
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", ""))
while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1)
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1)
src.access_news_network()
@@ -2069,13 +2073,13 @@
src.access_news_network()
else if(href_list["ac_set_wanted_name"])
src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person", "Network Security Handler", ""))
src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", ""))
while(findtext(src.admincaster_wanted_message.criminal," ") == 1)
src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1)
src.access_news_network()
else if(href_list["ac_set_wanted_desc"])
src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", ""))
while (findtext(src.admincaster_wanted_message.body," ") == 1)
src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1)
src.access_news_network()
@@ -2097,7 +2101,7 @@
src.access_news_network()
else if(href_list["ac_cancel_wanted"])
var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
news_network.deleteWanted()
src.admincaster_screen=17
@@ -2160,7 +2164,7 @@
src.access_news_network()
else if(href_list["ac_set_signature"])
src.admin_signature = adminscrub(input(usr, "Provide your desired signature", "Network Identity Handler", ""))
src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", ""))
src.access_news_network()
else if(href_list["ac_del_comment"])
@@ -2207,7 +2211,7 @@
message_admins("[key_name_admin(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
log_admin("[key_name(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
else
usr << "You may only use this when the game is running"
usr << "You may only use this when the game is running."
else if(href_list["create_outfit"])
if(!check_rights(R_ADMIN))
+2 -2
View File
@@ -24,8 +24,8 @@
T.break_tile()
target << "<span class='userdanger'>You're hit by bluespace artillery!</span>"
log_admin("[target.name] has been hit by Bluespace Artillery fired by [usr]")
message_admins("[target.name] has been hit by Bluespace Artillery fired by [usr]")
log_admin("[key_name(target)] has been hit by Bluespace Artillery fired by [key_name(usr)]")
message_admins("[ADMIN_LOOKUPFLW(target)] has been hit by Bluespace Artillery fired by [ADMIN_LOOKUPFLW(usr)]")
if(target.health <= 1)
target.gib(1, 1)
-1
View File
@@ -573,7 +573,6 @@ var/global/list/g_fancy_list_of_types = null
if(!ishuman(M))
alert("Invalid mob")
return
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/outfits = list("Naked","Custom","As Job...")
+7 -4
View File
@@ -15,8 +15,7 @@
/obj/item/device/assembly/igniter/Destroy()
qdel(sparks)
sparks = null
return ..()
. = ..()
/obj/item/device/assembly/igniter/activate()
if(!..())
@@ -27,8 +26,12 @@
sparks.start()
return 1
/obj/item/device/assembly/igniter/attack_self(mob/user)
activate()
add_fingerprint(user)
return
/obj/item/device/assembly/igniter/ignition_effect(atom/A, mob/user)
. = "<span class='notice'>[user] fiddles with [src], and manages to \
light [A].</span>"
activate()
add_fingerprint(user)
+127 -12
View File
@@ -4,6 +4,7 @@
#define FLAG_RETURN_TIME 200 // 20 seconds
#define INSTAGIB_RESPAWN 50 //5 seconds
#define DEFAULT_RESPAWN 150 //15 seconds
#define AMMO_DROP_LIFETIME 300
@@ -131,6 +132,8 @@
var/control_points = 0
var/control_points_to_win = 180
var/list/team_members = list()
var/list/spawned_mobs = list()
var/list/recently_dead_ckeys = list()
var/ctf_enabled = FALSE
var/ctf_gear = /datum/outfit/ctf
var/instagib_gear = /datum/outfit/ctf/instagib
@@ -157,6 +160,21 @@
poi_list.Remove(src)
..()
/obj/machinery/capture_the_flag/process()
for(var/i in spawned_mobs)
if(!i)
spawned_mobs -= i
continue
// Anyone in crit, automatically reap
var/mob/living/M = i
if(M.InCritical() || M.stat == DEAD)
ctf_dust_old(M)
else
// The changes that you've been hit with no shield but not
// instantly critted are low, but have some healing.
M.adjustBruteLoss(-1)
M.adjustFireLoss(-1)
/obj/machinery/capture_the_flag/red
name = "Red CTF Controller"
icon_state = "syndbeacon"
@@ -177,11 +195,12 @@
if(ticker.current_state != GAME_STATE_PLAYING)
return
if(user.ckey in team_members)
if(user.mind.current && user.mind.current.timeofdeath + respawn_cooldown > world.time)
if(user.ckey in recently_dead_ckeys)
user << "It must be more than [respawn_cooldown/10] seconds from your last death to respawn!"
return
var/client/new_team_member = user.client
dust_old(user)
if(user.mind && user.mind.current)
ctf_dust_old(user.mind.current)
spawn_team_member(new_team_member)
return
@@ -196,15 +215,20 @@
return
team_members |= user.ckey
var/client/new_team_member = user.client
dust_old(user)
if(user.mind && user.mind.current)
ctf_dust_old(user.mind.current)
spawn_team_member(new_team_member)
/obj/machinery/capture_the_flag/proc/dust_old(mob/user)
if(user.mind && user.mind.current && user.mind.current.z == src.z)
new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current))
new /obj/item/ammo_box/magazine/recharge/ctf (get_turf(user.mind.current))
user.mind.current.dust()
/obj/machinery/capture_the_flag/proc/ctf_dust_old(mob/living/body)
if(isliving(body) && body.z == src.z)
var/turf/T = get_turf(body)
new /obj/effect/ctf/ammo(T)
recently_dead_ckeys += body.ckey
addtimer(src, "clear_cooldown", respawn_cooldown, TRUE, body.ckey)
body.dust()
/obj/machinery/capture_the_flag/proc/clear_cooldown(var/ckey)
recently_dead_ckeys -= ckey
/obj/machinery/capture_the_flag/proc/spawn_team_member(client/new_team_member)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(get_turf(src))
@@ -212,6 +236,7 @@
M.key = new_team_member.key
M.faction += team
M.equipOutfit(ctf_gear)
spawned_mobs += M
/obj/machinery/capture_the_flag/Topic(href, href_list)
if(href_list["join"])
@@ -281,12 +306,15 @@
/obj/machinery/capture_the_flag/proc/stop_ctf()
ctf_enabled = FALSE
arena_cleared = FALSE
var/area/A = get_area(src)
for(var/i in mob_list)
var/mob/M = i
if((get_area(A) == A) && (M.ckey in team_members))
M.dust()
team_members.Cut()
spawned_mobs.Cut()
recently_dead_ckeys.Cut()
/obj/machinery/capture_the_flag/proc/instagib_mode()
for(var/obj/machinery/capture_the_flag/CTF in machines)
@@ -300,23 +328,43 @@
CTF.ctf_gear = initial(ctf_gear)
CTF.respawn_cooldown = DEFAULT_RESPAWN
/obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF
/obj/item/weapon/gun/projectile/automatic/pistol/deagle/ctf
desc = "This looks like it could really hurt in melee."
force = 75
/obj/item/weapon/gun/projectile/automatic/pistol/deagle/ctf/dropped()
. = ..()
addtimer(src, "floor_vanish", 1)
/obj/item/weapon/gun/projectile/automatic/pistol/deagle/ctf/proc/floor_vanish()
if(isturf(loc))
qdel(src)
/obj/item/weapon/gun/projectile/automatic/laser/ctf
mag_type = /obj/item/ammo_box/magazine/recharge/ctf
desc = "This looks like it could really hurt in melee."
force = 50
flags = NODROP | DROPDEL
/obj/item/ammo_box/magazine/recharge/ctf
ammo_type = /obj/item/ammo_casing/caseless/laser/ctf
/obj/item/ammo_box/magazine/recharge/ctf/dropped()
. = ..()
addtimer(src, "floor_vanish", 1)
/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish()
if(isturf(loc))
qdel(src)
/obj/item/ammo_casing/caseless/laser/ctf
projectile_type = /obj/item/projectile/beam/ctf
/obj/item/projectile/beam/ctf
damage = 150
icon_state = "omnilaser"
// RED TEAM GUNS
/obj/item/weapon/gun/projectile/automatic/laser/ctf/red
mag_type = /obj/item/ammo_box/magazine/recharge/ctf/red
@@ -330,6 +378,8 @@
/obj/item/projectile/beam/ctf/red
icon_state = "laser"
// BLUE TEAM GUNS
/obj/item/weapon/gun/projectile/automatic/laser/ctf/blue
mag_type = /obj/item/ammo_box/magazine/recharge/ctf/blue
@@ -344,17 +394,35 @@
/datum/outfit/ctf
name = "CTF"
/obj/item/device/radio/headset
ears = /obj/item/device/radio/headset
uniform = /obj/item/clothing/under/syndicate
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
id = /obj/item/weapon/card/id/syndicate
belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle/CTF
belt = /obj/item/weapon/gun/projectile/automatic/pistol/deagle/ctf
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf
/datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
if(visualsOnly)
return
var/list/no_drops = list()
var/obj/item/weapon/card/id/W = H.wear_id
no_drops += W
W.registered_name = H.real_name
W.update_label(W.registered_name, W.assignment)
// The shielded hardsuit is already NODROP
no_drops += H.get_item_by_slot(slot_gloves)
no_drops += H.get_item_by_slot(slot_shoes)
no_drops += H.get_item_by_slot(slot_w_uniform)
no_drops += H.get_item_by_slot(slot_ears)
for(var/i in no_drops)
var/obj/item/I = i
I.flags |= NODROP
/datum/outfit/ctf/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill
shoes = /obj/item/clothing/shoes/jackboots/fast
@@ -363,6 +431,8 @@
ears = /obj/item/device/radio/headset/syndicate/alt
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/red
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf/red
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
/datum/outfit/ctf/red/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill/red
@@ -372,17 +442,21 @@
ears = /obj/item/device/radio/headset/headset_cent/commander
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf/blue
r_hand = /obj/item/weapon/gun/projectile/automatic/laser/ctf/blue
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
/datum/outfit/ctf/blue/instagib
r_hand = /obj/item/weapon/gun/energy/laser/instakill/blue
shoes = /obj/item/clothing/shoes/jackboots/fast
/datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H)
..()
var/obj/item/device/radio/R = H.ears
R.set_frequency(SYND_FREQ)
R.freqlock = 1
/datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H)
..()
var/obj/item/device/radio/R = H.ears
R.set_frequency(CENTCOM_FREQ)
R.freqlock = 1
@@ -406,7 +480,7 @@
/obj/structure/divine/trap/ctf/trap_effect(mob/living/L)
if(!(src.team in L.faction))
L << "<span class='danger'><B>Stay out of the enemy spawn!</B></span>"
L.dust()
L.death()
/obj/structure/divine/trap/ctf/red
@@ -430,7 +504,48 @@
invisibility = INVISIBILITY_OBSERVER
alpha = 100
/obj/effect/ctf/ammo
name = "ammo pickup"
desc = "You like revenge, right? Everybody likes revenge! Well, \
let's go get some!"
icon = 'icons/effects/effects.dmi'
icon_state = "at_shield1"
layer = ABOVE_MOB_LAYER
alpha = 255
invisibility = 0
/obj/effect/ctf/ammo/New()
..()
QDEL_IN(src, AMMO_DROP_LIFETIME)
/obj/effect/ctf/ammo/Crossed(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/Bump(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/Bumped(atom/movable/AM)
reload(AM)
/obj/effect/ctf/ammo/proc/reload(mob/living/M)
if(!ishuman(M))
return
for(var/obj/machinery/capture_the_flag/CTF in machines)
if(M in CTF.spawned_mobs)
var/outfit = CTF.ctf_gear
var/datum/outfit/O = new outfit
for(var/obj/item/weapon/gun/G in M)
M.unEquip(G)
qdel(G)
O.equip(M)
M << "<span class='notice'>Ammunition reloaded!</span>"
playsound(get_turf(M), 'sound/weapons/shotgunpump.ogg', 50, 1, -1)
qdel(src)
break
/obj/effect/ctf/dead_barricade
name = "dead barrier"
desc = "It provided cover in fire fights. And now it's gone."
icon = 'icons/obj/objects.dmi'
icon_state = "barrier0"
+27 -26
View File
@@ -17,58 +17,59 @@
name = "Lumbermill"
icon_state = "away3"
/*Cabin code*/
/obj/structure/fireplace
name = "fireplace"
/obj/structure/firepit
name = "firepit"
desc = "warm and toasty"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "fireplace-active"
icon = 'icons/obj/fireplace.dmi'
icon_state = "firepit-active"
density = 0
var/active = 1
/obj/structure/fireplace/initialize()
/obj/structure/firepit/initialize()
..()
toggleFireplace()
toggleFirepit()
/obj/structure/fireplace/attack_hand(mob/living/user)
/obj/structure/firepit/attack_hand(mob/living/user)
if(active)
active = 0
toggleFireplace()
toggleFirepit()
else
..()
/obj/structure/fireplace/attackby(obj/item/W,mob/living/user,params)
/obj/structure/firepit/attackby(obj/item/W,mob/living/user,params)
if(!active)
if(W.is_hot())
active = 1
toggleFireplace()
var/msg = W.ignition_effect(src, user)
if(msg)
active = TRUE
visible_message(msg)
toggleFirepit()
else
return ..()
else
W.fire_act()
/obj/structure/fireplace/proc/toggleFireplace()
/obj/structure/firepit/proc/toggleFirepit()
if(active)
SetLuminosity(8)
icon_state = "fireplace-active"
icon_state = "firepit-active"
else
SetLuminosity(0)
icon_state = "fireplace"
icon_state = "firepit"
/obj/structure/fireplace/extinguish()
/obj/structure/firepit/extinguish()
if(active)
active = 0
toggleFireplace()
active = FALSE
toggleFirepit()
/obj/structure/fireplace/fire_act()
/obj/structure/firepit/fire_act()
if(!active)
active = 1
toggleFireplace()
active = TRUE
toggleFirepit()
//other Cabin Stuff//
/obj/machinery/recycler/lumbermill
name = "lumbermill saw"
+5
View File
@@ -224,6 +224,11 @@ You can set verify to TRUE if you want send() to sleep until the client has the
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
)
/datum/asset/simple/IRV
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
"jquery-1.10.2.min.js" = 'html/IRV/jquery-1.10.2.min.js'
)
//Registers HTML Interface assets.
/datum/asset/HTML_interface/register()
+21 -18
View File
@@ -4,6 +4,7 @@
var/list/categories = list(CAT_WEAPON,CAT_AMMO,CAT_ROBOT,CAT_FOOD,CAT_MISC,CAT_PRIMAL)
var/datum/action/innate/crafting/button
var/display_craftable_only = FALSE
var/display_compact = FALSE
@@ -239,24 +240,26 @@
/datum/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = not_incapacitated_turf_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 600, 800, master_ui, state)
ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state)
ui.open()
/datum/personal_crafting/ui_data(mob/user)
var/list/data = list()
var/cur_category = categories[viewing_category]
data["busy"] = busy
data["prev_cat"] = categories[prev_cat()]
data["category"] = categories[viewing_category]
data["category"] = cur_category
data["next_cat"] = categories[next_cat()]
data["display_craftable_only"] = display_craftable_only
data["display_compact"] = display_compact
var/list/surroundings = get_surroundings(user)
var/list/can_craft = list()
var/list/cant_craft = list()
for(var/rec in crafting_recipes)
var/datum/crafting_recipe/R = rec
if(R.category != categories[viewing_category])
if(R.category != cur_category)
continue
if(check_contents(R, surroundings))
can_craft += list(build_recipe_data(R))
@@ -294,6 +297,10 @@
display_craftable_only = !display_craftable_only
usr << "<span class='notice'>You will now [display_craftable_only ? "only see recipes you can craft":"see all recipes"].</span>"
. = TRUE
if("toggle_compact")
display_compact = !display_compact
usr << "<span class='notice'>Crafting menu is now [display_compact? "compact" : "full size"].</span>"
. = TRUE
//Next works nicely with modular arithmetic
@@ -318,27 +325,23 @@
var/tool_text = ""
var/catalyst_text = ""
for(var/A in R.reqs)
if(ispath(A, /obj))
var/obj/O = A
req_text += " [R.reqs[A]] [initial(O.name)],"
else if(ispath(A, /datum/reagent))
var/datum/reagent/RE = A
req_text += " [R.reqs[A]] [initial(RE.name)],"
for(var/a in R.reqs)
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
//Also these are typepaths so sadly we can't just do "[a]"
var/atom/A = a
req_text += " [R.reqs[A]] [initial(A.name)],"
req_text = replacetext(req_text,",","",-1)
data["req_text"] = req_text
for(var/C in R.chem_catalysts)
if(ispath(C, /datum/reagent))
var/datum/reagent/RE = C
catalyst_text += " [R.chem_catalysts[C]] [initial(RE.name)],"
for(var/a in R.chem_catalysts)
var/atom/A = a //cheat-typecast
catalyst_text += " [R.chem_catalysts[A]] [initial(A.name)],"
catalyst_text = replacetext(catalyst_text,",","",-1)
data["catalyst_text"] = catalyst_text
for(var/O in R.tools)
if(ispath(O, /obj))
var/obj/T = O
tool_text += " [R.tools[O]] [initial(T.name)],"
for(var/a in R.tools)
var/atom/A = a //cheat-typecast
tool_text += " [R.tools[A]] [initial(A.name)],"
tool_text = replacetext(tool_text,",","",-1)
data["tool_text"] = tool_text
+82 -41
View File
@@ -109,23 +109,36 @@
/turf/open/floor/vines/ChangeTurf(turf/open/floor/T)
for(var/obj/effect/spacevine/SV in src)
qdel(SV)
..()
. = ..()
UpdateAffectingLights()
/datum/spacevine_mutation/space_covering
var/static/list/coverable_turfs
/datum/spacevine_mutation/space_covering/New()
. = ..()
if(!coverable_turfs)
coverable_turfs = typecacheof(list(
/turf/open/space
))
coverable_turfs -= typecacheof(list(
/turf/open/space/transit
))
/datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/space))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/floor/vines)
process_mutation(holder)
/datum/spacevine_mutation/space_covering/process_mutation(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/space))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/floor/vines)
var/turf/T = get_turf(holder)
if(is_type_in_typecache(T, coverable_turfs))
var/currtype = T.type
T.ChangeTurf(/turf/open/floor/vines)
T.baseturf = currtype
/datum/spacevine_mutation/space_covering/on_death(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/floor/vines))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/space)
var/turf/T = get_turf(holder)
if(istype(T, /turf/open/floor/vines))
T.ChangeTurf(T.baseturf)
/datum/spacevine_mutation/bluespace
name = "bluespace"
@@ -155,12 +168,13 @@
/datum/spacevine_mutation/toxicity/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
if(issilicon(crosser))
return
if(prob(severity) && istype(crosser))
if(prob(severity) && istype(crosser) && !isvineimmune(crosser))
crosser << "<span class='alert'>You accidently touch the vine and feel a strange sensation.</span>"
crosser.adjustToxLoss(5)
/datum/spacevine_mutation/toxicity/on_eat(obj/effect/spacevine/holder, mob/living/eater)
eater.adjustToxLoss(5)
if(!isvineimmune(eater))
eater.adjustToxLoss(5)
/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!!
name = "explosive"
@@ -173,8 +187,7 @@
qdel(src)
else
. = 1
spawn(5)
qdel(src)
QDEL_IN(src, 5)
/datum/spacevine_mutation/explosive/on_death(obj/effect/spacevine/holder, mob/hitter, obj/item/I)
explosion(holder.loc, 0, 0, severity, 0, 0)
@@ -190,6 +203,8 @@
/datum/spacevine_mutation/fire_proof/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(I && I.damtype == "fire")
. = 0
else
. = expected_damage
/datum/spacevine_mutation/vine_eating
name = "vine eating"
@@ -208,10 +223,10 @@
quality = NEGATIVE
/datum/spacevine_mutation/aggressive_spread/on_spread(obj/effect/spacevine/holder, turf/target)
target.ex_act(severity, src)
target.ex_act(severity, src) // vine immunity handled at /mob/ex_act
/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/effect/spacevine/holder, mob/living/buckled)
buckled.ex_act(severity)
buckled.ex_act(severity, src)
/datum/spacevine_mutation/transparency
name = "transparent"
@@ -289,16 +304,17 @@
quality = NEGATIVE
/datum/spacevine_mutation/thorns/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
if(prob(severity) && istype(crosser))
if(prob(severity) && istype(crosser) && !isvineimmune(holder))
var/mob/living/M = crosser
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
/datum/spacevine_mutation/thorns/on_hit(obj/effect/spacevine/holder, mob/living/hitter)
if(prob(severity) && istype(hitter))
/datum/spacevine_mutation/thorns/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(prob(severity) && istype(hitter) && !isvineimmune(holder))
var/mob/living/M = hitter
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
. = expected_damage
/datum/spacevine_mutation/woodening
name = "hardened"
@@ -308,15 +324,14 @@
/datum/spacevine_mutation/woodening/on_grow(obj/effect/spacevine/holder)
if(holder.energy)
holder.density = 1
holder.maxhealth = 100
holder.health = holder.maxhealth
/datum/spacevine_mutation/woodening/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(!expected_damage)
return
if(hitter)
if(I)
. = I.force * 2
else
. = 8
/datum/spacevine_mutation/woodening/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(I.is_sharp())
. = expected_damage * 0.5
else
. = expected_damage
/datum/spacevine_mutation/flowering
name = "flowering"
@@ -343,6 +358,8 @@
layer = SPACEVINE_LAYER
mouse_opacity = 2 //Clicking anywhere on the turf is good enough
pass_flags = PASSTABLE | PASSGRILLE
var/health = 50
var/maxhealth = 50
var/energy = 0
var/obj/effect/spacevine_controller/master = null
var/list/mutations = list()
@@ -385,22 +402,33 @@
if (!W || !user || !W.type)
return
user.changeNext_move(CLICK_CD_MELEE)
var/force = W.force
var/override = W.force
if(W.is_sharp())
override = 100
if(istype(W, /obj/item/weapon/scythe))
var/local_override = override
force = force * 4
for(var/obj/effect/spacevine/B in orange(1,src))
for(var/datum/spacevine_mutation/SM in mutations)
local_override = SM.on_hit(src, user, W, local_override)
if(prob(local_override))
qdel(B)
B.health = health - force
if(B.health < 1)
qdel(B)
health = health - force
if(health < 1)
qdel(src)
return
if(W.is_sharp())
force = force * 4
if(W && W.damtype == "fire")
force = force * 4
for(var/datum/spacevine_mutation/SM in mutations)
override = SM.on_hit(src, user, W, override) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
force = SM.on_hit(src, user, W, force) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
if(prob(override))
health = health - force
if(health < 1)
qdel(src)
..()
@@ -482,7 +510,7 @@
/obj/effect/spacevine_controller/process()
if(!vines)
qdel(src) //space vines exterminated. Remove the controller
qdel(src) //space vines exterminated. Remove the controller
return
if(!growth_queue)
qdel(src) //Sanity check
@@ -494,7 +522,7 @@
var/i = 0
var/list/obj/effect/spacevine/queue_end = list()
for( var/obj/effect/spacevine/SV in growth_queue )
for(var/obj/effect/spacevine/SV in growth_queue)
if(qdeleted(SV))
continue
i++
@@ -531,12 +559,12 @@
if(!has_buckled_mobs() && prob(25))
for(var/mob/living/V in src.loc)
entangle(V)
if(buckled_mobs.len)
if(buckled_mobs && buckled_mobs.len)
break //only capture one mob at a time
/obj/effect/spacevine/proc/entangle(mob/living/V)
if(!V)
if(!V || isvineimmune(V))
return
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_buckle(src, V)
@@ -570,3 +598,16 @@
override += SM.process_temperature(src, temp, volume)
if(!override)
qdel(src)
/obj/effect/spacevine/CanPass(atom/movable/mover, turf/target, height=0)
if(isvineimmune(mover))
. = TRUE
else
. = ..()
/proc/isvineimmune(atom/A)
. = FALSE
if(isliving(A))
var/mob/living/M = A
if(("vines" in M.faction) || ("plants" in M.faction))
. = TRUE
@@ -212,7 +212,6 @@
var/datum/browser/popup = new(user, "microwave", name, 300, 300)
popup.set_content(dat)
popup.open()
return
/***********************************
* Microwave Menu Handling/Cooking
@@ -340,4 +339,3 @@
if ("dispose")
dispose()
updateUsrDialog()
return
+2 -2
View File
@@ -34,7 +34,7 @@
// Stronger reagents must always come first to avoid being displaced by weaker ones.
// Total amount of any reagent in plant is calculated by formula: 1 + round(potency * multiplier)
var/innate_yieldmod = 1 //modifier for yield, seperate to the one in Hydro trays, as that one is SPECIFICALLY for nutriment/chems (which means it's constantly reset)
var/innate_yieldmod = 0 //modifier for yield, seperate to the one in Hydro trays, as that one is SPECIFICALLY for nutriment/chems (which means it's constantly reset)
//This is added onto the yield mod of the hydro tray, yield *= (parent.yieldmod+innate_yieldmod)
var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth
@@ -269,4 +269,4 @@
if(seed.icon_harvest) // mushrooms have no grown sprites, same for items with no product
if(!(seed.icon_harvest in states))
world << "[seed.name] ([seed.type]) lacks the [seed.icon_harvest] icon!"
world << "[seed.name] ([seed.type]) lacks the [seed.icon_harvest] icon!"
+3 -2
View File
@@ -790,6 +790,7 @@
name = "necropolis wall"
desc = "A seemingly impenetrable wall."
icon = 'icons/turf/walls.dmi'
icon_state = "necro"
explosion_block = 50
baseturf = /turf/closed/indestructible/necropolis
@@ -797,10 +798,10 @@
name = "necropolis floor"
desc = "It's regarding you suspiciously."
icon = 'icons/turf/floors.dmi'
icon_state = "floor"
icon_state = "necro1"
baseturf = /turf/open/indestructible/necropolis
/turf/open/indestructible/necropolis/New()
..()
if(prob(12))
icon_state = "necropolis[rand(1,2)]"
icon_state = "necro[rand(2,3)]"
+1
View File
@@ -72,6 +72,7 @@
var/forceProcess = 0
var/processTime = 8
var/lastProc = 0
var/showexaminetext = 1 //If we show our telltale examine text
var/list/knownStrings = list()
@@ -33,8 +33,7 @@
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
. = ..(gibbed)
if(mind && mind.devilinfo)
spawn(0)
mind.devilinfo.beginResurrectionCheck(src)
addtimer(mind.devilinfo, "beginResurrectionCheck", 0, FALSE, src)
/mob/living/carbon/human/proc/makeSkeleton()
status_flags |= DISFIGURED
@@ -289,7 +289,9 @@
if(getorgan(/obj/item/organ/brain))
if(istype(src,/mob/living/carbon/human/interactive))
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
var/mob/living/carbon/human/interactive/auto = src
if(auto.showexaminetext)
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
else if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
else if(!client)
@@ -120,6 +120,8 @@
var/b_loss = null
var/f_loss = null
var/bomb_armor = getarmor(null, "bomb")
if(istype(ex_target, /datum/spacevine_mutation) && isvineimmune(src))
return
switch (severity)
if (1)
@@ -104,6 +104,15 @@
heatmod = 1.5
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/plant
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
C.faction |= "plants"
C.faction |= "vines"
/datum/species/pod/on_species_loss(mob/living/carbon/C)
. = ..()
C.faction -= "plants"
C.faction -= "vines"
/datum/species/pod/spec_life(mob/living/carbon/human/H)
if(H.stat == DEAD)
@@ -146,8 +155,6 @@
H.show_message("<span class='userdanger'>The radiation beam singes you!</span>")
if(/obj/item/projectile/energy/florayield)
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
return
/*
SHADOWPEOPLE
+2
View File
@@ -54,7 +54,9 @@
message_type=DEADCHAT_DEATHRATTLE)
if(mind)
mind.store_memory("Time of death: [tod]", 0)
var/list/scripture_states = get_scripture_states()
living_mob_list -= src
scripture_unlock_alert(scripture_states)
if(!gibbed)
dead_mob_list += src
else if(buckled)
+3 -1
View File
@@ -225,7 +225,9 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/InCritical()
return (src.health < 0 && src.health > -95 && stat == UNCONSCIOUS)
/mob/living/ex_act(severity, target)
/mob/living/ex_act(severity, origin)
if(istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
flash_eyes()
+27 -8
View File
@@ -45,7 +45,6 @@ var/list/ai_list = list()
//MALFUNCTION
var/datum/module_picker/malf_picker
var/list/datum/AI_Module/current_modules = list()
var/fire_res_on_core = 0
var/can_dominate_mechs = 0
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
@@ -157,7 +156,9 @@ var/list/ai_list = list()
shuttle_caller_list -= src
SSshuttle.autoEvac()
qdel(eyeobj) // No AI, no Eye
return ..()
malfhack = null
. = ..()
/mob/living/silicon/ai/verb/pick_icon()
@@ -320,8 +321,6 @@ var/list/ai_list = list()
if(C)
C.post_status("shuttle")
return
/mob/living/silicon/ai/cancel_camera()
src.view_core()
@@ -385,8 +384,6 @@ var/list/ai_list = list()
if (stat != DEAD)
adjustBruteLoss(30)
return
/mob/living/silicon/ai/Topic(href, href_list)
if(usr != src)
return
@@ -470,7 +467,6 @@ var/list/ai_list = list()
return
..()
return
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
@@ -746,7 +742,6 @@ var/list/ai_list = list()
light_cameras()
src << "Camera lights activated."
return
//AI_CAMERA_LUMINOSITY
@@ -898,3 +893,27 @@ var/list/ai_list = list()
if(..()) //successfully ressuscitated from death
icon_state = "ai"
. = 1
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
malfhack = null
malfhacking = FALSE
if(!istype(apc) || qdeleted(apc) || apc.stat & BROKEN)
src << "Hack aborted. The designated APC no longer exists on the \
power network."
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
else if(apc.aidisabled)
src << "Hack aborted. \The [apc] is no longer responding \
to our systems."
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 1)
else
malf_picker.processing_time += 10
apc.malfai = parent || src
apc.malfhack = TRUE
apc.locked = TRUE
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, 1)
src << "Hack complete. \The [apc] is now under your \
exclusive control."
apc.update_icon()
+1 -3
View File
@@ -49,9 +49,7 @@
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
return
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss()
if(!fire_res_on_core)
health -= getFireLoss()
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
update_stat()
diag_hud_set_health()
@@ -138,4 +138,4 @@
return //we don't get hacked or give a shit about it
/mob/living/simple_animal/drone/cogscarab/drone_chat(msg)
send_hierophant_message(src, msg, "heavy_alloy") //HIEROPHANT DRONES
titled_hierophant_message(src, msg, "heavy_alloy") //HIEROPHANT DRONES
@@ -232,6 +232,13 @@
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
FindTarget()
/mob/living/simple_animal/hostile/UnarmedAttack(atom/A)
target = A
if(dextrous)
..()
else
AttackingTarget()
/mob/living/simple_animal/hostile/proc/AttackingTarget()
target.attack_animal(src)
@@ -1,3 +1,26 @@
/*
BUBBLEGUM
Bubblegum spawns randomly wherever a lavaland creature is able to spawn. It is the most powerful slaughter demon in existence.
Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size.
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming.
Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target.
To make this possible, it sprays streams of blood at random.
From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress.
When Bubblegum dies, it leaves behind a chest that can contain three things:
1. A slaughter demon spawner
2. A bottle that, when activated, drives everyone nearby into a frenzy
3. A contract that marks for death the chosen target
Difficulty: Hard
*/
/mob/living/simple_animal/hostile/megafauna/bubblegum
name = "bubblegum"
desc = "In what passes for a heirarchy among slaughter demons, this one is king."
@@ -1,3 +1,26 @@
/*
COLOSSUS
The colossus spawns randomly wherever a lavaland creature is able to spawn. It is powerful, ancient, and extremely deadly.
The colossus has a degree of sentience, proving this in speech during its attacks.
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
The colossus' true danger lies in its ranged capabilities. It fires immensely damaging death bolts that penetrate all armor in a variety of ways:
1. The colossus fires death bolts in alternating patterns: the cardinal directions and the diagonal directions.
2. The colossus fires death bolts in a shotgun-like pattern, instantly downing anything unfortunate enough to be hit by all of them.
3. The colossus fires a spiral of death bolts.
At 33% health, the colossus gains an additional attack:
4. The colossus fires two spirals of death bolts, spinning in opposite directions.
When a colossus dies, it leaves behind a chunk of glowing crystal known as a black box. Anything placed inside will carry over into future rounds.
For instance, you could place a bag of holding into the black box, and then kill another colossus next round and retrieve the bag of holding from inside.
Difficulty: Very Hard
*/
/mob/living/simple_animal/hostile/megafauna/colossus
name = "colossus"
desc = "A monstrous creature protected by heavy shielding."
@@ -1,3 +1,28 @@
/*
ASH DRAKE
Ash drakes spawn randomly wherever a lavaland creature is able to spawn. They are the draconic guardians of the Necropolis.
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast.
It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs.
The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage.
- Sometimes it will chain these swooping attacks over and over, making swiftness a necessity.
When an ash drake dies, it leaves behind a chest that can contain four things:
1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power
2. A lava staff that allows its wielder to create lava
3. A spellbook and wand of fireballs
4. A bottle of dragon's blood with several effects, including turning its imbiber into a drake themselves.
When butchered, they leave behind diamonds, sinew, bone, and ash drake hide. Ash drake hide can be used to create a hooded cloak that protects its wearer from ash storms.
Difficulty: Medium
*/
/mob/living/simple_animal/hostile/megafauna/dragon
name = "ash drake"
desc = "Guardians of the necropolis."
@@ -1,3 +1,21 @@
/*
LEGION
Legion spawns from the necropolis gate in the far north of lavaland. It is the guardian of the Necropolis and emerges from within whenever an intruder tries to enter through its gate.
Whenever Legion emerges, everything in lavaland will receive a notice via color, audio, and text. This is because Legion is powerful enough to slaughter the entirety of lavaland with little effort.
It has two attack modes that it constantly rotates between.
In ranged mode, it will behave like a normal legion - retreating when possible and firing legion skulls at the target.
In charge mode, it will spin and rush its target, attacking with melee whenever possible.
When Legion dies, it drops a staff of storms, which allows its wielder to call and disperse ash storms at will and functions as a powerful melee weapon.
Difficulty: Medium
*/
/mob/living/simple_animal/hostile/megafauna/legion
name = "Legion"
health = 800
@@ -264,7 +264,7 @@
else
feedback_add_details("hivelord_core", "[type]|stabilizer")
/obj/item/organ/hivelord_core/proc/go_inert()
inert = TRUE
desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested."
@@ -454,7 +454,7 @@
mob_size = MOB_SIZE_LARGE
var/pre_attack = 0
var/pre_attack_icon = "Goliath_preattack"
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide{layer = ABOVE_MOB_LAYER})
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide)
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
..()
@@ -486,7 +486,6 @@
ranged_cooldown = world.time + ranged_cooldown_time
icon_state = icon_aggro
pre_attack = 0
return
/mob/living/simple_animal/hostile/asteroid/goliath/adjustHealth(damage)
ranged_cooldown -= 10
@@ -498,7 +497,6 @@
handle_preattack()
if(icon_state != icon_aggro)
icon_state = icon_aggro
return
/obj/effect/goliath_tentacle/
name = "Goliath tentacle"
@@ -423,16 +423,25 @@
/mob/living/simple_animal/ex_act(severity, target)
..()
var/bomb_armor = getarmor(null, "bomb")
switch (severity)
if (1)
gib()
return
if(prob(bomb_armor))
adjustBruteLoss(500)
else
gib()
return
if (2)
adjustBruteLoss(60)
var/bloss = 60
if(prob(bomb_armor))
bloss = bloss / 1.5
adjustBruteLoss(bloss)
if(3)
adjustBruteLoss(30)
var/bloss = 30
if(prob(bomb_armor))
bloss = bloss / 1.5
adjustBruteLoss(bloss)
/mob/living/simple_animal/proc/CanAttack(atom/the_target)
if(see_invisible < the_target.invisibility)
+11
View File
@@ -201,6 +201,8 @@
if(href_list["votepollid"] && href_list["votetype"])
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
//lets take data from the user to decide what kind of poll this is, without validating it
//what could go wrong
switch(votetype)
if(POLLTYPE_OPTION)
var/optionid = text2num(href_list["voteoptionid"])
@@ -219,6 +221,7 @@
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
//(protip, this stops no exploits)
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
@@ -257,6 +260,14 @@
usr << "<span class='danger'>Maximum replies reached.</span>"
break
usr << "<span class='notice'>Vote successful.</span>"
if(POLLTYPE_IRV)
if (!href_list["IRVdata"])
src << "<span class='danger'>No ordering data found. Please try again or contact an administrator.</span>"
var/list/votelist = splittext(href_list["IRVdata"], ",")
if (!vote_on_irv_poll(pollid, votelist))
src << "<span class='danger'>Vote failed, please try again or contact an administrator.</span>"
return
src << "<span class='notice'>Vote successful.</span>"
/mob/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = SSjob.GetJob(rank)
+276 -12
View File
@@ -24,7 +24,7 @@
/mob/new_player/proc/poll_player(pollid)
if(!pollid)
return
if(!dbcon.IsConnected())
if(!establish_db_connection())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
@@ -87,6 +87,7 @@
output += "<p><input type='submit' value='Vote'>"
output += "</form>"
output += "</div>"
src << browse(null ,"window=playerpolllist")
src << browse(output,"window=playerpoll;size=500x250")
if(POLLTYPE_TEXT)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
@@ -117,6 +118,7 @@
else
vote_text = replacetext(vote_text, "\n", "<br>")
output += "[vote_text]"
src << browse(null ,"window=playerpolllist")
src << browse(output,"window=playerpoll;size=500x500")
if(POLLTYPE_RATING)
var/DBQuery/voted_query = 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")
@@ -172,6 +174,7 @@
output += "<input type='hidden' name='minid' value='[minid]'>"
output += "<input type='hidden' name='maxid' value='[maxid]'>"
output += "<p><input type='submit' value='Submit'></form>"
src << browse(null ,"window=playerpolllist")
src << browse(output,"window=playerpoll;size=500x500")
if(POLLTYPE_MULTI)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
@@ -223,14 +226,133 @@
if(!votedfor.len)
output += "<p><input type='submit' value='Vote'></form>"
output += "</div>"
src << browse(null ,"window=playerpolllist")
src << browse(output,"window=playerpoll;size=500x250")
if(POLLTYPE_IRV)
var/datum/asset/irv_assets = get_asset_datum(/datum/asset/simple/IRV)
irv_assets.send(src)
var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
if(!voted_query.Execute())
var/err = voted_query.ErrorMsg()
log_game("SQL ERROR obtaining optionid from poll_vote table. Error : \[[err]\]\n")
return
var/list/votedfor = list()
while(voted_query.NextRow())
votedfor.Add(text2num(voted_query.item[1]))
var/list/datum/polloption/options = list()
var/DBQuery/options_query = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
if(!options_query.Execute())
var/err = options_query.ErrorMsg()
log_game("SQL ERROR obtaining id, text from poll_option table. Error : \[[err]\]\n")
return
while(options_query.NextRow())
var/datum/polloption/PO = new()
PO.optionid = text2num(options_query.item[1])
PO.optiontext = options_query.item[2]
options["[PO.optionid]"] += PO
//if they already voted, use their sort
if (votedfor.len)
var/list/datum/polloption/newoptions = list()
for (var/V in votedfor)
var/datum/polloption/PO = options["[V]"]
if(PO)
newoptions["[V]"] = PO
options -= "[V]"
//add any options that they didn't vote on (some how, some way)
options = shuffle(options)
for (var/V in options)
newoptions["[V]"] = options["[V]"]
options = newoptions
//otherwise, lets shuffle it.
else
var/list/datum/polloption/newoptions = list()
while (options.len)
var/list/local_options = options.Copy()
var/key
//the jist is we randomly remove all options from a copy of options until only one reminds,
// move that over to our new list
// and repeat until we've moved all of them
while (local_options.len)
key = local_options[rand(1, local_options.len)]
local_options -= key
var/value = options[key]
options -= key
newoptions[key] = value
options = newoptions
var/output = {"
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<script src="jquery-1.10.2.min.js"></script>
<script src="jquery-ui.custom-core-widgit-mouse-sortable-min.js"></script>
<style>
#sortable { list-style-type: none; margin: 0; padding: 2em; }
#sortable li { min-height: 1em; margin: 0px 1px 1px 1px; padding: 1px; border: 1px solid black; border-radius: 5px; background-color: white; cursor:move;}
#sortable .sortable-placeholder-highlight { min-height: 1em; margin: 0 2px 2px 2px; padding: 2px; border: 1px dotted blue; border-radius: 5px; background-color: GhostWhite; }
span.grippy { content: '....'; width: 10px; height: 20px; display: inline-block; overflow: hidden; line-height: 5px; padding: 3px 1px; cursor: move; vertical-align: middle; margin-top: -.7em; margin-right: .3em; font-size: 12px; font-family: sans-serif; letter-spacing: 2px; color: #cccccc; text-shadow: 1px 0 1px black; }
span.grippy::after { content: '.. .. .. ..';}
</style>
<script>
$(function() {
$( "#sortable" ).sortable({
placeholder: "sortable-placeholder-highlight",
axis: "y",
containment: "#ballot",
scroll: false,
cursor: "ns-resize",
tolerance: "pointer"
});
$( "#sortable" ).disableSelection();
$('form').submit(function(){
$('#IRVdata').val($( "#sortable" ).sortable("toArray", { attribute: "voteid" }));
});
});
</script>
</head>
<body>
<div align='center'><B>Player poll</B><hr>
<b>Question: [pollquestion]</b><br>Please sort the options in the order of <b>most preferred</b> to <b>least preferred</b><br>
<font size='2'>Revoting has been enabled on this poll, if you think you made a mistake, simply revote<br></font>
<font size='2'>Poll runs from <b>[pollstarttime]</b> until <b>[pollendtime]</b></font><p>
</div>
<form name='cardcomp' action='?src=\ref[src]' method='POST'>
<input type='hidden' name='src' value='\ref[src]'>
<input type='hidden' name='votepollid' value='[pollid]'>
<input type='hidden' name='votetype' value=[POLLTYPE_IRV]>
<input type='hidden' name='IRVdata' id='IRVdata'>
<div id="ballot" class="center">
<b><center>Most Preferred</center></b>
<ol id="sortable" class="rankings" style="padding:0px">
"}
for(var/O in options)
var/datum/polloption/PO = options["[O]"]
if(PO.optionid && PO.optiontext)
output += "<li voteid='[PO.optionid]' class='ranking'><span class='grippy'></span> [PO.optiontext]</li>\n"
output += {"
</ol>
<b><center>Least Preferred</center></b><br>
</div>
<p><input type='submit' value='[( votedfor.len ? "Re" : "")]Vote'></form>
"}
src << browse(null ,"window=playerpolllist")
src << browse(output,"window=playerpoll;size=500x500")
return
/mob/new_player/proc/poll_check_voted(pollid, table)
if(!dbcon.IsConnected())
/mob/new_player/proc/poll_check_voted(pollid, text = FALSE)
var/table = "poll_vote"
if (text)
table = "poll_textreply"
if (!establish_db_connection())
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 = dbcon.NewQuery("SELECT id FROM `[format_table_name(table)]` WHERE pollid = [pollid] AND ckey = '[ckey]'")
if(!query_hasvoted.Execute())
var/err = query_hasvoted.ErrorMsg()
log_game("SQL ERROR obtaining id from [table] table. Error : \[[err]\]\n")
@@ -243,10 +365,134 @@
. = client.holder.rank
return .
/mob/new_player/proc/vote_rig_check()
if (usr != src)
if (!usr || !src)
return 0
//we gots ourselfs a dirty cheater on our hands!
log_game("[key_name(usr)] attempted to rig the vote by voting as [ckey]")
message_admins("[key_name_admin(usr)] attempted to rig the vote by voting as [ckey]")
usr << "<span class='danger'>You don't seem to be [ckey].</span>"
src << "<span class='danger'>Something went horribly wrong processing your vote. Please contact an administrator, they should have gotten a message about this</span>"
return 0
return 1
/mob/new_player/proc/vote_valid_check(pollid, holder, type)
if (!establish_db_connection())
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/select_query = dbcon.NewQuery({"
SELECT id
FROM [format_table_name("poll_question")]
WHERE
[(holder ? "" : "adminonly = false AND")]
id = [pollid]
AND
Now() BETWEEN starttime AND endtime
AND
polltype = '[type]'
"})
if (!select_query.Execute())
var/err = select_query.ErrorMsg()
log_game("SQL ERROR validating poll via poll_question table. Error : \[[err]\]\n")
return 0
if (!select_query.NextRow())
return 0
return 1
/mob/new_player/proc/vote_on_irv_poll(pollid, list/votelist)
if (!establish_db_connection())
src << "<span class='danger'>Failed to establish database connection.</span>"
return 0
if (!vote_rig_check())
return 0
pollid = text2num(pollid)
if (!pollid || pollid < 0)
return 0
if (!votelist || !istype(votelist) || !votelist.len)
return 0
if (!client)
return 0
//save these now so we can still process the vote if the client goes away while we process.
var/datum/admins/holder = client.holder
var/rank = "Player"
if (holder)
rank = holder.rank
var/ckey = client.ckey
var/address = client.address
//validate the poll
if (!vote_valid_check(pollid, holder, POLLTYPE_IRV))
return 0
//lets collect the options
var/DBQuery/options_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
if (!options_query.Execute())
var/err = options_query.ErrorMsg()
log_game("SQL ERROR obtaining id from poll_option table. Error : \[[err]\]\n")
return 0
var/list/optionlist = list()
while (options_query.NextRow())
optionlist += text2num(options_query.item[1])
//validate their votes are actually in the list of options and actually numbers
var/list/numberedvotelist = list()
for (var/vote in votelist)
vote = text2num(vote)
numberedvotelist += vote
if (!vote) //this is fine because voteid starts at 1, so it will never be 0
src << "<span class='danger'>Error: Invalid (non-numeric) votes in the vote data.</span>"
return 0
if (!(vote in optionlist))
src << "<span class='danger'>Votes for choices that do not appear to be in the poll detected<span>"
return 0
if (!numberedvotelist.len)
src << "<span class='danger'>Invalid vote data</span>"
return 0
//lets add the vote, first we generate a insert statement.
var/sqlrowlist = ""
for (var/vote in numberedvotelist)
if (sqlrowlist != "")
sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
sqlrowlist += "(Now(), [pollid], [vote], '[sanitizeSQL(ckey)]', '[sanitizeSQL(address)]', '[sanitizeSQL(rank)]')"
//now lets delete their old votes (if any)
var/DBQuery/voted_query = dbcon.NewQuery("DELETE FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[ckey]'")
if (!voted_query.Execute())
var/err = voted_query.ErrorMsg()
log_game("SQL ERROR clearing out old votes. Error : \[[err]\]\n")
return 0
//now to add the new ones.
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES [sqlrowlist]")
if(!query_insert.Execute())
var/err = query_insert.ErrorMsg()
log_game("SQL ERROR adding vote to table. Error : \[[err]\]\n")
src << "<span class='danger'>Error adding vote.</span>"
return 0
src << browse(null,"window=playerpoll")
return 1
/mob/new_player/proc/vote_on_poll(pollid, optionid)
if(!establish_db_connection())
src << "<span class='danger'>Failed to establish database connection.</span>"
return 0
if (!vote_rig_check())
return 0
if(!pollid || !optionid)
return
var/adminrank = poll_check_voted(pollid, "poll_vote")
//validate the poll
if (!vote_valid_check(pollid, client.holder, POLLTYPE_OPTION))
return 0
var/adminrank = poll_check_voted(pollid)
if(!adminrank)
return
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (datetime, pollid, optionid, ckey, ip, adminrank) VALUES (Now(), [pollid], [optionid], '[ckey]', '[client.address]', '[adminrank]')")
@@ -258,12 +504,20 @@
return 1
/mob/new_player/proc/log_text_poll_reply(pollid, replytext)
if(!establish_db_connection())
src << "<span class='danger'>Failed to establish database connection.</span>"
return 0
if (!vote_rig_check())
return 0
if(!pollid)
return
//validate the poll
if (!vote_valid_check(pollid, client.holder, POLLTYPE_TEXT))
return 0
if(!replytext)
usr << "The text you entered was blank. Please correct the text and submit again."
return
var/adminrank = poll_check_voted(pollid, "poll_textreply")
var/adminrank = poll_check_voted(pollid, TRUE)
if(!adminrank)
return
replytext = sanitizeSQL(replytext)
@@ -279,11 +533,16 @@
return 1
/mob/new_player/proc/vote_on_numval_poll(pollid, optionid, rating)
if(!establish_db_connection())
src << "<span class='danger'>Failed to establish database connection.</span>"
return 0
if (!vote_rig_check())
return 0
if(!pollid || !optionid || !rating)
return
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
//validate the poll
if (!vote_valid_check(pollid, client.holder, POLLTYPE_RATING))
return 0
var/DBQuery/query_hasvoted = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[ckey]'")
if(!query_hasvoted.Execute())
var/err = query_hasvoted.ErrorMsg()
@@ -304,11 +563,16 @@
return 1
/mob/new_player/proc/vote_on_multi_poll(pollid, optionid)
if(!establish_db_connection())
src << "<span class='danger'>Failed to establish database connection.</span>"
return 0
if (!vote_rig_check())
return 0
if(!pollid || !optionid)
return 1
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return 1
//validate the poll
if (!vote_valid_check(pollid, client.holder, POLLTYPE_MULTI))
return 0
var/DBQuery/query_get_choicelen = dbcon.NewQuery("SELECT multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
if(!query_get_choicelen.Execute())
var/err = query_get_choicelen.ErrorMsg()
+8 -2
View File
@@ -11,18 +11,24 @@
pressure_resistance = 8
burn_state = FLAMMABLE
var/amount = 30 //How much paper is in the bin.
var/list/papers = new/list() //List of papers put in the bin for reference.
var/list/papers = list() //List of papers put in the bin for reference.
/obj/item/weapon/paper_bin/fire_act()
if(!amount)
return
..()
/obj/item/weapon/paper_bin/Destroy()
if(papers)
for(var/i in papers)
qdel(i)
papers = null
. = ..()
/obj/item/weapon/paper_bin/burn()
amount = 0
extinguish()
update_icon()
return
/obj/item/weapon/paper_bin/MouseDrop(atom/over_object)
var/mob/living/M = usr
+6 -19
View File
@@ -114,7 +114,7 @@
setDir(SOUTH)
if(auto_name)
name = "[get_area(src)] APC"
name = "\improper [get_area(src)] APC"
pixel_x = (src.tdir & 3)? 0 : (src.tdir == 4 ? 24 : -24)
pixel_y = (src.tdir & 3)? (src.tdir ==1 ? 24 : -24) : 0
@@ -147,7 +147,7 @@
qdel(cell)
if(terminal)
disconnect_terminal()
return ..()
. = ..()
/obj/machinery/power/apc/proc/make_terminal()
// create a terminal object at the same position as original turf loc
@@ -797,24 +797,11 @@
malf << "Beginning override of APC systems. This takes some time, and you cannot perform other actions during the process."
malf.malfhack = src
malf.malfhacking = TRUE
addtimer(src, "malfhacked", 600, FALSE, malf)
addtimer(malf, "malfhacked", 600, FALSE, src)
/obj/machinery/power/apc/proc/malfhacked(mob/living/silicon/ai/malf)
if(!istype(malf))
return
malf.malfhack = null
malf.malfhacking = FALSE
if(src && !src.aidisabled)
malf.malf_picker.processing_time += 10
malfai = malf.parent || malf
malfhack = TRUE
locked = TRUE
malf << "Hack complete. The APC is now under your exclusive control."
update_icon()
else
malf << "Hack aborted. The designated APC has stopped responding and no longer exists on the power network."
var/obj/screen/alert/hackingapc/A
A = malf.throw_alert("hackingapc", /obj/screen/alert/hackingapc)
A.target = src
/obj/machinery/power/apc/proc/malfoccupy(mob/living/silicon/ai/malf)
if(!istype(malf))
+18 -20
View File
@@ -48,7 +48,7 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
var/obj/singularity/energy_ball/EB = ball
qdel(EB)
return ..()
. = ..()
/obj/singularity/energy_ball/process()
if(!orbiting)
@@ -71,8 +71,6 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
else
energy = 0 // ensure we dont have miniballs of miniballs
return
/obj/singularity/energy_ball/examine(mob/user)
..()
if(orbiting_balls.len)
@@ -89,28 +87,17 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
var/turf/T = get_step(src, move_dir)
if(can_move(T))
loc = T
for(var/mob/living/carbon/C in loc)
dust_mobs(C)
/obj/singularity/energy_ball/proc/handle_energy()
if(energy >= energy_to_raise)
energy_to_lower = energy_to_raise - 20
energy_to_raise = energy_to_raise * 1.25
playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 30)
spawn(100)
if (!loc)
return
var/obj/singularity/energy_ball/EB = new(loc)
EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
var/icon/I = icon(icon,icon_state,dir)
var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8)
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
EB.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36))
addtimer(src, "new_mini_ball", 100)
else if(energy < energy_to_lower && orbiting_balls.len)
energy_to_raise = energy_to_raise / 1.25
@@ -122,6 +109,20 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
else if(orbiting_balls.len)
dissipate() //sing code has a much better system.
/obj/singularity/energy_ball/proc/new_mini_ball()
if(!loc)
return
var/obj/singularity/energy_ball/EB = new(loc)
EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
var/icon/I = icon(icon,icon_state,dir)
var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8)
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
EB.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36))
/obj/singularity/energy_ball/Bump(atom/A)
dust_mobs(A)
@@ -146,7 +147,6 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/C = A
C.dust()
return
/proc/tesla_zap(var/atom/source, zap_range = 3, power)
. = source.dir
@@ -262,5 +262,3 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
else if(closest_structure)
closest_structure.tesla_act(power)
+2 -2
View File
@@ -32,9 +32,8 @@
desc = "[initial(desc)][BB ? "" : " This one is spent"]"
/obj/item/ammo_casing/proc/newshot() //For energy weapons, shotgun shells and wands (!).
if (!BB)
if(!BB)
BB = new projectile_type(src)
return
/obj/item/ammo_casing/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/ammo_box))
@@ -79,6 +78,7 @@
var/multiload = 1
/obj/item/ammo_box/New()
..()
for(var/i = 1, i <= max_ammo, i++)
stored_ammo += new ammo_type(src)
update_icon()
-1
View File
@@ -107,7 +107,6 @@
/obj/item/weapon/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
user << "<span class='danger'>*click*</span>"
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
/obj/item/weapon/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
@@ -36,7 +36,8 @@
if(istype(AM, mag_type))
if(magazine)
user << "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>"
magazine.loc = get_turf(src.loc)
magazine.dropped()
magazine.forceMove(get_turf(src.loc))
magazine.update_icon()
magazine = null
else
+56 -48
View File
@@ -35,7 +35,7 @@
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
var/nodamage = 0 //Determines if the projectile will skip any damage inflictions
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb
var/projectile_type = "/obj/item/projectile"
var/projectile_type = /obj/item/projectile
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
//Effects
var/stun = 0
@@ -140,58 +140,66 @@
Angle = setAngle
if(!legacy) //new projectiles
set waitfor = 0
var/next_run = world.time
while(loc)
if(!paused)
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if(paused)
next_run = world.time
sleep(1)
continue
if((!( current ) || loc == current))
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
if(!Angle)
Angle=round(Get_Angle(src,current))
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2)
var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2)
var/pixel_x_offset = pixel_x + Pixel_x
var/pixel_y_offset = pixel_y + Pixel_y
var/new_x = x
var/new_y = y
var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2)
var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2)
var/pixel_x_offset = pixel_x + Pixel_x
var/pixel_y_offset = pixel_y + Pixel_y
var/new_x = x
var/new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
pixel_x += 32
new_x--
while(pixel_x_offset > 16)
pixel_x_offset -= 32
pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
pixel_y += 32
new_y--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
pixel_y += 32
new_y--
speed = round(speed)
step_towards(src, locate(new_x, new_y, z))
if(speed <= 1)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed)))
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
if(delay <= world.tick_lag*2)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)))
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
sleep(max(1, speed))
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
Bump(original, 1)
Range()
if (delay > 0)
sleep(delay)
else //old projectile system
set waitfor = 0
while(loc)
@@ -204,7 +212,7 @@
if(!(original in permutated))
Bump(original, 1)
Range()
sleep(1)
sleep(config.run_speed * 0.9)
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
@@ -218,4 +226,4 @@
/obj/item/projectile/proc/dumbfire(var/dir)
current = get_ranged_target_turf(src, dir, world.maxx)
fire()
fire()
@@ -125,7 +125,6 @@
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),0)
G.react()
qdel(hotspot)
return
/*
* Water reaction to an object
@@ -589,7 +589,10 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M)
M.adjustToxLoss(current_cycle*3*REM)
var/toxdamage = current_cycle*3*REM
M.adjustToxLoss(toxdamage)
if(M)
add_logs(M, get_turf(M), "has taken [toxdamage] toxin damage from amanitin toxin")
..()
/datum/reagent/toxin/lipolicide
@@ -258,9 +258,8 @@
if(istype(T, /turf/open/floor)) //intact floor, pop the tile
var/turf/open/floor/myturf = T
if(myturf.builtin_tile)
myturf.builtin_tile.loc = T
myturf.builtin_tile = null
if(myturf.floor_tile)
PoolOrNew(myturf.floor_tile, T)
myturf.make_plating()
if(direction) // direction is specified
@@ -711,3 +711,20 @@
materials = list(MAT_METAL = 12000)
build_path = /obj/item/wallframe/turret_control
category = list("initial", "Construction")
/datum/design/conveyor_belt
name = "Conveyor belt"
id = "conveyor_belt"
build_type = AUTOLATHE
materials = list(MAT_METAL = 5000)
build_path = /obj/item/conveyor_construct
category = list("initial", "Construction")
/datum/design/conveyor_switch
name = "Conveyor belt switch"
id = "conveyor_switch"
build_type = AUTOLATHE
materials = list(MAT_METAL = 450, MAT_GLASS = 190)
build_path = /obj/item/conveyor_switch_construct
category = list("initial", "Construction")
-6
View File
@@ -1,11 +1,5 @@
//If you're looking for spawners like ash walker eggs, check ghost_role_spawners.dm
/obj/machinery/lavaland_controller
name = "weather machine"
desc = "Controls the weather... when it's on, at any rate. A sticky note on the side proclaims \"DISABLED IN FAVOR OF AN ACTUAL ATMOSPHERE\"."
icon = 'icons/obj/machines/telecomms.dmi'
icon_state = "processor_off"
/obj/structure/fans/tiny/invisible //For blocking air in ruin doorways
invisibility = INVISIBILITY_ABSTRACT
@@ -1,5 +1,5 @@
//The necropolis gate is used to call forth Legion from the Necropolis.
/obj/structure/lavaland_door
/obj/structure/necropolis_gate
name = "necropolis gate"
desc = "A tremendous and impossibly large gateway, bored into dense bedrock."
icon = 'icons/effects/96x96.dmi'
@@ -9,12 +9,13 @@
opacity = 1
bound_width = 96
bound_height = 96
pixel_x = -32
burn_state = LAVA_PROOF
luminosity = 1
var/boss = FALSE
var/is_anyone_home = FALSE
/obj/structure/lavaland_door/attack_hand(mob/user)
/obj/structure/necropolis_gate/attack_hand(mob/user)
for(var/mob/living/simple_animal/hostile/megafauna/legion/L in mob_list)
return
if(is_anyone_home)
@@ -51,10 +52,10 @@
is_anyone_home = FALSE
new/mob/living/simple_animal/hostile/megafauna/legion(get_step(src.loc, SOUTH))
/obj/structure/lavaland_door/singularity_pull()
/obj/structure/necropolis_gate/singularity_pull()
return 0
/obj/structure/lavaland_door/Destroy(force)
/obj/structure/necropolis_gate/Destroy(force)
if(force)
. = ..()
else
+3
View File
@@ -435,6 +435,8 @@
if(S0.area_type)
area_type = S0.area_type
var/destination_turf_type = S1.turf_type
var/list/L0 = return_ordered_turfs(x, y, z, dir, areaInstance)
var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir)
@@ -466,6 +468,7 @@
continue
if(T0.type != T0.baseturf) //So if there is a hole in the shuttle we don't drag along the space/asteroid/etc to wherever we are going next
T0.copyTurf(T1)
T1.baseturf = destination_turf_type
areaInstance.contents += T1
//copy over air
+2 -2
View File
@@ -53,7 +53,7 @@
*
* return datum/tgui The requested UI.
**/
/datum/tgui/New(mob/user, datum/src_object, ui_key, interface, title, width = 0, height = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state, browser_id)
/datum/tgui/New(mob/user, datum/src_object, ui_key, interface, title, width = 0, height = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state, browser_id = null)
src.user = user
src.src_object = src_object
src.ui_key = ui_key
@@ -99,7 +99,7 @@
var/debugable = check_rights_for(user.client, R_DEBUG)
user << browse(get_html(debugable), "window=[window_id];[window_size][list2params(window_options)]") // Open the window.
if (custom_browser_id)
if (!custom_browser_id)
winset(user, window_id, "on-close=\"uiclose \ref[src]\"") // Instruct the client to signal UI when the window is closed.
SStgui.on_open(src)