diff --git a/.travis.yml b/.travis.yml
index e825828ab4..563545ca02 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,12 +2,16 @@
language: c
env:
- BYOND_MAJOR="507"
- BYOND_MINOR="1282"
+ BYOND_MAJOR="508"
+ BYOND_MINOR="1287"
before_install:
- sudo apt-get update -qq
- sudo apt-get install libc6:i386 libgcc1:i386 libstdc++6:i386 -qq
+ - sudo apt-get install python -qq
+ - sudo apt-get install python-pip -qq
+ - sudo pip install PyYaml -q
+ - sudo pip install beautifulsoup4 -q
install:
- curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip
@@ -19,4 +23,9 @@ install:
script:
- shopt -s globstar
- (! grep 'step_[xy]' maps/**/*.dmm)
- - DreamMaker polaris.dme
+ - (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
+ - (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; [ $num -le 1355 ])
+ - ( md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int")
+ - python tools/TagMatcher/tag-matcher.py ../..
+ - python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs
+ - DreamMaker baystation12.dme
diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm
index 506657df12..922275bcc9 100644
--- a/code/ZAS/Controller.dm
+++ b/code/ZAS/Controller.dm
@@ -282,7 +282,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
var/space = !istype(B)
if(direct && !space)
- if(equivalent_pressure(A.zone,B.zone) || current_cycle == 0)
+ if(min(A.zone.contents.len, B.zone.contents.len) <= ZONE_MIN_SIZE || equivalent_pressure(A.zone,B.zone) || current_cycle == 0)
merge(A.zone,B.zone)
return
diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm
index 8d084dc4c9..1f652ffaab 100644
--- a/code/ZAS/_docs.dm
+++ b/code/ZAS/_docs.dm
@@ -32,4 +32,6 @@ Notes for people who used ZAS before:
#define AIR_BLOCKED 1
#define ZONE_BLOCKED 2
-#define BLOCKED 3
\ No newline at end of file
+#define BLOCKED 3
+
+#define ZONE_MIN_SIZE 14 //zones with less than this many turfs will always merge, even if the connection is not direct
diff --git a/code/__defines/_compile_options.dm b/code/__defines/_compile_options.dm
new file mode 100644
index 0000000000..ac5f7120fd
--- /dev/null
+++ b/code/__defines/_compile_options.dm
@@ -0,0 +1,2 @@
+#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary.
+ // 1 will enable set background. 0 will disable set background.
\ No newline at end of file
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index 936d80890d..6e1acef8ce 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -80,6 +80,8 @@ var/list/be_special_flags = list(
#define MODE_MALFUNCTION "malf"
#define MODE_TRAITOR "traitor"
+#define DEFAULT_TELECRYSTAL_AMOUNT 12
+
/////////////////
////WIZARD //////
/////////////////
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index f2a96d460d..ecca29bfd1 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -135,6 +135,7 @@
#define WALL_CAN_OPEN 1
#define WALL_OPENING 2
+#define DEFAULT_TABLE_MATERIAL "plastic"
#define DEFAULT_WALL_MATERIAL "steel"
#define SHARD_SHARD "shard"
@@ -147,4 +148,9 @@
#define MATERIAL_BRITTLE 2
#define MATERIAL_PADDING 4
-#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
\ No newline at end of file
+#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
+
+#define BOMBCAP_DVSTN_RADIUS (max_explosion_range/4)
+#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
+#define BOMBCAP_LIGHT_RADIUS max_explosion_range
+#define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5)
diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm
index 50f55703d3..d5d0f58685 100644
--- a/code/_helpers/logging.dm
+++ b/code/_helpers/logging.dm
@@ -93,3 +93,60 @@
if(dir & DOWN) comps += "DOWN"
return english_list(comps, nothing_text="0", and_text="|", comma_text="|")
+
+//more or less a logging utility
+/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special_characters = 1)
+ var/mob/M
+ var/client/C
+ var/key
+
+ if(!whom) return "*null*"
+ if(istype(whom, /client))
+ C = whom
+ M = C.mob
+ key = C.key
+ else if(ismob(whom))
+ M = whom
+ C = M.client
+ key = M.key
+ else if(istype(whom, /datum))
+ var/datum/D = whom
+ return "*invalid:[D.type]*"
+ else
+ return "*invalid*"
+
+ . = ""
+
+ if(key)
+ if(include_link && C)
+ . += ""
+
+ if(C && C.holder && C.holder.fakekey && !include_name)
+ . += "Administrator"
+ else
+ . += key
+
+ if(include_link)
+ if(C) . += ""
+ else . += " (DC)"
+ else
+ . += "*no key*"
+
+ if(include_name && M)
+ var/name
+
+ if(M.real_name)
+ name = M.real_name
+ else if(M.name)
+ name = M.name
+
+
+ if(include_link && is_special_character(M) && highlight_special_characters)
+ . += "/([name])" //Orange
+ else
+ . += "/([name])"
+
+ return .
+
+/proc/key_name_admin(var/whom, var/include_name = 1)
+ return key_name(whom, 1, include_name)
diff --git a/code/_helpers/matrices.dm b/code/_helpers/matrices.dm
new file mode 100644
index 0000000000..abb0366382
--- /dev/null
+++ b/code/_helpers/matrices.dm
@@ -0,0 +1,17 @@
+/matrix/proc/TurnTo(old_angle, new_angle)
+ . = new_angle - old_angle
+ Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
+
+
+/atom/proc/SpinAnimation(speed = 10, loops = -1)
+ var/matrix/m120 = matrix(transform)
+ m120.Turn(120)
+ var/matrix/m240 = matrix(transform)
+ m240.Turn(240)
+ var/matrix/m360 = matrix(transform)
+ speed /= 3 //Gives us 3 equal time segments for our three turns.
+ //Why not one turn? Because byond will see that the start and finish are the same place and do nothing
+ //Why not two turns? Because byond will do a flip instead of a turn
+ animate(src, transform = m120, time = speed, loops)
+ animate(transform = m240, time = speed)
+ animate(transform = m360, time = speed)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 29d55e629f..e44a60ebc2 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -479,64 +479,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
if(M < 0)
return -M
-
-/proc/key_name(var/whom, var/include_link = null, var/include_name = 1, var/highlight_special_characters = 1)
- var/mob/M
- var/client/C
- var/key
-
- if(!whom) return "*null*"
- if(istype(whom, /client))
- C = whom
- M = C.mob
- key = C.key
- else if(ismob(whom))
- M = whom
- C = M.client
- key = M.key
- else if(istype(whom, /datum))
- var/datum/D = whom
- return "*invalid:[D.type]*"
- else
- return "*invalid*"
-
- . = ""
-
- if(key)
- if(include_link && C)
- . += ""
-
- if(C && C.holder && C.holder.fakekey && !include_name)
- . += "Administrator"
- else
- . += key
-
- if(include_link)
- if(C) . += ""
- else . += " (DC)"
- else
- . += "*no key*"
-
- if(include_name && M)
- var/name
-
- if(M.real_name)
- name = M.real_name
- else if(M.name)
- name = M.name
-
-
- if(include_link && is_special_character(M) && highlight_special_characters)
- . += "/([name])" //Orange
- else
- . += "/([name])"
-
- return .
-
-/proc/key_name_admin(var/whom, var/include_name = 1)
- return key_name(whom, 1, include_name)
-
-
// returns the turf located at the map edge in the specified direction relative to A
// used for mass driver
/proc/get_edge_target_turf(var/atom/A, var/direction)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 5a56b34e61..b22266274a 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -115,7 +115,7 @@
if(W.flags&USEDELAY)
next_move += 5
- var/resolved = A.attackby(W,src)
+ var/resolved = W.resolve_attackby(A, src)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1 indicates adjacency
else
@@ -136,7 +136,7 @@
next_move += 5
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
- var/resolved = A.attackby(W,src)
+ var/resolved = W.resolve_attackby(A,src)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
else
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index 0ba005455c..f3419b074a 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -74,135 +74,104 @@ var/const/tk_maxrange = 15
var/atom/movable/focus = null
var/mob/living/host = null
+/obj/item/tk_grab/dropped(mob/user as mob)
+ if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
+ if(focus.Adjacent(loc))
+ focus.loc = loc
+ loc = null
+ spawn(1)
+ qdel(src)
+ return
- dropped(mob/user as mob)
- if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
- if(focus.Adjacent(loc))
- focus.loc = loc
+//stops TK grabs being equipped anywhere but into hands
+/obj/item/tk_grab/equipped(var/mob/user, var/slot)
+ if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
+ qdel(src)
+ return
+/obj/item/tk_grab/attack_self(mob/user as mob)
+ if(focus)
+ focus.attack_self_tk(user)
+
+/obj/item/tk_grab/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this
+ if(!target || !user) return
+ if(last_throw+3 > world.time) return
+ if(!host || host != user)
qdel(src)
return
-
-
- //stops TK grabs being equipped anywhere but into hands
- equipped(var/mob/user, var/slot)
- if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
+ if(!(TK in host.mutations))
qdel(src)
return
+ if(isobj(target) && !isturf(target.loc))
+ return
-
- attack_self(mob/user as mob)
- if(focus)
- focus.attack_self_tk(user)
-
- afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this
- if(!target || !user) return
- if(last_throw+3 > world.time) return
- if(!host || host != user)
- qdel(src)
- return
- if(!(TK in host.mutations))
- qdel(src)
- return
- if(isobj(target) && !isturf(target.loc))
- return
-
- var/d = get_dist(user, target)
- if(focus) d = max(d,get_dist(user,focus)) // whichever is further
- switch(d)
- if(0)
- ;
- if(1 to 5) // not adjacent may mean blocked by window
- if(!proximity)
- user.next_move += 2
- if(5 to 7)
- user.next_move += 5
- if(8 to tk_maxrange)
- user.next_move += 10
- else
- user << "Your mind won't reach that far."
- return
-
- if(!focus)
- focus_object(target, user)
- return
-
- if(target == focus)
- target.attack_self_tk(user)
- return // todo: something like attack_self not laden with assumptions inherent to attack_self
-
-
- if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
- var/obj/item/I = focus
- var/resolved = target.attackby(I, user, user:get_organ_target())
- if(!resolved && target && I)
- I.afterattack(target,user,1) // for splashing with beakers
-
-
+ var/d = get_dist(user, target)
+ if(focus) d = max(d,get_dist(user,focus)) // whichever is further
+ switch(d)
+ if(0)
+ ;
+ if(1 to 5) // not adjacent may mean blocked by window
+ if(!proximity)
+ user.next_move += 2
+ if(5 to 7)
+ user.next_move += 5
+ if(8 to tk_maxrange)
+ user.next_move += 10
else
- apply_focus_overlay()
- focus.throw_at(target, 10, 1, user)
- last_throw = world.time
- return
-
- attack(mob/living/M as mob, mob/living/user as mob, def_zone)
- return
-
-
- proc/focus_object(var/obj/target, var/mob/living/user)
- if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
- if(target.anchored || !isturf(target.loc))
- qdel(src)
+ user << "Your mind won't reach that far."
return
- focus = target
- update_icon()
+
+ if(!focus)
+ focus_object(target, user)
+ return
+
+ if(target == focus)
+ target.attack_self_tk(user)
+ return // todo: something like attack_self not laden with assumptions inherent to attack_self
+
+
+ if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
+ var/obj/item/I = focus
+ var/resolved = target.attackby(I, user, user:get_organ_target())
+ if(!resolved && target && I)
+ I.afterattack(target,user,1) // for splashing with beakers
+ else
apply_focus_overlay()
+ focus.throw_at(target, 10, 1, user)
+ last_throw = world.time
+ return
+
+/obj/item/tk_grab/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
+ return
+
+
+/obj/item/tk_grab/proc/focus_object(var/obj/target, var/mob/living/user)
+ if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
+ if(target.anchored || !isturf(target.loc))
+ qdel(src)
return
-
-
- proc/apply_focus_overlay()
- if(!focus) return
- var/obj/effect/overlay/O = PoolOrNew(/obj/effect/overlay, locate(focus.x,focus.y,focus.z))
- O.name = "sparkles"
- O.anchored = 1
- O.density = 0
- O.layer = FLY_LAYER
- O.set_dir(pick(cardinal))
- O.icon = 'icons/effects/effects.dmi'
- O.icon_state = "nothing"
- flick("empdisable",O)
- spawn(5)
- qdel(O)
- return
-
-
+ focus = target
update_icon()
- overlays.Cut()
- if(focus && focus.icon && focus.icon_state)
- overlays += icon(focus.icon,focus.icon_state)
- return
+ apply_focus_overlay()
+ return
-/*Not quite done likely needs to use something thats not get_step_to
- proc/check_path()
- var/turf/ref = get_turf(src.loc)
- var/turf/target = get_turf(focus.loc)
- if(!ref || !target) return 0
- var/distance = get_dist(ref, target)
- if(distance >= 10) return 0
- for(var/i = 1 to distance)
- ref = get_step_to(ref, target, 0)
- if(ref != target) return 0
- return 1
-*/
-
-//equip_to_slot_or_del(obj/item/W, slot, del_on_fail = 1)
-/*
- if(istype(user, /mob/living/carbon))
- if(user:mutations & TK && get_dist(source, user) <= 7)
- if(user:get_active_hand()) return 0
- var/X = source:x
- var/Y = source:y
- var/Z = source:z
-
-*/
+/obj/item/tk_grab/proc/apply_focus_overlay()
+ if(!focus) return
+ var/obj/effect/overlay/O = PoolOrNew(/obj/effect/overlay, locate(focus.x,focus.y,focus.z))
+ O.name = "sparkles"
+ O.anchored = 1
+ O.density = 0
+ O.layer = FLY_LAYER
+ O.set_dir(pick(cardinal))
+ O.icon = 'icons/effects/effects.dmi'
+ O.icon_state = "nothing"
+ flick("empdisable",O)
+ spawn(5)
+ qdel(O)
+ return
+/obj/item/tk_grab/update_icon()
+ overlays.Cut()
+ if(focus && focus.icon && focus.icon_state)
+ overlays += icon(focus.icon,focus.icon_state)
+ return
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 7380e709f4..668f715cf5 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -91,6 +91,7 @@ var/list/gamemode_cache = list()
var/guests_allowed = 1
var/debugparanoid = 0
+ var/serverurl
var/server
var/banappeals
var/wikiurl
@@ -164,6 +165,7 @@ var/list/gamemode_cache = list()
var/use_irc_bot = 0
var/irc_bot_host = ""
+ var/irc_bot_export = 0 // whether the IRC bot in use is a Bot32 (or similar) instance; Bot32 uses world.Export() instead of nudge.py/libnudge
var/main_irc = ""
var/admin_irc = ""
var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix
@@ -386,6 +388,9 @@ var/list/gamemode_cache = list()
if ("hostedby")
config.hostedby = value
+ if ("serverurl")
+ config.serverurl = value
+
if ("server")
config.server = value
@@ -500,6 +505,9 @@ var/list/gamemode_cache = list()
if("use_irc_bot")
use_irc_bot = 1
+ if("irc_bot_export")
+ irc_bot_export = 1
+
if("ticklag")
Ticklag = text2num(value)
diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm
index 469df7305a..7a4d10fc88 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -237,7 +237,7 @@ datum/controller/vote
return 0
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
- if(!(antag.id in additional_antag_types) && (antag.flags & ANTAG_VOTABLE))
+ if(!(antag.id in additional_antag_types) && antag.is_votable())
choices.Add(antag.role_text)
choices.Add("None")
if("custom")
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c3a77b4b0e..5163bfb270 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -29,7 +29,7 @@
*/
-datum/mind
+/datum/mind
var/key
var/name //replaces mob/var/original_name
var/mob/living/current
@@ -58,459 +58,389 @@ datum/mind
// the world.time since the mob has been brigged, or -1 if not at all
var/brigged_since = -1
- New(var/key)
- src.key = key
-
//put this here for easier tracking ingame
var/datum/money_account/initial_account
- proc/transfer_to(mob/living/new_character)
- if(!istype(new_character))
- world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
- if(current) //remove ourself from our old body's mind variable
- if(changeling)
- current.remove_changeling_powers()
- current.verbs -= /datum/changeling/proc/EvolutionMenu
- current.mind = null
+/datum/mind/New(var/key)
+ src.key = key
- nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user
- if(new_character.mind) //remove any mind currently in our new body's mind variable
- new_character.mind.current = null
-
- current = new_character //link ourself to our new body
- new_character.mind = src //and link our new body to ourself
+/datum/mind/proc/transfer_to(mob/living/new_character)
+ if(!istype(new_character))
+ world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
+ if(current) //remove ourself from our old body's mind variable
if(changeling)
- new_character.make_changeling()
+ current.remove_changeling_powers()
+ current.verbs -= /datum/changeling/proc/EvolutionMenu
+ current.mind = null
- if(active)
- new_character.key = key //now transfer the key to link the client to our new body
+ nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user
+ if(new_character.mind) //remove any mind currently in our new body's mind variable
+ new_character.mind.current = null
- proc/store_memory(new_text)
- memory += "[new_text]
"
+ current = new_character //link ourself to our new body
+ new_character.mind = src //and link our new body to ourself
- proc/show_memory(mob/recipient)
- var/output = "[current.real_name]'s Memory
"
- output += memory
+ if(changeling)
+ new_character.make_changeling()
- if(objectives.len>0)
- output += "
Objectives:"
+ if(active)
+ new_character.key = key //now transfer the key to link the client to our new body
- var/obj_count = 1
- for(var/datum/objective/objective in objectives)
- output += "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+/datum/mind/proc/store_memory(new_text)
+ memory += "[new_text]
"
- recipient << browse(output,"window=memory")
+/datum/mind/proc/show_memory(mob/recipient)
+ var/output = "[current.real_name]'s Memory
"
+ output += memory
- proc/edit_memory()
- if(!ticker || !ticker.mode)
- alert("Not before round-start!", "Alert")
- return
+ if(objectives.len>0)
+ output += "
Objectives:"
- var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
- out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
- out += "Assigned role: [assigned_role]. Edit
"
- out += "
"
- out += "Factions and special roles:
"
- for(var/antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[antag_type]
- out += "[antag.get_panel_entry(src)]"
- out += "
"
- out += "Objectives"
+ var/obj_count = 1
+ for(var/datum/objective/objective in objectives)
+ output += "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
- if(objectives && objectives.len)
- var/num = 1
- for(var/datum/objective/O in objectives)
- out += "Objective #[num]: [O.explanation_text] "
- if(O.completed)
- out += "(complete)"
- else
- out += "(incomplete)"
- out += " \[toggle\]"
- out += " \[remove\]
"
- num++
- out += "
\[announce objectives\]"
+ recipient << browse(output,"window=memory")
- else
- out += "None."
- out += "
\[add\]"
- usr << browse(out, "window=edit_memory[src]")
+/datum/mind/proc/edit_memory()
+ if(!ticker || !ticker.mode)
+ alert("Not before round-start!", "Alert")
+ return
- Topic(href, href_list)
- if(!check_rights(R_ADMIN)) return
+ var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
+ out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
+ out += "Assigned role: [assigned_role]. Edit
"
+ out += "
"
+ out += "Factions and special roles:
"
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ out += "[antag.get_panel_entry(src)]"
+ out += "
"
+ out += "Objectives"
- if(href_list["add_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
- if(antag) antag.add_antagonist(src)
-
- else if(href_list["remove_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
- if(antag) antag.remove_antagonist(src)
-
- else if(href_list["equip_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]]
- if(antag) antag.equip(src.current)
-
- else if(href_list["unequip_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]]
- if(antag) antag.unequip(src.current)
-
- else if(href_list["move_antag_to_spawn"])
- var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]]
- if(antag) antag.place_mob(src.current)
-
- else if (href_list["role_edit"])
- var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist
- if (!new_role) return
- assigned_role = new_role
-
- else if (href_list["memory_edit"])
- var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message)
- if (isnull(new_memo)) return
- memory = new_memo
-
- else if (href_list["obj_edit"] || href_list["obj_add"])
- var/datum/objective/objective
- var/objective_pos
- var/def_value
-
- if (href_list["obj_edit"])
- objective = locate(href_list["obj_edit"])
- if (!objective) return
- objective_pos = objectives.Find(objective)
-
- //Text strings are easy to manipulate. Revised for simplicity.
- var/temp_obj_type = "[objective.type]"//Convert path into a text string.
- def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
- if(!def_value)//If it's a custom objective, it will be an empty string.
- def_value = "custom"
-
- var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
- if (!new_obj_type) return
-
- var/datum/objective/new_objective = null
-
- switch (new_obj_type)
- if ("assassinate","protect","debrain", "harm", "brig")
- //To determine what to name the objective in explanation text.
- var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter.
- var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text.
- var/objective_type = "[objective_type_capital][objective_type_text]"//Add them together into a text string.
-
- var/list/possible_targets = list("Free objective")
- for(var/datum/mind/possible_target in ticker.minds)
- if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
- possible_targets += possible_target.current
-
- var/mob/def_target = null
- var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain)
- if (objective&&(objective.type in objective_list) && objective:target)
- def_target = objective:target.current
-
- var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
- if (!new_target) return
-
- var/objective_path = text2path("/datum/objective/[new_obj_type]")
- if (new_target == "Free objective")
- new_objective = new objective_path
- new_objective.owner = src
- new_objective:target = null
- new_objective.explanation_text = "Free objective"
- else
- new_objective = new objective_path
- new_objective.owner = src
- new_objective:target = new_target:mind
- //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
- new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
-
- if ("prevent")
- new_objective = new /datum/objective/block
- new_objective.owner = src
-
- if ("hijack")
- new_objective = new /datum/objective/hijack
- new_objective.owner = src
-
- if ("escape")
- new_objective = new /datum/objective/escape
- new_objective.owner = src
-
- if ("survive")
- new_objective = new /datum/objective/survive
- new_objective.owner = src
-
- if ("mercenary")
- new_objective = new /datum/objective/nuclear
- new_objective.owner = src
-
- if ("steal")
- if (!istype(objective, /datum/objective/steal))
- new_objective = new /datum/objective/steal
- new_objective.owner = src
- else
- new_objective = objective
- var/datum/objective/steal/steal = new_objective
- if (!steal.select_target())
- return
-
- if("download","capture","absorb")
- var/def_num
- if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
- def_num = objective.target_amount
-
- var/target_number = input("Input target number:", "Objective", def_num) as num|null
- if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
- return
-
- switch(new_obj_type)
- if("download")
- new_objective = new /datum/objective/download
- new_objective.explanation_text = "Download [target_number] research levels."
- if("capture")
- new_objective = new /datum/objective/capture
- new_objective.explanation_text = "Accumulate [target_number] capture points."
- if("absorb")
- new_objective = new /datum/objective/absorb
- new_objective.explanation_text = "Absorb [target_number] compatible genomes."
- new_objective.owner = src
- new_objective.target_amount = target_number
-
- if ("custom")
- var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null)
- if (!expl) return
- new_objective = new /datum/objective
- new_objective.owner = src
- new_objective.explanation_text = expl
-
- if (!new_objective) return
-
- if (objective)
- objectives -= objective
- objectives.Insert(objective_pos, new_objective)
+ if(objectives && objectives.len)
+ var/num = 1
+ for(var/datum/objective/O in objectives)
+ out += "Objective #[num]: [O.explanation_text] "
+ if(O.completed)
+ out += "(complete)"
else
- objectives += new_objective
+ out += "(incomplete)"
+ out += " \[toggle\]"
+ out += " \[remove\]
"
+ num++
+ out += "
\[announce objectives\]"
- else if (href_list["obj_delete"])
- var/datum/objective/objective = locate(href_list["obj_delete"])
- if(!istype(objective)) return
- objectives -= objective
+ else
+ out += "None."
+ out += "
\[add\]"
+ usr << browse(out, "window=edit_memory[src]")
- else if(href_list["obj_completed"])
- var/datum/objective/objective = locate(href_list["obj_completed"])
- if(!istype(objective)) return
- objective.completed = !objective.completed
+/datum/mind/Topic(href, href_list)
+ if(!check_rights(R_ADMIN)) return
- else if(href_list["implant"])
- var/mob/living/carbon/human/H = current
+ if(href_list["add_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
+ if(antag) antag.add_antagonist(src, 1, 1, 0, 1, 1) // Ignore equipment and role type for this.
- BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not.
+ else if(href_list["remove_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
+ if(antag) antag.remove_antagonist(src)
- switch(href_list["implant"])
- if("remove")
- for(var/obj/item/weapon/implant/loyalty/I in H.contents)
- for(var/obj/item/organ/external/organs in H.organs)
- if(I in organs.implants)
- qdel(I)
- break
- H << "Your loyalty implant has been deactivated."
- log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
- if("add")
- H << "You somehow have become the recepient of a loyalty transplant, and it just activated!"
- H.implant_loyalty(H, override = TRUE)
- log_admin("[key_name_admin(usr)] has loyalty implanted [current].")
+ else if(href_list["equip_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]]
+ if(antag) antag.equip(src.current)
+
+ else if(href_list["unequip_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]]
+ if(antag) antag.unequip(src.current)
+
+ else if(href_list["move_antag_to_spawn"])
+ var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]]
+ if(antag) antag.place_mob(src.current)
+
+ else if (href_list["role_edit"])
+ var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist
+ if (!new_role) return
+ assigned_role = new_role
+
+ else if (href_list["memory_edit"])
+ var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message)
+ if (isnull(new_memo)) return
+ memory = new_memo
+
+ else if (href_list["obj_edit"] || href_list["obj_add"])
+ var/datum/objective/objective
+ var/objective_pos
+ var/def_value
+
+ if (href_list["obj_edit"])
+ objective = locate(href_list["obj_edit"])
+ if (!objective) return
+ objective_pos = objectives.Find(objective)
+
+ //Text strings are easy to manipulate. Revised for simplicity.
+ var/temp_obj_type = "[objective.type]"//Convert path into a text string.
+ def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
+ if(!def_value)//If it's a custom objective, it will be an empty string.
+ def_value = "custom"
+
+ var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
+ if (!new_obj_type) return
+
+ var/datum/objective/new_objective = null
+
+ switch (new_obj_type)
+ if ("assassinate","protect","debrain", "harm", "brig")
+ //To determine what to name the objective in explanation text.
+ var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter.
+ var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text.
+ var/objective_type = "[objective_type_capital][objective_type_text]"//Add them together into a text string.
+
+ var/list/possible_targets = list("Free objective")
+ for(var/datum/mind/possible_target in ticker.minds)
+ if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
+ possible_targets += possible_target.current
+
+ var/mob/def_target = null
+ var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain)
+ if (objective&&(objective.type in objective_list) && objective:target)
+ def_target = objective:target.current
+
+ var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
+ if (!new_target) return
+
+ var/objective_path = text2path("/datum/objective/[new_obj_type]")
+ if (new_target == "Free objective")
+ new_objective = new objective_path
+ new_objective.owner = src
+ new_objective:target = null
+ new_objective.explanation_text = "Free objective"
else
- /*
- else if (href_list["monkey"])
- var/mob/living/L = current
- if (L.monkeyizing)
- return
- switch(href_list["monkey"])
- if("healthy")
- if (usr.client.holder.rights & R_ADMIN)
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]")
- src = null
- M = H.monkeyize()
- src = M.mind
- //world << "DEBUG: \"healthy\": M=[M], M.mind=[M.mind], src=[src]!"
- else if (istype(M) && length(M.viruses))
- for(var/datum/disease/D in M.viruses)
- D.cure(0)
- sleep(0) //because deleting of virus is done through spawn(0)
- if("infected")
- if (usr.client.holder.rights & R_ADMIN)
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]", 1)
- src = null
- M = H.monkeyize()
- src = M.mind
- current.contract_disease(new /datum/disease/jungle_fever,1,0)
- else if (istype(M))
- current.contract_disease(new /datum/disease/jungle_fever,1,0)
- if("human")
- var/mob/living/carbon/monkey/M = current
- if (istype(M))
- for(var/datum/disease/D in M.viruses)
- if (istype(D,/datum/disease/jungle_fever))
- D.cure(0)
- sleep(0) //because deleting of virus is doing throught spawn(0)
- log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
- message_admins("[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]")
- var/obj/item/weapon/dnainjector/m2h/m2h = new
- var/obj/item/weapon/implant/mobfinder = new(M) //hack because humanizing deletes mind --rastaf0
- src = null
- m2h.inject(M)
- src = mobfinder.loc:mind
- qdel(mobfinder)
- current.radiation -= 50
- */
- else if (href_list["silicon"])
- BITSET(current.hud_updateflag, SPECIALROLE_HUD)
- switch(href_list["silicon"])
+ new_objective = new objective_path
+ new_objective.owner = src
+ new_objective:target = new_target:mind
+ //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
+ new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
- if("unemag")
- var/mob/living/silicon/robot/R = current
- if (istype(R))
+ if ("prevent")
+ new_objective = new /datum/objective/block
+ new_objective.owner = src
+
+ if ("hijack")
+ new_objective = new /datum/objective/hijack
+ new_objective.owner = src
+
+ if ("escape")
+ new_objective = new /datum/objective/escape
+ new_objective.owner = src
+
+ if ("survive")
+ new_objective = new /datum/objective/survive
+ new_objective.owner = src
+
+ if ("mercenary")
+ new_objective = new /datum/objective/nuclear
+ new_objective.owner = src
+
+ if ("steal")
+ if (!istype(objective, /datum/objective/steal))
+ new_objective = new /datum/objective/steal
+ new_objective.owner = src
+ else
+ new_objective = objective
+ var/datum/objective/steal/steal = new_objective
+ if (!steal.select_target())
+ return
+
+ if("download","capture","absorb")
+ var/def_num
+ if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
+ def_num = objective.target_amount
+
+ var/target_number = input("Input target number:", "Objective", def_num) as num|null
+ if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
+ return
+
+ switch(new_obj_type)
+ if("download")
+ new_objective = new /datum/objective/download
+ new_objective.explanation_text = "Download [target_number] research levels."
+ if("capture")
+ new_objective = new /datum/objective/capture
+ new_objective.explanation_text = "Accumulate [target_number] capture points."
+ if("absorb")
+ new_objective = new /datum/objective/absorb
+ new_objective.explanation_text = "Absorb [target_number] compatible genomes."
+ new_objective.owner = src
+ new_objective.target_amount = target_number
+
+ if ("custom")
+ var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null)
+ if (!expl) return
+ new_objective = new /datum/objective
+ new_objective.owner = src
+ new_objective.explanation_text = expl
+
+ if (!new_objective) return
+
+ if (objective)
+ objectives -= objective
+ objectives.Insert(objective_pos, new_objective)
+ else
+ objectives += new_objective
+
+ else if (href_list["obj_delete"])
+ var/datum/objective/objective = locate(href_list["obj_delete"])
+ if(!istype(objective)) return
+ objectives -= objective
+
+ else if(href_list["obj_completed"])
+ var/datum/objective/objective = locate(href_list["obj_completed"])
+ if(!istype(objective)) return
+ objective.completed = !objective.completed
+
+ else if(href_list["implant"])
+ var/mob/living/carbon/human/H = current
+
+ BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not.
+
+ switch(href_list["implant"])
+ if("remove")
+ for(var/obj/item/weapon/implant/loyalty/I in H.contents)
+ for(var/obj/item/organ/external/organs in H.organs)
+ if(I in organs.implants)
+ qdel(I)
+ break
+ H << "Your loyalty implant has been deactivated."
+ log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
+ if("add")
+ H << "You somehow have become the recepient of a loyalty transplant, and it just activated!"
+ H.implant_loyalty(H, override = TRUE)
+ log_admin("[key_name_admin(usr)] has loyalty implanted [current].")
+ else
+ else if (href_list["silicon"])
+ BITSET(current.hud_updateflag, SPECIALROLE_HUD)
+ switch(href_list["silicon"])
+
+ if("unemag")
+ var/mob/living/silicon/robot/R = current
+ if (istype(R))
+ R.emagged = 0
+ if (R.activated(R.module.emag))
+ R.module_active = null
+ if(R.module_state_1 == R.module.emag)
+ R.module_state_1 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_2 == R.module.emag)
+ R.module_state_2 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_3 == R.module.emag)
+ R.module_state_3 = null
+ R.contents -= R.module.emag
+ log_admin("[key_name_admin(usr)] has unemag'ed [R].")
+
+ if("unemagcyborgs")
+ if (istype(current, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/ai = current
+ for (var/mob/living/silicon/robot/R in ai.connected_robots)
R.emagged = 0
- if (R.activated(R.module.emag))
- R.module_active = null
- if(R.module_state_1 == R.module.emag)
- R.module_state_1 = null
- R.contents -= R.module.emag
- else if(R.module_state_2 == R.module.emag)
- R.module_state_2 = null
- R.contents -= R.module.emag
- else if(R.module_state_3 == R.module.emag)
- R.module_state_3 = null
- R.contents -= R.module.emag
- log_admin("[key_name_admin(usr)] has unemag'ed [R].")
+ if (R.module)
+ if (R.activated(R.module.emag))
+ R.module_active = null
+ if(R.module_state_1 == R.module.emag)
+ R.module_state_1 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_2 == R.module.emag)
+ R.module_state_2 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_3 == R.module.emag)
+ R.module_state_3 = null
+ R.contents -= R.module.emag
+ log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
- if("unemagcyborgs")
- if (istype(current, /mob/living/silicon/ai))
- var/mob/living/silicon/ai/ai = current
- for (var/mob/living/silicon/robot/R in ai.connected_robots)
- R.emagged = 0
- if (R.module)
- if (R.activated(R.module.emag))
- R.module_active = null
- if(R.module_state_1 == R.module.emag)
- R.module_state_1 = null
- R.contents -= R.module.emag
- else if(R.module_state_2 == R.module.emag)
- R.module_state_2 = null
- R.contents -= R.module.emag
- else if(R.module_state_3 == R.module.emag)
- R.module_state_3 = null
- R.contents -= R.module.emag
- log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
-
- else if (href_list["common"])
- switch(href_list["common"])
- if("undress")
- for(var/obj/item/W in current)
- current.drop_from_inventory(W)
- if("takeuplink")
- take_uplink()
- memory = null//Remove any memory they may have had.
- if("crystals")
- if (usr.client.holder.rights & R_FUN)
- var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
- var/crystals
+ else if (href_list["common"])
+ switch(href_list["common"])
+ if("undress")
+ for(var/obj/item/W in current)
+ current.drop_from_inventory(W)
+ if("takeuplink")
+ take_uplink()
+ memory = null//Remove any memory they may have had.
+ if("crystals")
+ if (usr.client.holder.rights & R_FUN)
+ var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
+ var/crystals
+ if (suplink)
+ crystals = suplink.uses
+ crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
+ if (!isnull(crystals))
if (suplink)
- crystals = suplink.uses
- crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
- if (!isnull(crystals))
- if (suplink)
- suplink.uses = crystals
+ suplink.uses = crystals
- else if (href_list["obj_announce"])
- var/obj_count = 1
- current << "Your current objectives:"
- for(var/datum/objective/objective in objectives)
- current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
- edit_memory()
-/*
- proc/clear_memory(var/silent = 1)
- var/datum/game_mode/current_mode = ticker.mode
+ else if (href_list["obj_announce"])
+ var/obj_count = 1
+ current << "\blue Your current objectives:"
+ for(var/datum/objective/objective in objectives)
+ current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ edit_memory()
- // remove traitor uplinks
- var/list/L = current.get_contents()
- for (var/t in L)
- if (istype(t, /obj/item/device/pda))
- if (t:uplink) qdel(t:uplink)
- t:uplink = null
- else if (istype(t, /obj/item/device/radio))
- if (t:traitorradio) qdel(t:traitorradio)
- t:traitorradio = null
- t:traitor_frequency = 0.0
- else if (istype(t, /obj/item/weapon/SWF_uplink) || istype(t, /obj/item/weapon/syndicate_uplink))
- if (t:origradio)
- var/obj/item/device/radio/R = t:origradio
- R.loc = current.loc
- R.traitorradio = null
- R.traitor_frequency = 0.0
- qdel(t)
+/datum/mind/proc/find_syndicate_uplink()
+ var/list/L = current.get_contents()
+ for (var/obj/item/I in L)
+ if (I.hidden_uplink)
+ return I.hidden_uplink
+ return null
- // remove wizards spells
- //If there are more special powers that need removal, they can be procced into here./N
- current.spellremove(current)
-
- // clear memory
- memory = ""
- special_role = null
-
-*/
-
- proc/find_syndicate_uplink()
- var/list/L = current.get_contents()
- for (var/obj/item/I in L)
- if (I.hidden_uplink)
- return I.hidden_uplink
- return null
-
- proc/take_uplink()
- var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
- if(H)
- qdel(H)
+/datum/mind/proc/take_uplink()
+ var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
+ if(H)
+ qdel(H)
- // check whether this mind's mob has been brigged for the given duration
- // have to call this periodically for the duration to work properly
- proc/is_brigged(duration)
- var/turf/T = current.loc
- if(!istype(T))
- brigged_since = -1
- return 0
-
- var/is_currently_brigged = 0
-
- if(istype(T.loc,/area/security/brig))
- is_currently_brigged = 1
- for(var/obj/item/weapon/card/id/card in current)
+// check whether this mind's mob has been brigged for the given duration
+// have to call this periodically for the duration to work properly
+/datum/mind/proc/is_brigged(duration)
+ var/turf/T = current.loc
+ if(!istype(T))
+ brigged_since = -1
+ return 0
+ var/is_currently_brigged = 0
+ if(istype(T.loc,/area/security/brig))
+ is_currently_brigged = 1
+ for(var/obj/item/weapon/card/id/card in current)
+ is_currently_brigged = 0
+ break // if they still have ID they're not brigged
+ for(var/obj/item/device/pda/P in current)
+ if(P.id)
is_currently_brigged = 0
break // if they still have ID they're not brigged
- for(var/obj/item/device/pda/P in current)
- if(P.id)
- is_currently_brigged = 0
- break // if they still have ID they're not brigged
- if(!is_currently_brigged)
- brigged_since = -1
- return 0
+ if(!is_currently_brigged)
+ brigged_since = -1
+ return 0
- if(brigged_since == -1)
- brigged_since = world.time
+ if(brigged_since == -1)
+ brigged_since = world.time
- return (duration <= world.time - brigged_since)
+ return (duration <= world.time - brigged_since)
+/datum/mind/proc/reset()
+ assigned_role = null
+ special_role = null
+ role_alt_title = null
+ assigned_job = null
+ //faction = null //Uncommenting this causes a compile error due to 'undefined type', fucked if I know.
+ changeling = null
+ initial_account = null
+ objectives = list()
+ special_verbs = list()
+ has_been_rev = 0
+ rev_cooldown = 0
+ brigged_since = -1
//Antagonist role check
/mob/living/proc/check_special_role(role)
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index a70822942f..65f34ed580 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -310,7 +310,7 @@ var/global/ManifestJSON
item_state = "beachball"
density = 0
anchored = 0
- w_class = 2.0
+ w_class = 4
force = 0.0
throwforce = 0.0
throw_speed = 1
diff --git a/code/game/antagonist/_antagonist_setup.dm b/code/game/antagonist/_antagonist_setup.dm
new file mode 100644
index 0000000000..ebf22a21c9
--- /dev/null
+++ b/code/game/antagonist/_antagonist_setup.dm
@@ -0,0 +1,72 @@
+/*
+ MODULAR ANTAGONIST SYSTEM
+
+ Attempts to move all the bullshit snowflake antag tracking code into its own system, which
+ has the added bonus of making the display procs consistent. Still needs work/adjustment/cleanup
+ but should be fairly self-explanatory with a review of the procs. Will supply a few examples
+ of common tasks that the system will be expected to perform below. ~Z
+
+ To use:
+ - Get the appropriate datum via get_antag_data("antagonist id")
+ using the id var of the desired /datum/antagonist ie. var/datum/antagonist/A = get_antag_data("traitor")
+ - Call add_antagonist() on the desired target mind ie. A.add_antagonist(mob.mind)
+ - To ignore protected roles, supply a positive second argument.
+ - To skip equipping with appropriate gear, supply a positive third argument.
+*/
+
+// Antagonist datum flags.
+#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning.
+#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning.
+#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged.
+#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name.
+#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted.
+#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report.
+#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist.
+#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location.
+#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
+#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
+#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
+
+// Globals.
+var/global/list/all_antag_types = list()
+var/global/list/all_antag_spawnpoints = list()
+var/global/list/antag_names_to_ids = list()
+
+// Global procs.
+/proc/get_antag_data(var/antag_type)
+ if(all_antag_types[antag_type])
+ return all_antag_types[antag_type]
+ else
+ for(var/cur_antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[cur_antag_type]
+ if(antag && antag.is_type(antag_type))
+ return antag
+
+/proc/clear_antag_roles(var/datum/mind/player, var/implanted)
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE))
+ antag.remove_antagonist(player, 1, implanted)
+
+/proc/update_antag_icons(var/datum/mind/player)
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ if(player)
+ antag.update_icons_removed(player)
+ if(antag.is_antagonist(player))
+ antag.update_icons_added(player)
+ else
+ antag.update_all_icons()
+
+/proc/populate_antag_type_list()
+ for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist)
+ var/datum/antagonist/A = new antag_type
+ all_antag_types[A.id] = A
+ all_antag_spawnpoints[A.landmark_id] = list()
+ antag_names_to_ids[A.role_text] = A.id
+
+/proc/get_antags(var/atype)
+ var/datum/antagonist/antag = all_antag_types[atype]
+ if(antag && islist(antag.current_antagonists))
+ return antag.current_antagonists
+ return list()
\ No newline at end of file
diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm
index 1ab79f26b5..f93409a820 100644
--- a/code/game/antagonist/alien/xenomorph.dm
+++ b/code/game/antagonist/alien/xenomorph.dm
@@ -26,12 +26,12 @@ var/datum/antagonist/xenos/xenomorphs
/datum/antagonist/xenos/Topic(href, href_list)
if (..())
return
- if(href_list["move_to_spawn"]) place_mob(href_list["move_to_spawn"])
+ if(href_list["move_to_spawn"]) place_mob(locate(href_list["move_to_spawn"]))
/datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player)
return "\[move to vent\]"
-/datum/antagonist/xenos/random_spawn()
+/datum/antagonist/xenos/attempt_random_spawn()
if(config.aliens_allowed) ..()
/datum/antagonist/xenos/proc/get_vents()
diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm
index aad02b1c6c..11431682a1 100644
--- a/code/game/antagonist/antagonist.dm
+++ b/code/game/antagonist/antagonist.dm
@@ -33,8 +33,9 @@
var/nuke_spawn_loc
var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance.
- var/list/starting_locations = list()
var/list/current_antagonists = list()
+ var/list/pending_antagonists = list()
+ var/list/starting_locations = list()
var/list/global_objectives = list()
var/list/restricted_jobs = list()
var/list/protected_jobs = list()
@@ -42,209 +43,70 @@
var/default_access = list()
var/id_type = /obj/item/weapon/card/id
+ var/announced
/datum/antagonist/New()
..()
cur_max = max_antags
get_starting_locations()
+ if(!role_text_plural)
+ role_text_plural = role_text
if(config.protect_roles_from_antagonist)
restricted_jobs |= protected_jobs
/datum/antagonist/proc/tick()
return 1
-/datum/antagonist/proc/get_panel_entry(var/datum/mind/player)
+/datum/antagonist/proc/get_candidates(var/ghosts_only)
+ candidates = list() // Clear.
+ candidates = ticker.mode.get_players_for_role(role_type, id)
+ // Prune restricted jobs and status. Broke it up for readability.
+ for(var/datum/mind/player in candidates)
+ if(ghosts_only && !istype(player.current, /mob/dead))
+ candidates -= player
+ else if(player.special_role)
+ candidates -= player
+ else if (player in pending_antagonists)
+ candidates -= player
+ else if(!can_become_antag(player))
+ candidates -= player
+ return candidates
- var/dat = "| [role_text]:"
- var/extra = get_extra_panel_options(player)
- if(is_antagonist(player))
- dat += "\[-\]"
- dat += "\[equip\]"
- if(starting_locations && starting_locations.len)
- dat += "\[move to spawn\]"
- if(extra) dat += "[extra]"
+/datum/antagonist/proc/attempt_random_spawn()
+ attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
+
+/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
+ if(!can_late_spawn())
+ return
+ if(!istype(player)) player = get_candidates(is_latejoin_template())
+ player.current << "You have been selected this round as an antagonist!"
+ if(istype(player.current, /mob/dead))
+ create_default(player.current)
else
- dat += "\[+\]"
- dat += " |
"
-
- return dat
-
-/datum/antagonist/proc/get_extra_panel_options()
+ add_antagonist(player,0,1,0,1,1)
return
-/datum/antagonist/proc/get_starting_locations()
- if(landmark_id)
- starting_locations = list()
- for(var/obj/effect/landmark/L in landmarks_list)
- if(L.name == landmark_id)
- starting_locations |= get_turf(L)
+/datum/antagonist/proc/attempt_spawn(var/ghosts_only)
-/datum/antagonist/proc/place_all_mobs()
- if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len)
- return
- for(var/datum/mind/player in current_antagonists)
- player.current.loc = pick(starting_locations)
+ // Get the raw list of potential players.
+ update_current_antag_max()
+ candidates = get_candidates(ghosts_only)
-/datum/antagonist/proc/finalize(var/datum/mind/target)
-
- // This will fail if objectives have already been generated.
- create_global_objectives()
-
- if(leader && flags & ANTAG_HAS_NUKE && !spawned_nuke)
- make_nuke(leader)
-
- if(target)
- apply(target)
- create_objectives(target)
- update_icons_added(target)
- greet(target)
- return
-
- for(var/datum/mind/player in current_antagonists)
- apply(player)
- equip(player.current)
- create_objectives(player)
- update_icons_added(player)
- greet(player)
-
- place_all_mobs()
-
- spawn(1)
- if(spawn_announcement)
- if(spawn_announcement_delay)
- sleep(spawn_announcement_delay)
- if(spawn_announcement_sound)
- command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
- else
- command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
-
-
-/datum/antagonist/proc/print_player_summary()
-
- if(!current_antagonists.len)
+ // Update our boundaries.
+ if(!candidates.len)
return 0
- var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:"
- for(var/datum/mind/P in current_antagonists)
- text += print_player_full(P)
- text += get_special_objective_text(P)
- var/failed
- if(!global_objectives.len && P.objectives && P.objectives.len)
- var/num = 1
- for(var/datum/objective/O in P.objectives)
- text += print_objective(O, num)
- if(O.completed) // This is set actively in check_victory()
- text += "Success!"
- feedback_add_details(feedback_tag,"[O.type]|SUCCESS")
- else
- text += "Fail."
- feedback_add_details(feedback_tag,"[O.type]|FAIL")
- failed = 1
- num++
+ //Grab candidates randomly until we have enough.
+ while(candidates.len)
+ var/datum/mind/player = pick(candidates)
+ pending_antagonists |= player
+ candidates -= player
+ return 1
- if(!config.objectives_disabled)
- if(failed)
- text += "
The [role_text] has failed."
- else
- text += "
The [role_text] was successful!"
-
- if(global_objectives && global_objectives.len)
- text += "
Their objectives were:"
- var/num = 1
- for(var/datum/objective/O in global_objectives)
- text += print_objective(O, num, 1)
- num++
-
- // Display the results.
- world << text
-
-/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success)
- var/text = "
Objective [num]: [O.explanation_text] "
- if(append_success)
- if(O.check_completion())
- text += "Success!"
- else
- text += "Fail."
- return text
-
-/datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
- var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
- var/text = "
[ply.name] ([ply.key]) as \a [role] ("
- if(ply.current)
- if(ply.current.stat == DEAD)
- text += "died"
- else if(isNotStationLevel(ply.current.z))
- text += "fled the station"
- else
- text += "survived"
- if(ply.current.real_name != ply.name)
- text += " as [ply.current.real_name]"
- else
- text += "body destroyed"
- text += ")"
-
- return text
-
-/datum/antagonist/proc/print_player_full(var/datum/mind/ply)
- var/text = print_player_lite(ply)
-
- var/TC_uses = 0
- var/uplink_true = 0
- var/purchases = ""
- for(var/obj/item/device/uplink/H in world_uplinks)
- if(H && H.uplink_owner && H.uplink_owner == ply)
- TC_uses += H.used_TC
- uplink_true = 1
- var/list/refined_log = new()
- for(var/datum/uplink_item/UI in H.purchase_log)
- var/obj/I = new UI.path
- refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]")
- qdel(I)
- purchases = english_list(refined_log, nothing_text = "")
- if(uplink_true)
- text += " (used [TC_uses] TC)"
- if(purchases)
- text += "
[purchases]"
-
- return text
-
-/datum/antagonist/proc/update_all_icons()
- if(!antag_indicator)
+/datum/antagonist/proc/finalize_spawn()
+ if(!pending_antagonists || !pending_antagonists.len)
return
- for(var/datum/mind/antag in current_antagonists)
- if(antag.current && antag.current.client)
- for(var/image/I in antag.current.client.images)
- if(I.icon_state == antag_indicator)
- qdel(I)
- for(var/datum/mind/other_antag in current_antagonists)
- if(other_antag.current)
- antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator)
-
-/datum/antagonist/proc/update_icons_added(var/datum/mind/player)
- if(!antag_indicator || !player.current)
- return
- spawn(0)
- for(var/datum/mind/antag in current_antagonists)
- if(!antag.current)
- continue
- if(antag.current.client)
- antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator)
- if(player.current.client)
- player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator)
-
-/datum/antagonist/proc/update_icons_removed(var/datum/mind/player)
- if(!antag_indicator || !player.current)
- return
- spawn(0)
- for(var/datum/mind/antag in current_antagonists)
- if(antag.current)
- if(antag.current.client)
- for(var/image/I in antag.current.client.images)
- if(I.icon_state == antag_indicator && I.loc == player.current)
- qdel(I)
- if(player.current && player.current.client)
- for(var/image/I in player.current.client.images)
- if(I.icon_state == antag_indicator)
- qdel(I)
-
-
+ for(var/datum/mind/player in pending_antagonists)
+ if(can_become_antag(player) && !player.special_role)
+ add_antagonist(player,0,0,1)
+ pending_antagonists.Cut()
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm
new file mode 100644
index 0000000000..e3c653a4e5
--- /dev/null
+++ b/code/game/antagonist/antagonist_add.dm
@@ -0,0 +1,31 @@
+/datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
+ if(!istype(player))
+ return 0
+ if(!player.current)
+ return 0
+ if(player in current_antagonists)
+ return 0
+ if(!can_become_antag(player, ignore_role))
+ return 0
+
+ current_antagonists |= player
+ if(flags & ANTAG_OVERRIDE_JOB)
+ player.assigned_role = "MODE"
+
+ if(istype(player.current, /mob/dead))
+ create_default(player.current)
+ else
+ create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance)
+ if(!do_not_equip)
+ equip(player.current)
+ return 1
+
+/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
+ if(player in current_antagonists)
+ player.current << "You are no longer a [role_text]!"
+ current_antagonists -= player
+ player.special_role = null
+ update_icons_removed(player)
+ BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm
deleted file mode 100644
index 35af4e6f80..0000000000
--- a/code/game/antagonist/antagonist_build.dm
+++ /dev/null
@@ -1,127 +0,0 @@
-/datum/antagonist/proc/create_objectives(var/datum/mind/player)
- if(config.objectives_disabled)
- return 0
- if(global_objectives && global_objectives.len)
- player.objectives |= global_objectives
- return 1
-
-/datum/antagonist/proc/apply(var/datum/mind/player)
-
- if(flags & ANTAG_HAS_LEADER && !leader)
- leader = current_antagonists[1]
-
- // Get the mob.
- if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
- var/mob/holder = player.current
- player.current = new mob_path(get_turf(player.current))
- player.transfer_to(player.current)
- if(holder) qdel(holder)
-
- player.original = player.current
- return player.current
-
-/datum/antagonist/proc/equip(var/mob/living/carbon/human/player)
-
- if(!istype(player))
- return 0
-
- // This could use work.
- if(flags & ANTAG_CLEAR_EQUIPMENT)
- for(var/obj/item/thing in player.contents)
- player.drop_from_inventory(thing)
- if(thing.loc != player)
- qdel(thing)
- return 1
-
- if(flags & ANTAG_SET_APPEARANCE)
- player.change_appearance(APPEARANCE_ALL, player.loc, player, valid_species, state = z_state)
-
-/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player)
- if(!istype(player))
- return 0
- return 1
-
-/datum/antagonist/proc/greet(var/datum/mind/player)
-
- // Basic intro text.
- player.current << "You are a [role_text]!"
- if(leader_welcome_text && player.current == leader)
- player.current << "[leader_welcome_text]"
- else
- player.current << "[welcome_text]"
- show_objectives(player)
-
- // Choose a name, if any.
- if(flags & ANTAG_CHOOSE_NAME)
- spawn(5)
- var/newname = sanitize(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
- if (newname)
- player.current.real_name = newname
- player.current.name = player.current.real_name
- player.name = player.current.name
- // Update any ID cards.
- update_access(player.current)
-
- // Clown clumsiness check, I guess downstream might use it.
- if (player.current.mind)
- if (player.current.mind.assigned_role == "Clown")
- player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
- player.current.mutations.Remove(CLUMSY)
- return 1
-
-/datum/antagonist/proc/update_access(var/mob/living/player)
- for(var/obj/item/weapon/card/id/id in player.contents)
- id.name = "[player.real_name]'s ID Card"
- id.registered_name = player.real_name
-
-/datum/antagonist/proc/random_spawn()
- create_global_objectives()
- attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
- finalize()
-
-/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
-
- var/obj/item/weapon/card/id/W = new id_type(player)
- if(!W) return
- W.name = "[player.real_name]'s ID Card"
- W.access |= default_access
- W.assignment = "[assignment]"
- W.registered_name = player.real_name
- player.equip_to_slot_or_del(W, slot_wear_id)
- return W
-
-/datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player)
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player)
- R.set_frequency(freq)
- player.equip_to_slot_or_del(R, slot_l_ear)
- return R
-
-/datum/antagonist/proc/make_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner)
-
- // Decide on a code.
- var/obj/effect/landmark/nuke_spawn = locate(nuke_spawn_loc ? nuke_spawn_loc : "landmark*Nuclear-Bomb")
-
- var/code
- if(nuke_spawn)
- var/obj/machinery/nuclearbomb/nuke = new(get_turf(nuke_spawn))
- code = "[rand(10000, 99999)]"
- nuke.r_code = code
-
- if(code)
- if(!paper_spawn_loc)
- paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code"))
- if(paper_spawn_loc)
- // Create and pass on the bomb code paper.
- var/obj/item/weapon/paper/P = new(paper_spawn_loc)
- P.info = "The nuclear authorization code is: [code]"
- P.name = "nuclear bomb code"
- if(code_owner)
- code_owner.store_memory("Nuclear Bomb Code: [code]", 0, 0)
- code_owner.current << "The nuclear authorization code is: [code]"
-
- else
- world << "Could not spawn nuclear bomb. Contact a developer."
- return
-
- spawned_nuke = code
- return code
diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm
new file mode 100644
index 0000000000..da0e5b33a1
--- /dev/null
+++ b/code/game/antagonist/antagonist_create.dm
@@ -0,0 +1,118 @@
+/datum/antagonist/proc/create_antagonist(var/datum/mind/target, var/move, var/gag_announcement, var/preserve_appearance)
+
+ if(!target)
+ return
+
+ update_antag_mob(target, preserve_appearance)
+ if(!target.current)
+ remove_antagonist(target)
+ return 0
+ if(flags & ANTAG_CHOOSE_NAME)
+ spawn(1)
+ set_antag_name(target.current)
+ if(move)
+ place_mob(target.current)
+ update_leader()
+ create_objectives(target)
+ update_icons_added(target)
+ greet(target)
+ announce_antagonist_spawn()
+
+/datum/antagonist/proc/create_default(var/mob/source)
+ var/mob/living/M
+ if(mob_path)
+ M = new mob_path(get_turf(source))
+ else
+ M = new /mob/living/carbon/human(get_turf(source))
+ M.real_name = source.real_name
+ M.name = M.real_name
+ M.ckey = source.ckey
+ add_antagonist(M.mind, 1, 0, 1) // Equip them and move them to spawn.
+ return M
+
+/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
+
+ var/obj/item/weapon/card/id/W = new id_type(player)
+ if(!W) return
+ W.name = "[player.real_name]'s ID Card"
+ W.access |= default_access
+ W.assignment = "[assignment]"
+ W.registered_name = player.real_name
+ player.equip_to_slot_or_del(W, slot_wear_id)
+ return W
+
+/datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player)
+ var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player)
+ R.set_frequency(freq)
+ player.equip_to_slot_or_del(R, slot_l_ear)
+ return R
+
+/datum/antagonist/proc/create_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner)
+
+ // Decide on a code.
+ var/obj/effect/landmark/nuke_spawn = locate(nuke_spawn_loc ? nuke_spawn_loc : "landmark*Nuclear-Bomb")
+
+ var/code
+ if(nuke_spawn)
+ var/obj/machinery/nuclearbomb/nuke = new(get_turf(nuke_spawn))
+ code = "[rand(10000, 99999)]"
+ nuke.r_code = code
+
+ if(code)
+ if(!paper_spawn_loc)
+ if(leader && leader.current)
+ paper_spawn_loc = get_turf(leader.current)
+ else
+ paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code"))
+
+ if(paper_spawn_loc)
+ // Create and pass on the bomb code paper.
+ var/obj/item/weapon/paper/P = new(paper_spawn_loc)
+ P.info = "The nuclear authorization code is: [code]"
+ P.name = "nuclear bomb code"
+ if(leader && leader.current)
+ if(get_turf(P) == get_turf(leader.current) && !(leader.current.l_hand && leader.current.r_hand))
+ leader.current.put_in_hands(P)
+
+ if(!code_owner && leader)
+ code_owner = leader
+ if(code_owner)
+ code_owner.store_memory("Nuclear Bomb Code: [code]", 0, 0)
+ code_owner.current << "The nuclear authorization code is: [code]"
+ else
+ world << "Could not spawn nuclear bomb. Contact a developer."
+ return
+
+ spawned_nuke = code
+ return code
+
+/datum/antagonist/proc/greet(var/datum/mind/player)
+
+ // Basic intro text.
+ player.current << "You are a [role_text]!"
+ if(leader_welcome_text && player == leader)
+ player.current << "[leader_welcome_text]"
+ else
+ player.current << "[welcome_text]"
+
+ if((flags & ANTAG_HAS_NUKE) && !spawned_nuke)
+ create_nuke()
+
+ show_objectives(player)
+
+ // Clown clumsiness check, I guess downstream might use it.
+ if (player.current.mind)
+ if (player.current.mind.assigned_role == "Clown")
+ player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
+ player.current.mutations.Remove(CLUMSY)
+ return 1
+
+/datum/antagonist/proc/set_antag_name(var/mob/living/player)
+ // Choose a name, if any.
+ var/newname = sanitize(input(player, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
+ if (newname)
+ player.real_name = newname
+ player.name = player.real_name
+ if(player.mind) player.mind.name = player.name
+ // Update any ID cards.
+ update_access(player)
diff --git a/code/game/antagonist/antagonist_equip.dm b/code/game/antagonist/antagonist_equip.dm
new file mode 100644
index 0000000000..2f4bc6da3a
--- /dev/null
+++ b/code/game/antagonist/antagonist_equip.dm
@@ -0,0 +1,17 @@
+/datum/antagonist/proc/equip(var/mob/living/carbon/human/player)
+
+ if(!istype(player))
+ return 0
+
+ // This could use work.
+ if(flags & ANTAG_CLEAR_EQUIPMENT)
+ for(var/obj/item/thing in player.contents)
+ player.drop_from_inventory(thing)
+ if(thing.loc != player)
+ qdel(thing)
+ return 1
+
+/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player)
+ if(!istype(player))
+ return 0
+ return 1
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_globals.dm b/code/game/antagonist/antagonist_globals.dm
deleted file mode 100644
index 02ec5304fc..0000000000
--- a/code/game/antagonist/antagonist_globals.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-var/global/list/all_antag_types = list()
-var/global/list/all_antag_spawnpoints = list()
-var/global/list/antag_names_to_ids = list()
-
-/proc/get_antag_data(var/antag_type)
- if(all_antag_types[antag_type])
- return all_antag_types[antag_type]
- else
- for(var/cur_antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[cur_antag_type]
- if(antag && antag.is_type(antag_type))
- return antag
-
-/proc/clear_antag_roles(var/datum/mind/player, var/implanted)
- for(var/antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[antag_type]
- if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE))
- antag.remove_antagonist(player, 1, implanted)
-
-/proc/update_antag_icons(var/datum/mind/player)
- for(var/antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[antag_type]
- if(player)
- antag.update_icons_removed(player)
- if(antag.is_antagonist(player))
- antag.update_icons_added(player)
- else
- antag.update_all_icons()
-
-/proc/populate_antag_type_list()
- for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist)
- var/datum/antagonist/A = new antag_type
- all_antag_types[A.id] = A
- all_antag_spawnpoints[A.landmark_id] = list()
- antag_names_to_ids[A.role_text] = A.id
-
-/proc/get_antags(var/atype)
- var/datum/antagonist/antag = all_antag_types[atype]
- if(antag && islist(antag.current_antagonists))
- return antag.current_antagonists
- return list()
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm
index 92556a817a..a578c1bf4f 100644
--- a/code/game/antagonist/antagonist_helpers.dm
+++ b/code/game/antagonist/antagonist_helpers.dm
@@ -1,10 +1,11 @@
-/datum/antagonist/proc/can_become_antag(var/datum/mind/player)
+/datum/antagonist/proc/can_become_antag(var/datum/mind/player, var/ignore_role)
if(player.current && jobban_isbanned(player.current, bantype))
return 0
- if(player.assigned_role in protected_jobs)
- return 0
- if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs))
- return 0
+ if(!ignore_role)
+ if(player.assigned_role in protected_jobs)
+ return 0
+ if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs))
+ return 0
return 1
/datum/antagonist/proc/antags_are_dead()
@@ -27,3 +28,15 @@
if(antag_type == id || antag_type == role_text)
return 1
return 0
+
+/datum/antagonist/proc/is_votable()
+ return (flags & ANTAG_VOTABLE)
+
+/datum/antagonist/proc/can_late_spawn()
+ update_current_antag_max()
+ if(get_antag_count() >= cur_max)
+ return 0
+ return 1
+
+/datum/antagonist/proc/is_latejoin_template()
+ return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm
index 58997fa68e..432c3f6bbe 100644
--- a/code/game/antagonist/antagonist_objectives.dm
+++ b/code/game/antagonist/antagonist_objectives.dm
@@ -1,5 +1,16 @@
/datum/antagonist/proc/create_global_objectives()
- return !((global_objectives && global_objectives.len) || config.objectives_disabled)
+ if(config.objectives_disabled)
+ return 0
+ if(global_objectives && global_objectives.len)
+ return 0
+ return 1
+
+/datum/antagonist/proc/create_objectives(var/datum/mind/player)
+ if(config.objectives_disabled)
+ return 0
+ if(create_global_objectives())
+ player.objectives |= global_objectives
+ return 1
/datum/antagonist/proc/get_special_objective_text()
return ""
@@ -12,8 +23,6 @@
for(var/datum/objective/O in global_objectives)
if(!O.completed && !O.check_completion())
result = 0
- else
- O.completed = 1 //Will this break anything?
if(result && victory_text)
world << "[victory_text]"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
diff --git a/code/game/antagonist/antagonist_panel.dm b/code/game/antagonist/antagonist_panel.dm
new file mode 100644
index 0000000000..ed8f1d9563
--- /dev/null
+++ b/code/game/antagonist/antagonist_panel.dm
@@ -0,0 +1,61 @@
+/datum/antagonist/proc/get_panel_entry(var/datum/mind/player)
+
+ var/dat = "| [role_text]:"
+ var/extra = get_extra_panel_options(player)
+ if(is_antagonist(player))
+ dat += "\[-\]"
+ dat += "\[equip\]"
+ if(starting_locations && starting_locations.len)
+ dat += "\[move to spawn\]"
+ if(extra) dat += "[extra]"
+ else
+ dat += "\[+\]"
+ dat += " |
"
+
+ return dat
+
+/datum/antagonist/proc/get_extra_panel_options()
+ return
+
+/datum/antagonist/proc/get_check_antag_output(var/datum/admins/caller)
+
+ if(!current_antagonists || !current_antagonists.len)
+ return ""
+
+ var/dat = "
| [role_text_plural] | |
"
+ for(var/datum/mind/player in current_antagonists)
+ var/mob/M = player.current
+ dat += ""
+ if(M)
+ dat += "| [M.real_name]"
+ if(!M.client) dat += " (logged out)"
+ if(M.stat == DEAD) dat += " (DEAD)"
+ dat += " | "
+ dat += "\[PM\]\[TP\] | "
+ else
+ dat += "Mob not found! | "
+ dat += "
"
+ dat += "
"
+
+ if(flags & ANTAG_HAS_NUKE)
+ dat += "
| Nuclear disk(s) |
"
+ for(var/obj/item/weapon/disk/nuclear/N in world)
+ dat += "| [N.name], "
+ var/atom/disk_loc = N.loc
+ while(!istype(disk_loc, /turf))
+ if(istype(disk_loc, /mob))
+ var/mob/M = disk_loc
+ dat += "carried by [M.real_name] "
+ if(istype(disk_loc, /obj))
+ var/obj/O = disk_loc
+ dat += "in \a [O.name] "
+ disk_loc = disk_loc.loc
+ dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z]) |
"
+ dat += "
"
+ dat += get_additional_check_antag_output(caller)
+ dat += "
"
+ return dat
+
+//Overridden elsewhere.
+/datum/antagonist/proc/get_additional_check_antag_output(var/datum/admins/caller)
+ return ""
diff --git a/code/game/antagonist/antagonist_place.dm b/code/game/antagonist/antagonist_place.dm
new file mode 100644
index 0000000000..1d69aaa96f
--- /dev/null
+++ b/code/game/antagonist/antagonist_place.dm
@@ -0,0 +1,29 @@
+/datum/antagonist/proc/get_starting_locations()
+ if(landmark_id)
+ starting_locations = list()
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(L.name == landmark_id)
+ starting_locations |= get_turf(L)
+
+/datum/antagonist/proc/place_all_mobs()
+ if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len)
+ return
+ for(var/datum/mind/player in current_antagonists)
+ player.current.loc = pick(starting_locations)
+
+/datum/antagonist/proc/announce_antagonist_spawn()
+ if(spawn_announcement)
+ if(announced)
+ return
+ announced = 1
+ if(spawn_announcement_delay)
+ sleep(spawn_announcement_delay)
+ if(spawn_announcement_sound)
+ command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
+ else
+ command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
+
+/datum/antagonist/proc/place_mob(var/mob/living/mob)
+ if(!starting_locations || !starting_locations.len)
+ return
+ mob.loc = pick(starting_locations)
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
new file mode 100644
index 0000000000..eaca01986c
--- /dev/null
+++ b/code/game/antagonist/antagonist_print.dm
@@ -0,0 +1,86 @@
+/datum/antagonist/proc/print_player_summary()
+
+ if(!current_antagonists.len)
+ return 0
+
+ var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:"
+ for(var/datum/mind/P in current_antagonists)
+ text += print_player_full(P)
+ text += get_special_objective_text(P)
+ var/failed
+ if(!global_objectives.len && P.objectives && P.objectives.len)
+ var/num = 1
+ for(var/datum/objective/O in P.objectives)
+ text += print_objective(O, num)
+ if(O.check_completion())
+ text += "Success!"
+ feedback_add_details(feedback_tag,"[O.type]|SUCCESS")
+ else
+ text += "Fail."
+ feedback_add_details(feedback_tag,"[O.type]|FAIL")
+ failed = 1
+ num++
+
+ if(!config.objectives_disabled)
+ if(failed)
+ text += "
The [role_text] has failed."
+ else
+ text += "
The [role_text] was successful!"
+
+ if(global_objectives && global_objectives.len)
+ text += "
Their objectives were:"
+ var/num = 1
+ for(var/datum/objective/O in global_objectives)
+ text += print_objective(O, num, 1)
+ num++
+
+ // Display the results.
+ world << text
+
+/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success)
+ var/text = "
Objective [num]: [O.explanation_text] "
+ if(append_success)
+ if(O.check_completion())
+ text += "Success!"
+ else
+ text += "Fail."
+ return text
+
+/datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
+ var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
+ var/text = "
[ply.name] ([ply.key]) as \a [role] ("
+ if(ply.current)
+ if(ply.current.stat == DEAD)
+ text += "died"
+ else if(isNotStationLevel(ply.current.z))
+ text += "fled the station"
+ else
+ text += "survived"
+ if(ply.current.real_name != ply.name)
+ text += " as [ply.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+
+ return text
+
+/datum/antagonist/proc/print_player_full(var/datum/mind/ply)
+ var/text = print_player_lite(ply)
+
+ var/TC_uses = 0
+ var/uplink_true = 0
+ var/purchases = ""
+ for(var/obj/item/device/uplink/H in world_uplinks)
+ if(H && H.owner && H.owner == ply)
+ TC_uses += H.used_TC
+ uplink_true = 1
+ var/list/refined_log = new()
+ for(var/datum/uplink_item/UI in H.purchase_log)
+ refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
+ purchases = english_list(refined_log, nothing_text = "")
+ if(uplink_true)
+ text += " (used [TC_uses] TC)"
+ if(purchases)
+ text += "
[purchases]"
+
+ return text
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_spawn.dm b/code/game/antagonist/antagonist_spawn.dm
deleted file mode 100644
index c8453663fb..0000000000
--- a/code/game/antagonist/antagonist_spawn.dm
+++ /dev/null
@@ -1,85 +0,0 @@
-/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn)
-
- update_cur_max()
- if(get_antag_count() >= cur_max)
- return 0
-
- player.current << "You have been selected this round as an antagonist!"
- add_antagonist(player)
- equip(player.current)
- if(move_to_spawn)
- place_mob(player.current)
- return
-
-/datum/antagonist/proc/update_cur_max()
-
- candidates = list()
- var/main_type
- if(ticker && ticker.mode)
- if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
- main_type = 1
- else
- return list()
-
- cur_max = (main_type ? max_antags_round : max_antags)
- if(ticker.mode.antag_scaling_coeff)
- cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
-
-/datum/antagonist/proc/attempt_spawn(var/ghosts_only)
-
- // Get the raw list of potential players.
- update_cur_max()
- candidates = get_candidates(ghosts_only)
-
- // Update our boundaries.
- if(!candidates.len)
- return 0
-
- //Grab candidates randomly until we have enough.
- while(candidates.len)
- var/datum/mind/player = pick(candidates)
- current_antagonists |= player
- // Update job and role.
- player.special_role = role_text
- if(flags & ANTAG_OVERRIDE_JOB)
- player.assigned_role = "MODE"
- candidates -= player
- return 1
-
-/datum/antagonist/proc/place_mob(var/mob/living/mob)
- if(!starting_locations || !starting_locations.len)
- return
- mob.loc = pick(starting_locations)
-
-/datum/antagonist/proc/add_antagonist(var/datum/mind/player)
- if(!istype(player))
- return 0
- if(player in current_antagonists)
- return 0
- if(!can_become_antag(player))
- return 0
-
- current_antagonists |= player
- apply(player)
- finalize(player)
- return 1
-
-/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
- if(player in current_antagonists)
- player.current << "You are no longer a [role_text]!"
- current_antagonists -= player
- player.special_role = null
- update_icons_removed(player)
- BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
- return 1
- return 0
-
-/datum/antagonist/proc/get_candidates(var/ghosts_only)
-
- candidates = list() // Clear.
- candidates = ticker.mode.get_players_for_role(role_type, id)
- // Prune restricted jobs and status.
- for(var/datum/mind/player in candidates)
- if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs))
- candidates -= player
- return candidates
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm
new file mode 100644
index 0000000000..0fd5fb2a93
--- /dev/null
+++ b/code/game/antagonist/antagonist_update.dm
@@ -0,0 +1,71 @@
+/datum/antagonist/proc/update_leader()
+ if(!leader && current_antagonists.len && (flags & ANTAG_HAS_LEADER))
+ leader = current_antagonists[1]
+
+/datum/antagonist/proc/update_antag_mob(var/datum/mind/player, var/preserve_appearance)
+
+ // Get the mob.
+ if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
+ var/mob/holder = player.current
+ player.current = new mob_path(get_turf(player.current))
+ player.transfer_to(player.current)
+ if(holder) qdel(holder)
+ player.original = player.current
+ if(!preserve_appearance && (flags & ANTAG_SET_APPEARANCE))
+ spawn(3)
+ var/mob/living/carbon/human/H = player.current
+ if(istype(H)) H.change_appearance(APPEARANCE_ALL, H.loc, H, valid_species, state = z_state)
+ return player.current
+
+/datum/antagonist/proc/update_access(var/mob/living/player)
+ for(var/obj/item/weapon/card/id/id in player.contents)
+ id.name = "[player.real_name]'s ID Card"
+ id.registered_name = player.real_name
+
+/datum/antagonist/proc/update_all_icons()
+ if(!antag_indicator)
+ return
+ for(var/datum/mind/antag in current_antagonists)
+ if(antag.current && antag.current.client)
+ for(var/image/I in antag.current.client.images)
+ if(I.icon_state == antag_indicator)
+ qdel(I)
+ for(var/datum/mind/other_antag in current_antagonists)
+ if(other_antag.current)
+ antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator)
+
+/datum/antagonist/proc/update_icons_added(var/datum/mind/player)
+ if(!antag_indicator || !player.current)
+ return
+ spawn(0)
+ for(var/datum/mind/antag in current_antagonists)
+ if(!antag.current)
+ continue
+ if(antag.current.client)
+ antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator)
+ if(player.current.client)
+ player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator)
+
+/datum/antagonist/proc/update_icons_removed(var/datum/mind/player)
+ if(!antag_indicator || !player.current)
+ return
+ spawn(0)
+ for(var/datum/mind/antag in current_antagonists)
+ if(antag.current)
+ if(antag.current.client)
+ for(var/image/I in antag.current.client.images)
+ if(I.icon_state == antag_indicator && I.loc == player.current)
+ qdel(I)
+ if(player.current && player.current.client)
+ for(var/image/I in player.current.client.images)
+ if(I.icon_state == antag_indicator)
+ qdel(I)
+
+/datum/antagonist/proc/update_current_antag_max()
+ var/main_type
+ if(ticker && ticker.mode)
+ if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
+ main_type = 1
+ cur_max = (main_type ? max_antags_round : max_antags)
+ if(ticker.mode.antag_scaling_coeff)
+ cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm
index d03f5c3d8a..376f25c34a 100644
--- a/code/game/antagonist/outsider/deathsquad.dm
+++ b/code/game/antagonist/outsider/deathsquad.dm
@@ -7,7 +7,7 @@ var/datum/antagonist/deathsquad/deathsquad
role_text_plural = "Death Commandos"
welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors."
landmark_id = "Commando"
- flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
max_antags = 4
max_antags_round = 6
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
@@ -23,6 +23,9 @@ var/datum/antagonist/deathsquad/deathsquad
deployed = 1
/datum/antagonist/deathsquad/equip(var/mob/living/carbon/human/player)
+ if(!..())
+ return
+
if (player.mind == leader)
player.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(player), slot_w_uniform)
else
@@ -49,7 +52,7 @@ var/datum/antagonist/deathsquad/deathsquad
id.icon_state = "centcom"
create_radio(DTH_FREQ, player)
-/datum/antagonist/deathsquad/apply(var/datum/mind/player)
+/datum/antagonist/deathsquad/update_antag_mob(var/datum/mind/player)
..()
@@ -76,9 +79,6 @@ var/datum/antagonist/deathsquad/deathsquad
return
-/datum/antagonist/deathsquad/finalize(var/datum/mind/target)
-
- ..()
-
- if(!deployed)
+/datum/antagonist/deathsquad/create_antagonist()
+ if(..() && !deployed)
deployed = 1
diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm
index 946ff1dfc2..d847d4ef7a 100644
--- a/code/game/antagonist/outsider/ert.dm
+++ b/code/game/antagonist/outsider/ert.dm
@@ -10,8 +10,13 @@ var/datum/antagonist/ert/ert
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
max_antags = 5
max_antags_round = 5 // ERT mode?
+ landmark_id = "Response Team"
- flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
+
+/datum/antagonist/ert/create_default(var/mob/source)
+ var/mob/living/carbon/human/M = ..()
+ if(istype(M)) M.age = rand(25,45)
/datum/antagonist/ert/New()
..()
diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm
index 72a6a56d62..1ddc6457d9 100644
--- a/code/game/antagonist/outsider/mercenary.dm
+++ b/code/game/antagonist/outsider/mercenary.dm
@@ -7,8 +7,9 @@ var/datum/antagonist/mercenary/mercs
bantype = "operative"
role_text_plural = "Mercenaries"
landmark_id = "Syndicate-Spawn"
+ leader_welcome_text = "You are the leader of the mercenary strikeforce; hail to the chief. Use :t to speak to your underlings."
welcome_text = "To speak on the strike team's private channel use :t."
- flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
max_antags = 4
max_antags_round = 6
id_type = /obj/item/weapon/card/id/syndicate
@@ -19,9 +20,10 @@ var/datum/antagonist/mercenary/mercs
/datum/antagonist/mercenary/create_global_objectives()
if(!..())
- return
+ return 0
global_objectives = list()
global_objectives |= new /datum/objective/nuclear
+ return 1
/datum/antagonist/mercenary/equip(var/mob/living/carbon/human/player)
@@ -50,7 +52,7 @@ var/datum/antagonist/mercenary/mercs
if(spawnpos > starting_locations.len)
spawnpos = 1
-/datum/antagonist/mercenary/make_nuke()
+/datum/antagonist/mercenary/create_nuke()
..()
// Create the radio.
var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink")
diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm
index 4fed41aa13..5af82ff05d 100644
--- a/code/game/antagonist/outsider/ninja.dm
+++ b/code/game/antagonist/outsider/ninja.dm
@@ -7,16 +7,16 @@ var/datum/antagonist/ninja/ninjas
role_text_plural = "Ninja"
bantype = "ninja"
landmark_id = "ninjastart"
- welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor."
+ welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
- max_antags = 3
- max_antags_round = 3
+ max_antags = 1
+ max_antags_round = 1
/datum/antagonist/ninja/New()
..()
ninjas = src
-/datum/antagonist/ninja/random_spawn()
+/datum/antagonist/ninja/attempt_random_spawn()
if(config.ninjas_allowed) ..()
/datum/antagonist/ninja/create_objectives(var/datum/mind/ninja)
@@ -82,7 +82,7 @@ var/datum/antagonist/ninja/ninjas
player.store_memory("Directive: [directive]
")
player << "Remember your directive: [directive]."
-/datum/antagonist/ninja/apply(var/datum/mind/player)
+/datum/antagonist/ninja/update_antag_mob(var/datum/mind/player)
..()
var/ninja_title = pick(ninja_titles)
var/ninja_name = pick(ninja_names)
diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm
index a7949011fc..4d25b1c3fe 100644
--- a/code/game/antagonist/outsider/raider.dm
+++ b/code/game/antagonist/outsider/raider.dm
@@ -8,7 +8,7 @@ var/datum/antagonist/raider/raiders
bantype = "raider"
landmark_id = "voxstart"
welcome_text = "Use :H to talk on your encrypted channel."
- flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
max_antags = 6
max_antags_round = 10
id_type = /obj/item/weapon/card/id/syndicate
@@ -83,8 +83,8 @@ var/datum/antagonist/raider/raiders
/datum/antagonist/raider/create_global_objectives()
- if(global_objectives.len)
- return
+ if(!..())
+ return 0
var/i = 1
var/max_objectives = pick(2,2,2,2,3,3,3,4)
@@ -107,6 +107,7 @@ var/datum/antagonist/raider/raiders
i++
global_objectives |= new /datum/objective/heist/preserve_crew
+ return 1
/datum/antagonist/raider/check_victory()
// Totally overrides the base proc.
@@ -150,7 +151,7 @@ var/datum/antagonist/raider/raiders
else
win_msg += "The Raiders were repelled!"
- world << "[win_type] [win_group] victory!"
+ world << "[win_type] [win_group] victory!"
world << "[win_msg]"
feedback_set_details("round_end_result","heist - [win_type] [win_group]")
diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm
index 2923008a7b..74866d9247 100644
--- a/code/game/antagonist/outsider/wizard.dm
+++ b/code/game/antagonist/outsider/wizard.dm
@@ -10,6 +10,7 @@ var/datum/antagonist/wizard/wizards
welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.
In your pockets you will find a teleport scroll. Use it as needed."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1
+ max_antags_round = 1
/datum/antagonist/wizard/New()
..()
@@ -58,7 +59,8 @@ var/datum/antagonist/wizard/wizards
wizard.objectives |= hijack_objective
return
-/datum/antagonist/wizard/apply(var/datum/mind/wizard)
+/datum/antagonist/wizard/update_antag_mob(var/datum/mind/wizard)
+ ..()
wizard.store_memory("Remember: do not forget to prepare your spells.")
wizard.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]"
wizard.current.name = wizard.current.real_name
diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm
index 55b67cc29a..f6307b8ae8 100644
--- a/code/game/antagonist/station/changeling.dm
+++ b/code/game/antagonist/station/changeling.dm
@@ -13,7 +13,7 @@
/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player)
return "
Changeling ID: [player.changeling.changelingID].
Genomes Absorbed: [player.changeling.absorbedcount]"
-/datum/antagonist/changeling/apply(var/datum/mind/player)
+/datum/antagonist/changeling/update_antag_mob(var/datum/mind/player)
..()
player.current.make_changeling()
diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm
index adaa2b24f5..f3999535af 100644
--- a/code/game/antagonist/station/cultist.dm
+++ b/code/game/antagonist/station/cultist.dm
@@ -98,7 +98,7 @@ var/datum/antagonist/cultist/cult
/datum/antagonist/cultist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
if(!..())
return 0
- player.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it."
+ player.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it."
player.memory = ""
if(show_message)
player.current.visible_message("[player.current] looks like they just reverted to their old faith!")
@@ -111,8 +111,6 @@ var/datum/antagonist/cultist/cult
/datum/antagonist/cultist/can_become_antag(var/datum/mind/player)
if(!..())
return 0
- if(!istype(player.current, /mob/living/carbon/human))
- return 0
for(var/obj/item/weapon/implant/loyalty/L in player.current)
if(L && (L.imp_in == player.current))
return 0
diff --git a/code/game/antagonist/station/revolutionary.dm b/code/game/antagonist/station/revolutionary.dm
index ced1d58b38..59d12b50ad 100644
--- a/code/game/antagonist/station/revolutionary.dm
+++ b/code/game/antagonist/station/revolutionary.dm
@@ -50,13 +50,43 @@ var/datum/antagonist/revolutionary/revs
)
mob.equip_in_one_of_slots(T, slots)
-/datum/antagonist/revolutionary/finalize(var/datum/mind/target)
+/*
+datum/antagonist/revolutionary/finalize(var/datum/mind/target)
if(target)
return ..(target)
current_antagonists |= head_revolutionaries
create_global_objectives()
..()
+/datum/antagonist/revolutionary/get_additional_check_antag_output(var/datum/admins/caller)
+ return ..() //Todo
+
+ Rev extras:
+ dat += "
| Revolutionaries | |
"
+ for(var/datum/mind/N in ticker.mode.head_revolutionaries)
+ var/mob/M = N.current
+ if(!M)
+ dat += "| Head Revolutionary not found! |
"
+ else
+ dat += "| [M.real_name] (Leader)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""] | "
+ dat += "PM |
"
+ for(var/datum/mind/N in ticker.mode.revolutionaries)
+ var/mob/M = N.current
+ if(M)
+ dat += "| [M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""] | "
+ dat += "PM |
"
+ dat += "
| Target(s) | | Location |
"
+ for(var/datum/mind/N in ticker.mode.get_living_heads())
+ var/mob/M = N.current
+ if(M)
+ dat += "| [M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""] | "
+ dat += "PM | "
+ var/turf/mob_loc = get_turf(M)
+ dat += "[mob_loc.loc] |
"
+ else
+ dat += "| Head not found! |
"
+*/
+
/datum/antagonist/revolutionary/create_global_objectives()
if(!..())
return
@@ -166,7 +196,7 @@ var/datum/antagonist/revolutionary/revs
if(choice == "Yes!")
M << "You join the revolution!"
src << "[M] joins the revolution!"
- revs.add_antagonist(M.mind)
+ revs.add_antagonist(M.mind, 0, 0, 1)
else if(choice == "No!")
M << "You reject this traitorous cause!"
src << "\The [M] does not support the revolution!"
diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm
index c8b8b95b2a..a4f14dccf8 100644
--- a/code/game/antagonist/station/traitor.dm
+++ b/code/game/antagonist/station/traitor.dm
@@ -18,7 +18,7 @@ var/datum/antagonist/traitor/traitors
/datum/antagonist/traitor/Topic(href, href_list)
if (..())
return
- if(href_list["spawn_uplink"]) spawn_uplink(href_list["spawn_uplink"])
+ if(href_list["spawn_uplink"]) spawn_uplink(locate(href_list["spawn_uplink"]))
/datum/antagonist/traitor/create_objectives(var/datum/mind/traitor)
if(!..())
@@ -147,19 +147,17 @@ var/datum/antagonist/traitor/traitors
freq += 2
if ((freq % 2) == 0)
freq += 1
- freq = freqlist[rand(1, freqlist.len)]
- var/obj/item/device/uplink/hidden/T = new(R)
- T.uplink_owner = traitor_mob.mind
- target_radio.hidden_uplink = T
- target_radio.traitor_frequency = freq
- traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
- traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [loc]).")
+ freq = freqlist[rand(1, freqlist.len)]
+ var/obj/item/device/uplink/hidden/T = new(R, traitor_mob.mind)
+ target_radio.hidden_uplink = T
+ target_radio.traitor_frequency = freq
+ traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features."
+ traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [loc]).")
else if (istype(R, /obj/item/device/pda))
// generate a passcode if the uplink is hidden in a PDA
var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
- var/obj/item/device/uplink/hidden/T = new(R)
- T.uplink_owner = traitor_mob.mind
+ var/obj/item/device/uplink/hidden/T = new(R, traitor_mob.mind)
R.hidden_uplink = T
var/obj/item/device/pda/P = R
P.lock_code = pda_pass
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index e1d2e0b992..b569f1c077 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -67,9 +67,6 @@
return flags & INSERT_CONTAINER
*/
-/atom/proc/meteorhit(obj/meteor as obj)
- return
-
/atom/proc/allow_drop()
return 1
@@ -223,6 +220,9 @@ its easier to just keep the beam vertical.
/atom/proc/ex_act()
return
+
+/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
+ return -1
/atom/proc/blob_act()
return
@@ -421,7 +421,7 @@ its easier to just keep the beam vertical.
src.color = initial(src.color) //paint
src.germ_level = 0
if(istype(blood_DNA, /list))
- qdel(blood_DNA)
+ del(blood_DNA)
return 1
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index ff93e69298..47923ef89b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -22,7 +22,6 @@
/atom/movable/Del()
if(isnull(gcDestroyed) && loc)
testing("GC: -- [type] was deleted via del() rather than qdel() --")
- CRASH() // Debug until I can get a clean server start.
// else if(isnull(gcDestroyed))
// testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel()
// else
diff --git a/code/game/dna/dna_misc.dm b/code/game/dna/dna_misc.dm
deleted file mode 100644
index 3862bd474f..0000000000
--- a/code/game/dna/dna_misc.dm
+++ /dev/null
@@ -1,562 +0,0 @@
-/////////////////////////// DNA HELPER-PROCS
-/proc/getleftblocks(input,blocknumber,blocksize)
- var/string
-
- if (blocknumber > 1)
- string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
- return string
- else
- return null
-
-/proc/getrightblocks(input,blocknumber,blocksize)
- var/string
- if (blocknumber < (length(input)/blocksize))
- string = copytext(input,blocksize*blocknumber+1,length(input)+1)
- return string
- else
- return null
-
-/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen
- var/string
- var/subpos = 1 // keeps track of the current sub block
- var/blockpos = 1 // keeps track of the current block
-
-
- for(var/i = 1, i <= length(input), i++) // loop through each letter
-
- var/pushstring
-
- if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it
- pushstring = "[copytext(input, i, i+1)]"
- else
- if(ui) //This is for allowing block clicks to be differentiated
- pushstring = "[copytext(input, i, i+1)]"
- else
- pushstring = "[copytext(input, i, i+1)]"
-
- string += pushstring // push the string to the return string
-
- if(subpos >= blocksize) // add a line break for every block
- string += " | "
- subpos = 0
- blockpos++
-
- subpos++
-
- return string
-
-
-/proc/getblock(input,blocknumber,blocksize)
- var/result
- result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1)
- return result
-
-/proc/getblockbuffer(input,blocknumber,blocksize)
- var/result[3]
- var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1)
- for(var/i = 1, i <= 3, i++)
- result[i] = copytext(block, i, i+1)
- return result
-
-/proc/setblock(istring, blocknumber, replacement, blocksize)
- if(!blocknumber)
- return istring
- if(!istring || !replacement || !blocksize) return 0
- var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
- return result
-
-/proc/add_zero2(t, u)
- var/temp1
- while (length(t) < u)
- t = "0[t]"
- temp1 = t
- if (length(t) > u)
- temp1 = copytext(t,2,u+1)
- return temp1
-
-/proc/miniscramble(input,rs,rd)
- var/output
- output = null
- if (input == "C" || input == "D" || input == "E" || input == "F")
- output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3")
- if (input == "8" || input == "9" || input == "A" || input == "B")
- output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3")
- if (input == "4" || input == "5" || input == "6" || input == "7")
- output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3")
- if (input == "0" || input == "1" || input == "2" || input == "3")
- output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F")
- if (!output) output = "5"
- return output
-
-//Instead of picking a value far from the input, this will pick values closer to it.
-//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text
-/proc/miniscrambletarget(input,rs,rd)
- var/output = null
- switch(input)
- if("0")
- output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3")
- if("1")
- output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4")
- if("2")
- output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5")
- if("3")
- output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6")
- if("4")
- output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7")
- if("5")
- output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8")
- if("6")
- output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9")
- if("7")
- output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A")
- if("8")
- output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B")
- if("9")
- output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C")
- if("10")//A
- output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D")
- if("11")//B
- output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E")
- if("12")//C
- output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F")
- if("13")//D
- output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F")
- if("14")//E
- output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F")
- if("15")//F
- output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F")
-
- if(!input || !output) //How did this happen?
- output = "8"
-
- return output
-
-/proc/isblockon(hnumber, bnumber , var/UI = 0)
-
- var/temp2
- temp2 = hex2num(hnumber)
-
- if(UI)
- if(temp2 >= 2050)
- return 1
- else
- return 0
-
- if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK)
- if (temp2 >= 3500 + BLOCKADD)
- return 1
- else
- return 0
- if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK)
- if (temp2 >= 3050 + BLOCKADD)
- return 1
- else
- return 0
-
-
- if (temp2 >= 2050 + BLOCKADD)
- return 1
- else
- return 0
-
-/proc/ismuton(var/block,var/mob/M)
- return isblockon(getblock(M.dna.struc_enzymes, block,3),block)
-
-/proc/randmutb(mob/M as mob)
- if(!M) return
- var/num
- var/newdna
- num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK)
- M.dna.check_integrity()
- newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3)
- M.dna.struc_enzymes = newdna
- return
-
-/proc/randmutg(mob/M as mob)
- if(!M) return
- var/num
- var/newdna
- num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK)
- M.dna.check_integrity()
- newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3)
- M.dna.struc_enzymes = newdna
- return
-
-/proc/scramble(var/type, mob/M as mob, var/p)
- if(!M) return
- M.dna.check_integrity()
- if(type)
- for(var/i = 1, i <= STRUCDNASIZE-1, i++)
- if(prob(p))
- M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3)
- updateappearance(M, M.dna.uni_identity)
-
- else
- for(var/i = 1, i <= STRUCDNASIZE-1, i++)
- if(prob(p))
- M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3)
- domutcheck(M, null)
- return
-
-/proc/randmuti(mob/M as mob)
- if(!M) return
- var/num
- var/newdna
- num = rand(1,UNIDNASIZE)
- M.dna.check_integrity()
- newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3)
- M.dna.uni_identity = newdna
- return
-
-/proc/toggledblock(hnumber) //unused
- var/temp3
- var/chtemp
- temp3 = hex2num(hnumber)
- if (temp3 < 2050)
- chtemp = rand(2050,4095)
- return add_zero2(num2hex(chtemp,1),3)
- else
- chtemp = rand(1,2049)
- return add_zero2(num2hex(chtemp,1),3)
-/////////////////////////// DNA HELPER-PROCS
-
-/////////////////////////// DNA MISC-PROCS
-/proc/updateappearance(mob/M as mob , structure)
- if(istype(M, /mob/living/carbon/human))
- M.dna.check_integrity()
- var/mob/living/carbon/human/H = M
- H.r_hair = hex2num(getblock(structure,1,3))
- H.b_hair = hex2num(getblock(structure,2,3))
- H.g_hair = hex2num(getblock(structure,3,3))
- H.r_facial = hex2num(getblock(structure,4,3))
- H.b_facial = hex2num(getblock(structure,5,3))
- H.g_facial = hex2num(getblock(structure,6,3))
- H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220))
- H.r_eyes = hex2num(getblock(structure,8,3))
- H.g_eyes = hex2num(getblock(structure,9,3))
- H.b_eyes = hex2num(getblock(structure,10,3))
-
- if(H.internal_organs_by_name["eyes"])
- H.update_eyes()
-
- if (isblockon(getblock(structure, 11,3),11 , 1))
- H.gender = FEMALE
- else
- H.gender = MALE
-
- //Hair
- var/hairnum = hex2num(getblock(structure,13,3))
- var/index = round(1 +(hairnum / 4096)*hair_styles_list.len)
- if((0 < index) && (index <= hair_styles_list.len))
- H.h_style = hair_styles_list[index]
-
- //Facial Hair
- var/beardnum = hex2num(getblock(structure,12,3))
- index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len)
- if((0 < index) && (index <= facial_hair_styles_list.len))
- H.f_style = facial_hair_styles_list[index]
-
- H.update_body(0)
- H.update_hair()
-
- return 1
- else
- return 0
-
-/proc/probinj(var/pr, var/inj)
- return prob(pr+inj*pr)
-
-/proc/domutcheck(mob/living/M as mob, connected, inj)
- if (!M) return
-
- M.dna.check_integrity()
-
- M.disabilities = 0
- M.sdisabilities = 0
- var/old_mutations = M.mutations
- M.mutations = list()
-
-// M.see_in_dark = 2
-// M.see_invisible = 0
-
- if(PLANT in old_mutations)
- M.mutations.Add(PLANT)
- if(SKELETON in old_mutations)
- M.mutations.Add(SKELETON)
- if(FAT in old_mutations)
- M.mutations.Add(FAT)
- if(HUSK in old_mutations)
- M.mutations.Add(HUSK)
-
- if(ismuton(NOBREATHBLOCK,M))
- if(probinj(45,inj) || (mNobreath in old_mutations))
- M << "You feel no need to breathe."
- M.mutations.Add(mNobreath)
- if(ismuton(REMOTEVIEWBLOCK,M))
- if(probinj(45,inj) || (mRemote in old_mutations))
- M << "Your mind expands."
- M.mutations.Add(mRemote)
- if(ismuton(REGENERATEBLOCK,M))
- if(probinj(45,inj) || (mRegen in old_mutations))
- M << "You feel strange."
- M.mutations.Add(mRegen)
- if(ismuton(INCREASERUNBLOCK,M))
- if(probinj(45,inj) || (mRun in old_mutations))
- M << "You feel quick."
- M.mutations.Add(mRun)
- if(ismuton(REMOTETALKBLOCK,M))
- if(probinj(45,inj) || (mRemotetalk in old_mutations))
- M << "You expand your mind outwards."
- M.mutations.Add(mRemotetalk)
- if(ismuton(MORPHBLOCK,M))
- if(probinj(45,inj) || (mMorph in old_mutations))
- M.mutations.Add(mMorph)
- M << "Your skin feels strange."
- if(ismuton(BLENDBLOCK,M))
- if(probinj(45,inj) || (mBlend in old_mutations))
- M.mutations.Add(mBlend)
- M << "You feel alone."
- if(ismuton(HALLUCINATIONBLOCK,M))
- if(probinj(45,inj) || (mHallucination in old_mutations))
- M.mutations.Add(mHallucination)
- M << "Your mind says 'Hello'."
- if(ismuton(NOPRINTSBLOCK,M))
- if(probinj(45,inj) || (mFingerprints in old_mutations))
- M.mutations.Add(mFingerprints)
- M << "Your fingers feel numb."
- if(ismuton(SHOCKIMMUNITYBLOCK,M))
- if(probinj(45,inj) || (mShock in old_mutations))
- M.mutations.Add(mShock)
- M << "You feel strange."
- if(ismuton(SMALLSIZEBLOCK,M))
- if(probinj(45,inj) || (mSmallsize in old_mutations))
- M << "Your skin feels rubbery."
- M.mutations.Add(mSmallsize)
-
-
-
- if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK))
- if(probinj(5,inj) || (HULK in old_mutations))
- M << "Your muscles hurt."
- M.mutations.Add(HULK)
- if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK))
- M.disabilities |= EPILEPSY
- M << "You get a headache."
- if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK))
- M << "You feel strange."
- if (prob(95))
- if(prob(50))
- randmutb(M)
- else
- randmuti(M)
- else
- randmutg(M)
- if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK))
- M.disabilities |= COUGHING
- M << "You start coughing."
- if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK))
- M << "You feel lightheaded."
- M.mutations.Add(CLUMSY)
- if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK))
- M.disabilities |= TOURETTES
- M << "You twitch."
- if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK))
- if(probinj(30,inj) || (XRAY in old_mutations))
- M << "The walls suddenly disappear."
-// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
-// M.see_in_dark = 8
-// M.see_invisible = 2
- M.mutations.Add(XRAY)
- if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK))
- M.disabilities |= NERVOUS
- M << "You feel nervous."
- if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK))
- if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations))
- M << "Your body feels warm."
- M.mutations.Add(COLD_RESISTANCE)
- if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK))
- M.sdisabilities |= BLIND
- M << "You can't seem to see anything."
- if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK))
- if(probinj(15,inj) || (TK in old_mutations))
- M << "You feel smarter."
- M.mutations.Add(TK)
- if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK))
- M.sdisabilities |= DEAF
- M.ear_deaf = 1
- M << "It's kinda quiet.."
- if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK))
- M.disabilities |= NEARSIGHTED
- M << "Your eyes feel weird..."
-
- /* If you want the new mutations to work, UNCOMMENT THIS.
- if(istype(M, /mob/living/carbon))
- for (var/datum/mutations/mut in global_mutations)
- mut.check_mutation(M)
- */
-
-//////////////////////////////////////////////////////////// Monkey Block
- if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human))
- // human > monkey
- var/mob/living/carbon/human/H = M
- H.monkeyizing = 1
- var/list/implants = list() //Try to preserve implants.
- for(var/obj/item/weapon/implant/W in H)
- implants += W
- W.loc = null
-
- if(!connected)
- for(var/obj/item/W in (H.contents-implants))
- if (W==H.w_uniform) // will be teared
- continue
- H.drop_from_inventory(W)
- M.monkeyizing = 1
- M.canmove = 0
- M.icon = null
- M.invisibility = 101
- var/atom/movable/overlay/animation = new( M.loc )
- animation.icon_state = "blank"
- animation.icon = 'icons/mob/mob.dmi'
- animation.master = src
- flick("h2monkey", animation)
- sleep(48)
- qdel(animation)
-
-
- var/mob/living/carbon/monkey/O = null
- if(H.species.primitive)
- O = new H.species.primitive(src)
- else
- H.gib() //Trying to change the species of a creature with no primitive var set is messy.
- return
-
- if(M)
- if (M.dna)
- O.dna = M.dna
- M.dna = null
-
- if (M.suiciding)
- O.suiciding = M.suiciding
- M.suiciding = null
-
-
- for(var/datum/disease/D in M.viruses)
- O.viruses += D
- D.affected_mob = O
- M.viruses -= D
-
-
- for(var/obj/T in (M.contents-implants))
- qdel(T)
-
- O.loc = M.loc
-
- if(M.mind)
- M.mind.transfer_to(O) //transfer our mind to the cute little monkey
-
- if (connected) //inside dna thing
- var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
- C.occupant = O
- connected = null
- O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6))
- O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss())
- O.adjustToxLoss(M.getToxLoss() + 20)
- O.adjustOxyLoss(M.getOxyLoss())
- O.stat = M.stat
- O.a_intent = "hurt"
- for (var/obj/item/weapon/implant/I in implants)
- I.loc = O
- I.implanted = O
-// O.update_icon = 1 //queue a full icon update at next life() call
- qdel(M)
- return
-
- if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human))
- // monkey > human,
- var/mob/living/carbon/monkey/Mo = M
- Mo.monkeyizing = 1
- var/list/implants = list() //Still preserving implants
- for(var/obj/item/weapon/implant/W in Mo)
- implants += W
- W.loc = null
- if(!connected)
- for(var/obj/item/W in (Mo.contents-implants))
- Mo.drop_from_inventory(W)
- M.monkeyizing = 1
- M.canmove = 0
- M.icon = null
- M.invisibility = 101
- var/atom/movable/overlay/animation = new( M.loc )
- animation.icon_state = "blank"
- animation.icon = 'icons/mob/mob.dmi'
- animation.master = src
- flick("monkey2h", animation)
- sleep(48)
- qdel(animation)
-
- var/mob/living/carbon/human/O = new( src )
- if(Mo.greaterform)
- O.set_species(Mo.greaterform)
-
- if (isblockon(getblock(M.dna.uni_identity, 11,3),11))
- O.gender = FEMALE
- else
- O.gender = MALE
-
- if (M)
- if (M.dna)
- O.dna = M.dna
- M.dna = null
-
- if (M.suiciding)
- O.suiciding = M.suiciding
- M.suiciding = null
-
- for(var/datum/disease/D in M.viruses)
- O.viruses += D
- D.affected_mob = O
- M.viruses -= D
-
- //for(var/obj/T in M)
- // qdel(T)
-
- O.loc = M.loc
-
- if(M.mind)
- M.mind.transfer_to(O) //transfer our mind to the human
-
- if (connected) //inside dna thing
- var/obj/machinery/dna_scannernew/C = connected
- O.loc = C
- C.occupant = O
- connected = null
-
- var/i
- while (!i)
- var/randomname
- if (O.gender == MALE)
- randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names)))
- else
- randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names)))
- if (findname(randomname))
- continue
- else
- O.real_name = randomname
- i++
- updateappearance(O,O.dna.uni_identity)
- O.take_overall_damage(M.getBruteLoss(), M.getFireLoss())
- O.adjustToxLoss(M.getToxLoss())
- O.adjustOxyLoss(M.getOxyLoss())
- O.stat = M.stat
- for (var/obj/item/weapon/implant/I in implants)
- I.loc = O
- I.implanted = O
-// O.update_icon = 1 //queue a full icon update at next life() call
- qdel(M)
- return
-//////////////////////////////////////////////////////////// Monkey Block
- if(M)
- M.update_icon = 1 //queue a full icon update at next life() call
- return null
-/////////////////////////// DNA MISC-PROCS
diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm
index 7d9da10636..c93a19d567 100644
--- a/code/game/dna/genes/monkey.dm
+++ b/code/game/dna/genes/monkey.dm
@@ -12,7 +12,7 @@
//testing("Cannot monkey-ify [M], type is [M.type].")
return
var/mob/living/carbon/human/H = M
- H.monkeyizing = 1
+ H.transforming = 1
var/list/implants = list() //Try to preserve implants.
for(var/obj/item/weapon/implant/W in H)
implants += W
@@ -23,7 +23,7 @@
if (W==H.w_uniform) // will be teared
continue
H.drop_from_inventory(W)
- M.monkeyizing = 1
+ M.transforming = 1
M.canmove = 0
M.icon = null
M.invisibility = 101
@@ -90,7 +90,7 @@
//testing("Cannot humanize [M], type is [M.type].")
return
var/mob/living/carbon/monkey/Mo = M
- Mo.monkeyizing = 1
+ Mo.transforming = 1
var/list/implants = list() //Still preserving implants
for(var/obj/item/weapon/implant/W in Mo)
implants += W
@@ -98,7 +98,7 @@
if(!connected)
for(var/obj/item/W in (Mo.contents-implants))
Mo.drop_from_inventory(W)
- M.monkeyizing = 1
+ M.transforming = 1
M.canmove = 0
M.icon = null
M.invisibility = 101
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 2961950377..eb15d45f51 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -374,7 +374,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
for (var/obj/item/weapon/implant/I in C) //Still preserving implants
implants += I
- C.monkeyizing = 1
+ C.transforming = 1
C.canmove = 0
C.icon = null
C.overlays.Cut()
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index a1c0acf008..f6c7d46063 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -6,6 +6,5 @@
required_players = 5
required_players_secret = 15
required_enemies = 3
- uplink_welcome = "Nar-Sie Uplink Console:"
end_on_antag_death = 1
antag_tag = MODE_CULTIST
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index d70c181830..3a6c2c1b3c 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -138,7 +138,7 @@
var/mob/living/M = A
if(M.stat != DEAD)
- if(M.monkeyizing)
+ if(M.transforming)
return
if(M.has_brain_worms())
return //Borer stuff - RR
@@ -146,7 +146,7 @@
if(iscultist(M)) return
if(!ishuman(M) && !isrobot(M)) return
- M.monkeyizing = 1
+ M.transforming = 1
M.canmove = 0
M.icon = null
M.overlays.len = 0
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 4900efb291..f644391bf7 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -425,7 +425,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
if(botEmagChance)
for(var/obj/machinery/bot/bot in machines)
if(prob(botEmagChance))
- bot.Emag()
+ bot.emag_act(1)
/*
diff --git a/code/game/gamemodes/events/clang.dm b/code/game/gamemodes/events/clang.dm
index 74fb9ee507..fdc955718b 100644
--- a/code/game/gamemodes/events/clang.dm
+++ b/code/game/gamemodes/events/clang.dm
@@ -34,7 +34,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
else if (istype(clong, /mob))
if(clong.density || prob(10))
- clong.meteorhit(src)
+ clong.ex_act(2)
else
qdel(src)
diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm
index 13cdb511e8..492b932e46 100644
--- a/code/game/gamemodes/events/dust.dm
+++ b/code/game/gamemodes/events/dust.dm
@@ -102,7 +102,7 @@ The "dust" will damage the hull of the station causin minor hull breaches.
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
if(ismob(A))
- A.meteorhit(src)//This should work for now I guess
+ A.ex_act(strength)//This should work for now I guess
else if(!istype(A,/obj/machinery/power/emitter) && !istype(A,/obj/machinery/field_generator)) //Protect the singularity from getting released every round!
A.ex_act(strength) //Changing emitter/field gen ex_act would make it immune to bombs and C4
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index edbaa4544c..8a2f46598b 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -42,17 +42,10 @@ var/global/list/additional_antag_types = list()
var/antag_tag // First (main) antag template to spawn.
var/list/antag_templates // Extra antagonist types to include.
-
+ var/list/latejoin_templates = list()
var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
- var/antag_prob = 0 // Likelihood of a new antagonist spawning.
- var/antag_count = 0 // Current number of antagonists.
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
- var/list/living_antag_templates = list() // Currently selected antag types that do not require a ghosted player.
- var/list/ghost_antag_templates = list() // Inverse of above.
- var/list/antag_candidates = list() // Living antag candidates.
- var/list/ghost_candidates = list() // Observing antag candidates.
-
var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm.
var/explosion_in_progress = 0 // Sit back and relax
var/waittime_l = 600 // Lower bound on time before intercept arrives (in tenths of seconds)
@@ -61,85 +54,6 @@ var/global/list/additional_antag_types = list()
var/event_delay_mod_moderate // Modifies the timing of random events.
var/event_delay_mod_major // As above.
- var/uplink_welcome = "Illegal Uplink Console:"
- var/uplink_uses = 12
-
- var/list/datum/uplink_item/uplink_items = list(
- "Ammunition" = list(
- new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, ".357", "RA"),
- new/datum/uplink_item(/obj/item/ammo_magazine/mc9mm, 2, "9mm", "R9"),
- new/datum/uplink_item(/obj/item/ammo_magazine/chemdart, 2, "Darts", "AD"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/sniperammo, 2, "14.5mm", "SA")
- ),
- "Highly Visible and Dangerous Weapons" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/emps, 3, "5 EMP Grenades", "EM"),
- new/datum/uplink_item(/obj/item/weapon/melee/energy/sword, 4, "Energy Sword", "ES"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/dartgun, 5, "Dart Gun", "DG"),
- new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/g9mm, 5, "Silenced 9mm", "S9"),
- new/datum/uplink_item(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, 6, "Exosuit Rigged Laser", "RL"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/revolver, 6, "Revolver", "RE"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU"),
- new/datum/uplink_item(/obj/item/weapon/gun/projectile/heavysniper, 12, "Anti-materiel Rifle", "AMR")
- ),
- "Stealthy and Inconspicuous Weapons" = list(
- new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"),
- new/datum/uplink_item(/obj/item/weapon/cane/concealed, 2, "Concealed Cane Sword", "CC"),
- new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"),
- new/datum/uplink_item(/obj/item/weapon/pen/reagent/paralysis, 3, "Paralysis Pen", "PP"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/toxin, 4, "Random Toxin - Beaker", "RT")
- ),
- "Stealth and Camouflage Items" = list(
- new/datum/uplink_item(/obj/item/weapon/card/id/syndicate, 2, "Agent ID card", "AC"),
- new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Bug Kit", "BK"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"),
- new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP"),
- new/datum/uplink_item(/obj/item/clothing/mask/gas/voice, 4, "Voice Changer", "VC"),
- new/datum/uplink_item(/obj/item/weapon/disk/file/cameras/syndicate, 6, "Camera Network Access - Floppy", "SF")
- ),
- "Devices and Tools" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/toolbox/syndicate, 1, "Fully Loaded Toolbox", "ST"),
- new/datum/uplink_item(/obj/item/weapon/plastique, 2, "C-4 (Destroys walls)", "C4"),
- new/datum/uplink_item(/obj/item/device/encryptionkey/syndicate, 2, "Encrypted Radio Channel Key", "ER"),
- new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"),
- new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/clerical, 3, "Morphic Clerical Kit", "CK"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/space, 3, "Space Suit", "SS"),
- new/datum/uplink_item(/obj/item/clothing/glasses/thermal/syndi, 3, "Thermal Imaging Glasses", "TM"),
- new/datum/uplink_item(/obj/item/clothing/suit/storage/vest/heavy/merc, 4, "Heavy Armor Vest", "HAV"),
- new/datum/uplink_item(/obj/item/weapon/aiModule/syndicate, 7, "Hacked AI Upload Module", "AI"),
- new/datum/uplink_item(/obj/item/device/powersink, 5, "Powersink (DANGER!)", "PS",),
- new/datum/uplink_item(/obj/item/device/radio/beacon/syndicate, 7, "Singularity Beacon (DANGER!)", "SB"),
- new/datum/uplink_item(/obj/item/weapon/circuitboard/teleporter, 20, "Teleporter Circuit Board", "TP")
- ),
- "Implants" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_freedom, 3, "Freedom Implant", "FI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_compress, 4, "Compressed Matter Implant", "CI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_explosive, 6, "Explosive Implant (DANGER!)", "EI"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_uplink, 10, "Uplink Implant (Contains 5 Telecrystals)", "UI")
- ),
- "Medical" = list(
- new/datum/uplink_item(/obj/item/weapon/storage/box/sinpockets, 1, "Box of Sin-Pockets", "DP"),
- new/datum/uplink_item(/obj/item/weapon/storage/firstaid/surgery, 5, "Surgery kit", "SK"),
- new/datum/uplink_item(/obj/item/weapon/storage/firstaid/combat, 5, "Combat medical kit", "CM")
- ),
- "Hardsuit Modules" = list(
- new/datum/uplink_item(/obj/item/rig_module/vision/thermal, 2, "Thermal Scanner", "RTS"),
- new/datum/uplink_item(/obj/item/rig_module/fabricator/energy_net, 3, "Net Projector", "REN"),
- new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/ewar_voice, 4, "Electrowarfare Suite and Voice Synthesiser", "REV"),
- new/datum/uplink_item(/obj/item/rig_module/maneuvering_jets, 4, "Maneuvering Jets", "RMJ"),
- new/datum/uplink_item(/obj/item/rig_module/mounted/egun, 6, "Mounted Energy Gun", "REG"),
- new/datum/uplink_item(/obj/item/rig_module/power_sink, 6, "Power Sink", "RPS"),
- new/datum/uplink_item(/obj/item/rig_module/mounted, 8, "Mounted Laser Cannon", "RLC")
- ),
- "(Pointless) Badassery" = list(
- new/datum/uplink_item(/obj/item/toy/syndicateballoon, 10, "For showing that You Are The BOSS (Useless Balloon)", "BS"),
- new/datum/uplink_item(/obj/item/toy/nanotrasenballoon, 10, "For showing that you love NT SOO much (Useless Balloon)", "NT")
- )
- )
-
/datum/game_mode/Topic(href, href_list[])
if(..())
return
@@ -272,7 +186,6 @@ var/global/list/additional_antag_types = list()
EMajor.delay_modifier = event_delay_mod_major
///post_setup()
-///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup()
refresh_event_modifiers()
@@ -287,7 +200,9 @@ var/global/list/additional_antag_types = list()
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
- antag.finalize()
+ antag.finalize_spawn()
+ if(antag.is_latejoin_template())
+ latejoin_templates |= antag
if(emergency_shuttle && auto_recall_shuttle)
emergency_shuttle.auto_recall = 1
@@ -336,67 +251,6 @@ var/global/list/additional_antag_types = list()
)
command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time, and post-evacuation recovery efforts will be substantially delayed.","Emergency Transmission")
-///process()
-///Called by the gameticker
-/datum/game_mode/proc/process()
-
- if(emergency_shuttle.departed)
- return
-
- if(!round_autoantag || !antag_templates || !antag_templates.len)
- return
-
- var/player_count = 0
- antag_count = 0
- antag_candidates = list()
-
- for(var/mob/living/player in mob_list)
- if(player.client)
- player_count += 1
- if(player.mind)
- if(player.stat == 2) // observing
- ghost_candidates |= player
- else
- if(player.mind.special_role)
- antag_count += 1
- else
- antag_candidates |= player
-
- antag_prob = min(100,max(0,(player_count - 5 * 10) * 5)) // This is arbitrary, probably needs adjusting.
-
- var/datum/antagonist/spawn_antag
- var/datum/mind/candidate
-
- var/from_ghosts
- if(prob(antag_prob))
- if(ghost_candidates.len && ghost_antag_templates.len && prob(50))
- spawn_antag = pick(ghost_antag_templates)
- candidate = pick(ghost_candidates)
- from_ghosts = 1
- else if(antag_candidates.len && living_antag_templates.len)
- spawn_antag = pick(living_antag_templates)
- candidate = pick(antag_candidates)
- else
- return // Failed :(
- else
- return
-
- if(spawn_antag.can_become_antag(candidate))
- spawn_antag.attempt_late_spawn(candidate, from_ghosts)
-
-/datum/game_mode/proc/latespawn(mob/living/carbon/human/character)
-
- if(emergency_shuttle.departed || !character.mind)
- return
-
- var/datum/antagonist/spawn_antag
- if(prob(antag_prob) && round_autoantag && living_antag_templates.len)
- spawn_antag = pick(living_antag_templates)
- if(spawn_antag && spawn_antag.can_become_antag(character.mind))
- spawn_antag.attempt_late_spawn(character.mind)
-
- return 0
-
/datum/game_mode/proc/check_finished()
if(emergency_shuttle.returned() || station_was_nuked)
return 1
@@ -623,13 +477,10 @@ var/global/list/additional_antag_types = list()
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
- if(antag.flags & ANTAG_OVERRIDE_JOB)
- ghost_antag_templates |= antag
- else if(antag.flags & ANTAG_RANDSPAWN)
- living_antag_templates |= antag
- else
- antag_templates -= antag
- world << "[antag.role_text_plural] are invalid for additional roundtype antags!"
+ if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
+ continue
+ antag_templates -= antag
+ world << "[antag.role_text_plural] are invalid for additional roundtype antags!"
newscaster_announcements = pick(newscaster_standard_feeds)
@@ -685,7 +536,7 @@ proc/display_roundstart_logout_report()
msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n"
continue //Ghosted while alive
- msg += "" // close the from right at the top
+ msg += "" // close the span from right at the top
for(var/mob/M in mob_list)
if(M.client && M.client.holder)
diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm
new file mode 100644
index 0000000000..9af3524144
--- /dev/null
+++ b/code/game/gamemodes/game_mode_latespawn.dm
@@ -0,0 +1,43 @@
+/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
+ var/list/usable_templates = list()
+ for(var/datum/antagonist/A in supplied_templates)
+ if(A.can_late_spawn())
+ usable_templates |= A
+ return usable_templates
+
+///process()
+///Called by the gameticker
+/datum/game_mode/proc/process()
+ try_latespawn()
+
+/datum/game_mode/proc/latespawn(var/mob/living/carbon/human/character)
+ if(!character.mind)
+ return
+ try_latespawn(character.mind)
+ return 0
+
+/datum/game_mode/proc/try_latespawn(var/datum/mind/player, var/latejoin_only)
+
+ if(emergency_shuttle.departed || !round_autoantag)
+ return
+
+ if(!prob(get_antag_prob()))
+ return
+
+ var/list/usable_templates
+ if(latejoin_only && latejoin_templates.len)
+ usable_templates = get_usable_templates(latejoin_templates)
+ else if (antag_templates.len)
+ usable_templates = get_usable_templates(antag_templates)
+ else
+ return
+ if(usable_templates.len)
+ var/datum/antagonist/spawn_antag = pick(usable_templates)
+ spawn_antag.attempt_late_spawn(player)
+
+/datum/game_mode/proc/get_antag_prob()
+ var/player_count = 0
+ for(var/mob/living/M in mob_list)
+ if(M.client)
+ player_count += 1
+ return min(100,max(0,(player_count - 5 * 10) * 5))
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 19378de167..b528016898 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -2,7 +2,6 @@
name = "AI malfunction"
round_description = "The AI is behaving abnormally and must be stopped."
extended_round_description = "The AI will attempt to hack the APCs around the station in order to gain as much control as possible."
- uplink_welcome = "Crazy AI Uplink Console:"
config_tag = "malfunction"
required_players = 2
required_players_secret = 7
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
index 1be9d0330f..f757ed5e9e 100644
--- a/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
@@ -65,7 +65,7 @@
set desc = "Opens help window with overview of available hardware, software and other important information."
var/mob/living/silicon/ai/user = usr
- var/help = file2text("ingame_manuals/malf_ai.html")
+ var/help = file2text('ingame_manuals/malf_ai.html')
if(!help)
help = "Error loading help (file /ingame_manuals/malf_ai.html is probably missing). Please report this to server administration staff."
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index 335360d40d..51cb427c0c 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -7,16 +7,17 @@
config_tag = "meteor"
required_players = 0
votable = 0
- uplink_welcome = "EVIL METEOR Uplink Console:"
deny_respawn = 1
+ var/next_wave = METEOR_DELAY
/datum/game_mode/meteor/post_setup()
defer_powernet_rebuild = 2//Might help with the lag
..()
/datum/game_mode/meteor/process()
- if(world.time >= METEOR_DELAY)
- spawn() spawn_meteors(6)
+ if(world.time >= next_wave)
+ next_wave = world.time + meteor_wave_delay
+ spawn() spawn_meteors(6, meteors_normal)
/datum/game_mode/meteor/declare_completion()
var/text
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 293631f2a8..6f5e6ab732 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -1,167 +1,259 @@
/var/const/meteor_wave_delay = 625 //minimum wait between waves in tenths of seconds
//set to at least 100 unless you want evarr ruining every round
-/var/wavesecret = 0
-/var/const/meteors_in_wave = 50
-/var/const/meteors_in_small_wave = 10
-/proc/meteor_wave(var/number = meteors_in_wave)
- if(!ticker || wavesecret)
- return
+//Meteors probability of spawning during a given wave
+/var/list/meteors_normal = list(/obj/effect/meteor/dust=3, /obj/effect/meteor/medium=8, /obj/effect/meteor/big=3, \
+ /obj/effect/meteor/flaming=1, /obj/effect/meteor/irradiated=3) //for normal meteor event
- wavesecret = 1
- for(var/i = 0 to number)
- spawn(rand(10,100))
- spawn_meteor()
- spawn(meteor_wave_delay)
- wavesecret = 0
+/var/list/meteors_threatening = list(/obj/effect/meteor/medium=4, /obj/effect/meteor/big=8, \
+ /obj/effect/meteor/flaming=3, /obj/effect/meteor/irradiated=3) //for threatening meteor event
-/proc/spawn_meteors(var/number = meteors_in_small_wave)
+/var/list/meteors_catastrophic = list(/obj/effect/meteor/medium=5, /obj/effect/meteor/big=75, \
+ /obj/effect/meteor/flaming=10, /obj/effect/meteor/irradiated=10, /obj/effect/meteor/tunguska = 1) //for catastrophic meteor event
+
+/var/list/meteors_dust = list(/obj/effect/meteor/dust) //for space dust event
+
+
+///////////////////////////////
+//Meteor spawning global procs
+///////////////////////////////
+
+/proc/spawn_meteors(var/number = 10, var/list/meteortypes)
for(var/i = 0; i < number; i++)
- spawn(0)
- spawn_meteor()
+ spawn_meteor(meteortypes)
-/proc/spawn_meteor()
-
- var/startx
- var/starty
- var/endx
- var/endy
+/proc/spawn_meteor(var/list/meteortypes)
var/turf/pickedstart
var/turf/pickedgoal
var/max_i = 10//number of tries to spawn meteor.
-
-
- do
- switch(pick(1,2,3,4))
- if(1) //NORTH
- starty = world.maxy-(TRANSITIONEDGE+1)
- startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
- endy = TRANSITIONEDGE
- endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
- if(2) //EAST
- starty = rand((TRANSITIONEDGE+1),world.maxy-(TRANSITIONEDGE+1))
- startx = world.maxx-(TRANSITIONEDGE+1)
- endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE)
- endx = TRANSITIONEDGE
- if(3) //SOUTH
- starty = (TRANSITIONEDGE+1)
- startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
- endy = world.maxy-TRANSITIONEDGE
- endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
- if(4) //WEST
- starty = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1))
- startx = (TRANSITIONEDGE+1)
- endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE)
- endx = world.maxx-TRANSITIONEDGE
-
- pickedstart = locate(startx, starty, 1)
- pickedgoal = locate(endx, endy, 1)
+ while (!istype(pickedstart, /turf/space))
+ var/startSide = pick(cardinal)
+ pickedstart = spaceDebrisStartLoc(startSide, 1)
+ pickedgoal = spaceDebrisFinishLoc(startSide, 1)
max_i--
- if(max_i<=0) return
-
- while (!istype(pickedstart, /turf/space)) //FUUUCK, should never happen.
-
-
- var/obj/effect/meteor/M
- switch(rand(1, 100))
-
- if(1 to 10)
- M = new /obj/effect/meteor/big( pickedstart )
- if(11 to 75)
- M = new /obj/effect/meteor( pickedstart )
- if(76 to 100)
- M = new /obj/effect/meteor/small( pickedstart )
-
+ if(max_i<=0)
+ return
+ var/Me = pickweight(meteortypes)
+ var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
+ M.z_original = 1
spawn(0)
walk_towards(M, M.dest, 1)
-
return
+/proc/spaceDebrisStartLoc(startSide, Z)
+ var/starty
+ var/startx
+ switch(startSide)
+ if(NORTH)
+ starty = world.maxy-(TRANSITIONEDGE+1)
+ startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
+ if(EAST)
+ starty = rand((TRANSITIONEDGE+1),world.maxy-(TRANSITIONEDGE+1))
+ startx = world.maxx-(TRANSITIONEDGE+1)
+ if(SOUTH)
+ starty = (TRANSITIONEDGE+1)
+ startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
+ if(WEST)
+ starty = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1))
+ startx = (TRANSITIONEDGE+1)
+ var/turf/T = locate(startx, starty, Z)
+ return T
+
+/proc/spaceDebrisFinishLoc(startSide, Z)
+ var/endy
+ var/endx
+ switch(startSide)
+ if(NORTH)
+ endy = TRANSITIONEDGE
+ endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
+ if(EAST)
+ endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE)
+ endx = TRANSITIONEDGE
+ if(SOUTH)
+ endy = world.maxy-TRANSITIONEDGE
+ endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
+ if(WEST)
+ endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE)
+ endx = world.maxx-TRANSITIONEDGE
+ var/turf/T = locate(endx, endy, Z)
+ return T
+
+///////////////////////
+//The meteor effect
+//////////////////////
+
/obj/effect/meteor
- name = "meteor"
+ name = "the concept of meteor"
+ desc = "You should probably run instead of gawking at this."
icon = 'icons/obj/meteor.dmi'
- icon_state = "flaming"
+ icon_state = "small"
density = 1
- anchored = 1.0
- var/hits = 1
- var/detonation_chance = 15
- var/power = 4
- var/power_step = 1
+ anchored = 1
+ var/hits = 4
+ var/hitpwr = 2 //Level of ex_act to be called on hit.
var/dest
pass_flags = PASSTABLE
+ var/heavy = 0
+ var/meteorsound = 'sound/effects/meteorimpact.ogg'
+ var/z_original = 1
-/obj/effect/meteor/small
- name = "small meteor"
- icon_state = "smallf"
- pass_flags = PASSTABLE | PASSGRILLE
- power = 2
+ var/meteordrop = /obj/item/weapon/ore/iron
+ var/dropamt = 2
+
+/obj/effect/meteor/Move()
+ if(z != z_original || loc == dest)
+ qdel(src)
+ return
+
+ . = ..() //process movement...
+
+ if(.)//.. if did move, ram the turf we get in
+ var/turf/T = get_turf(loc)
+ ram_turf(T)
+
+ if(prob(10) && !istype(T, /turf/space))//randomly takes a 'hit' from ramming
+ get_hit()
+
+ return .
/obj/effect/meteor/Destroy()
walk(src,0) //this cancels the walk_towards() proc
..()
+/obj/effect/meteor/New()
+ ..()
+ SpinAnimation()
+
/obj/effect/meteor/Bump(atom/A)
- spawn(0)
+ if(A)
+ ram_turf(get_turf(A))
+ playsound(src.loc, meteorsound, 40, 1)
+ get_hit()
- if (A)
- A.meteorhit(src)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
- if (--src.hits <= 0)
+/obj/effect/meteor/proc/ram_turf(var/turf/T)
+ //first bust whatever is in the turf
+ for(var/atom/A in T)
+ if(A != src)
+ A.ex_act(hitpwr)
- //Prevent meteors from blowing up the singularity's containment.
- //Changing emitter and generator ex_act would result in them being bomb and C4 proof.
- if(!istype(A,/obj/machinery/power/emitter) && \
- !istype(A,/obj/machinery/field_generator) && \
- prob(detonation_chance))
- explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0)
- qdel(src)
- return
+ //then, ram the turf if it still exists
+ if(T)
+ T.ex_act(hitpwr)
-/obj/effect/meteor/ex_act(severity)
-
- if (severity < 4)
+//process getting 'hit' by colliding with a dense object
+//or randomly when ramming turfs
+/obj/effect/meteor/proc/get_hit()
+ hits--
+ if(hits <= 0)
+ make_debris()
+ meteor_effect(heavy)
qdel(src)
+
+/obj/effect/meteor/ex_act()
return
-/obj/effect/meteor/big
- name = "big meteor"
- hits = 5
- power = 1
-
- ex_act(severity)
- return
-
- Bump(atom/A)
- spawn(0)
- //Prevent meteors from blowing up the singularity's containment.
- //Changing emitter and generator ex_act would result in them being bomb and C4 proof
- if(!istype(A,/obj/machinery/power/emitter) && \
- !istype(A,/obj/machinery/field_generator))
- if(--src.hits <= 0)
- qdel(src) //Dont blow up singularity containment if we get stuck there.
-
- if (A)
- for(var/mob/M in player_list)
- var/turf/T = get_turf(M)
- if(!T || T.z != src.z)
- continue
- shake_camera(M, 3, get_dist(M.loc, src.loc) > 20 ? 1 : 3)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
- explosion(src.loc, 0, 1, 2, 3, 0)
-
- if (--src.hits <= 0)
- if(prob(detonation_chance) && !istype(A, /obj/structure/grille))
- explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0)
- qdel(src)
- return
-
-/obj/effect/meteor/attackby(obj/item/weapon/W as obj, mob/user as mob)
+/obj/effect/meteor/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/pickaxe))
qdel(src)
return
..()
-/obj/effect/meteor/touch_map_edge()
- qdel(src)
+/obj/effect/meteor/proc/make_debris()
+ for(var/throws = dropamt, throws > 0, throws--)
+ var/obj/item/O = new meteordrop(get_turf(src))
+ O.throw_at(dest, 5, 10)
+
+/obj/effect/meteor/proc/meteor_effect(var/sound=1)
+ if(sound)
+ for(var/mob/M in player_list)
+ var/turf/T = get_turf(M)
+ if(!T || T.z != src.z)
+ continue
+ var/dist = get_dist(M.loc, src.loc)
+ shake_camera(M, dist > 20 ? 3 : 5, dist > 20 ? 1 : 3)
+ M.playsound_local(src.loc, meteorsound, 50, 1, get_rand_frequency(), 10)
+
+///////////////////////
+//Meteor types
+///////////////////////
+
+//Dust
+/obj/effect/meteor/dust
+ name = "space dust"
+ icon_state = "dust"
+ pass_flags = PASSTABLE | PASSGRILLE
+ hits = 1
+ hitpwr = 3
+ meteorsound = 'sound/weapons/throwtap.ogg'
+ meteordrop = /obj/item/weapon/ore/glass
+
+//Medium-sized
+/obj/effect/meteor/medium
+ name = "meteor"
+ dropamt = 3
+
+/obj/effect/meteor/medium/meteor_effect()
+ ..(heavy)
+ explosion(src.loc, 0, 1, 2, 3, 0)
+
+//Large-sized
+/obj/effect/meteor/big
+ name = "big meteor"
+ icon_state = "large"
+ hits = 6
+ heavy = 1
+ dropamt = 4
+
+/obj/effect/meteor/big/meteor_effect()
+ ..(heavy)
+ explosion(src.loc, 1, 2, 3, 4, 0)
+
+//Flaming meteor
+/obj/effect/meteor/flaming
+ name = "flaming meteor"
+ icon_state = "flaming"
+ hits = 5
+ heavy = 1
+ meteorsound = 'sound/effects/bamf.ogg'
+ meteordrop = /obj/item/weapon/ore/phoron
+
+/obj/effect/meteor/flaming/meteor_effect()
+ ..(heavy)
+ explosion(src.loc, 1, 2, 3, 4, 0, 0, 5)
+
+//Radiation meteor
+/obj/effect/meteor/irradiated
+ name = "glowing meteor"
+ icon_state = "glowing"
+ heavy = 1
+ meteordrop = /obj/item/weapon/ore/uranium
+
+
+/obj/effect/meteor/irradiated/meteor_effect()
+ ..(heavy)
+ explosion(src.loc, 0, 0, 4, 3, 0)
+ new /obj/effect/decal/cleanable/greenglow(get_turf(src))
+ for(var/mob/living/L in view(5, src))
+ L.apply_effect(40, IRRADIATE)
+
+//Station buster Tunguska
+/obj/effect/meteor/tunguska
+ name = "tunguska meteor"
+ icon_state = "flaming"
+ desc = "Your life briefly passes before your eyes the moment you lay them on this monstruosity"
+ hits = 30
+ hitpwr = 1
+ heavy = 1
+ meteorsound = 'sound/effects/bamf.ogg'
+ meteordrop = /obj/item/weapon/ore/phoron
+
+/obj/effect/meteor/tunguska/meteor_effect()
+ ..(heavy)
+ explosion(src.loc, 5, 10, 15, 20, 0)
+
+/obj/effect/meteor/tunguska/Bump()
+ ..()
+ if(prob(20))
+ explosion(src.loc,2,4,6,8)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 5d8ac9d071..37ec7d9a2a 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -14,8 +14,6 @@ var/list/nuke_disks = list()
end_on_antag_death = 1
antag_tag = MODE_MERCENARY
- uplink_welcome = "Corporate Backed Uplink Console:"
- uplink_uses = 40
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 493650359e..88de996e71 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -7,8 +7,6 @@
required_players_secret = 15
required_enemies = 3
auto_recall_shuttle = 1
- uplink_welcome = "AntagCorp Uplink Console:"
- uplink_uses = 10
end_on_antag_death = 1
shuttle_delay = 3
antag_tag = MODE_REVOLUTIONARY
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index b39ce3f147..2b0e776ce1 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -5,7 +5,6 @@
config_tag = "traitor"
required_players = 0
required_enemies = 1
- uplink_welcome = "AntagCorp Portable Teleportation Relay:"
end_on_antag_death = 1
antag_scaling_coeff = 10
- antag_tag = MODE_TRAITOR
\ No newline at end of file
+ antag_tag = MODE_TRAITOR
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 85cbf3a705..0812c51429 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -6,7 +6,5 @@
required_players = 1
required_players_secret = 10
required_enemies = 1
- uplink_welcome = "Wizardly Uplink Console:"
- uplink_uses = 10
end_on_antag_death = 1
antag_tag = MODE_WIZARD
diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm
index d0855e4781..3aca20b760 100644
--- a/code/game/jobs/access_datum.dm
+++ b/code/game/jobs/access_datum.dm
@@ -14,7 +14,7 @@
region = ACCESS_REGION_SECURITY
/var/const/access_brig = 2 // Brig timers and permabrig
-/datum/access/security
+/datum/access/holding
id = access_brig
desc = "Holding Cells"
region = ACCESS_REGION_SECURITY
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index fbf9bf5e7b..95e043db28 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -518,8 +518,8 @@
data["total_danger"] = max(oxygen_danger, data["total_danger"])
current_settings = TLV["carbon dioxide"]
- var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon dioxide"]*partial_pressure, current_settings)
- environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)
+ var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings)
+ environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger)
data["total_danger"] = max(carbon_dioxide_danger, data["total_danger"])
current_settings = TLV["phoron"]
@@ -946,6 +946,7 @@ FIRE ALARM
user.visible_message("\The [user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.")
else if (istype(W, /obj/item/weapon/wirecutters))
user.visible_message("\The [user] has cut the wires inside \the [src]!", "You have cut the wires inside \the [src].")
+ new/obj/item/stack/cable_coil(get_turf(src), 5)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
buildstage = 1
update_icon()
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index c84d030cc4..21550121cd 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -240,11 +240,6 @@ update_flag
healthcheck()
..()
-/obj/machinery/portable_atmospherics/canister/meteorhit(var/obj/O as obj)
- src.health = 0
- healthcheck()
- return
-
/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(!istype(W, /obj/item/weapon/wrench) && !istype(W, /obj/item/weapon/tank) && !istype(W, /obj/item/device/analyzer) && !istype(W, /obj/item/device/pda))
visible_message("\The [user] hits \the [src] with \a [W]!")
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index 58c3fc0e24..f8d611bcbf 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -175,15 +175,15 @@
C.add_fingerprint(user)
cell = C
C.loc = src
- user.visible_message("[user] opens the panel on [src] and inserts [C].", "You open the panel on [src] and insert [C].")
+ user.visible_message("[user] opens the panel on [src] and inserts [C].", "You open the panel on [src] and insert [C].")
return
if(istype(I, /obj/item/weapon/screwdriver))
if(!cell)
- user << "There is no power cell installed."
+ user << "There is no power cell installed."
return
- user.visible_message("[user] opens the panel on [src] and removes [cell].", "You open the panel on [src] and remove [cell].")
+ user.visible_message("[user] opens the panel on [src] and removes [cell].", "You open the panel on [src] and remove [cell].")
cell.add_fingerprint(user)
cell.loc = src.loc
cell = null
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 83112ea778..eca7dbcef9 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -262,7 +262,7 @@
if(!making || !src) return
//Create the desired item.
- var/obj/item/I = new making.path(get_step(loc, get_dir(src,usr)))
+ var/obj/item/I = new making.path(loc)
if(multiplier > 1 && istype(I, /obj/item/stack))
var/obj/item/stack/S = I
S.amount = multiplier
diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm
index ad9a964ca9..88d8f8dd7e 100644
--- a/code/game/machinery/bots/bots.dm
+++ b/code/game/machinery/bots/bots.dm
@@ -32,15 +32,18 @@
if (src.health <= 0)
src.explode()
-/obj/machinery/bot/proc/Emag(mob/user as mob)
- if(locked)
+/obj/machinery/bot/emag_act(var/remaining_charges, var/user)
+ if(locked && !emagged)
locked = 0
emagged = 1
user << "You short out [src]'s maintenance hatch lock."
log_and_message_admins("emagged [src]'s maintenance hatch lock")
- if(!locked && open)
+ return 1
+
+ if(!locked && open && emagged == 1)
emagged = 2
log_and_message_admins("emagged [src]'s inner circuits")
+ return 1
/obj/machinery/bot/examine(mob/user)
..(user)
@@ -65,8 +68,6 @@
user << "Unable to repair with the maintenance panel closed."
else
user << "[src] does not need a repair."
- else if (istype(W, /obj/item/weapon/card/emag) && emagged < 2)
- Emag(user)
else
if(hasvar(W,"force") && hasvar(W,"damtype"))
switch(W.damtype)
@@ -86,10 +87,6 @@
..()
healthcheck()
-/obj/machinery/bot/meteorhit()
- src.explode()
- return
-
/obj/machinery/bot/blob_act()
src.health -= rand(20,40)*fire_dam_coeff
healthcheck()
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 935856269c..36a6e76e55 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -88,12 +88,7 @@
// cell: insert it
// other: chance to knock rider off bot
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user)
- if(istype(I,/obj/item/weapon/card/emag))
- locked = !locked
- user << "You [locked ? "lock" : "unlock"] the mulebot's controls!"
- flick("mulebot-emagged", src)
- playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0)
- else if(istype(I,/obj/item/weapon/cell) && open && !cell)
+ if(istype(I,/obj/item/weapon/cell) && open && !cell)
var/obj/item/weapon/cell/C = I
user.drop_item()
C.loc = src
@@ -106,11 +101,11 @@
open = !open
if(open)
- src.visible_message("[user] opens the maintenance hatch of [src]", "You open [src]'s maintenance hatch.")
+ src.visible_message("[user] opens the maintenance hatch of [src]", "You open [src]'s maintenance hatch.")
on = 0
icon_state="mulebot-hatch"
else
- src.visible_message("[user] closes the maintenance hatch of [src]", "You close [src]'s maintenance hatch.")
+ src.visible_message("[user] closes the maintenance hatch of [src]", "You close [src]'s maintenance hatch.")
icon_state = "mulebot0"
updateDialog()
@@ -133,6 +128,12 @@
..()
return
+/obj/machinery/bot/mulebot/emag_act(var/remaining_charges, var/user)
+ locked = !locked
+ user << "You [locked ? "lock" : "unlock"] the mulebot's controls!"
+ flick("mulebot-emagged", src)
+ playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 0)
+ return 1
/obj/machinery/bot/mulebot/ex_act(var/severity)
unload(0)
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index d8c776bc36..8f048db043 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -130,11 +130,11 @@
/mob/living/silicon/ai/proc/ai_camera_track(var/target_name in trackable_mobs())
set category = "AI Commands"
- set name = "Track With Camera"
+ set name = "Follow With Camera"
set desc = "Select who you would like to track."
if(src.stat == 2)
- src << "You can't track with camera because you are dead!"
+ src << "You can't follow [target_name] with cameras because you are dead!"
return
if(!target_name)
src.cameraFollow = null
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index b4e75b046f..af33673a1f 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -216,13 +216,6 @@
else
locked = 0
user << "System unlocked."
- else if(istype(W, /obj/item/weapon/card/emag))
- if(isnull(occupant))
- return
- user << "You force an emergency ejection."
- locked = 0
- go_out()
- return
else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
user << "\The [src] processes \the [W]."
biomass += 50
@@ -252,6 +245,14 @@
else
..()
+/obj/machinery/clonepod/emag_act(var/remaining_charges, var/mob/user)
+ if(isnull(occupant))
+ return
+ user << "You force an emergency ejection."
+ locked = 0
+ go_out()
+ return 1
+
//Put messages in the connected computer's temp var for display.
/obj/machinery/clonepod/proc/connected_message(var/message)
if((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning)))
@@ -306,7 +307,7 @@
occupant.client.perspective = MOB_PERSPECTIVE
occupant.loc = loc
eject_wait = 0 //If it's still set somehow.
- domutcheck(occupant) //Waiting until they're out before possible monkeyizing.
+ domutcheck(occupant) //Waiting until they're out before possible transforming.
occupant = null
biomass -= CLONE_BIOMASS
diff --git a/code/game/machinery/computer/RCON_Console.dm b/code/game/machinery/computer/RCON_Console.dm
index cf275eb5ce..17d0552779 100644
--- a/code/game/machinery/computer/RCON_Console.dm
+++ b/code/game/machinery/computer/RCON_Console.dm
@@ -13,7 +13,7 @@
circuit = /obj/item/weapon/circuitboard/rcon_console
req_one_access = list(access_engine)
var/current_tag = null
- var/obj/nano_module/rcon/rcon
+ var/datum/nano_module/rcon/rcon
/obj/machinery/computer/rcon/New()
..()
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index d8d2a3bb0e..f579873701 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -221,8 +221,8 @@
return
-/obj/machinery/computer/arcade/attackby(I as obj, user as mob)
- if(istype(I, /obj/item/weapon/card/emag) && !emagged)
+/obj/machinery/computer/arcade/emag_act(var/charges, var/mob/user)
+ if(!emagged)
temp = "If you die in the game, you die for real!"
player_hp = 30
player_mp = 10
@@ -230,17 +230,13 @@
enemy_mp = 20
gameover = 0
blocked = 0
-
emagged = 1
enemy_name = "Cuban Pete"
name = "Outbomb Cuban Pete"
-
src.updateUsrDialog()
- else
- ..()
-
+ return 1
/obj/machinery/computer/arcade/emp_act(severity)
if(stat & (NOPOWER|BROKEN))
diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm
index 07b075a5f1..c11108b490 100644
--- a/code/game/machinery/computer/atmos_control.dm
+++ b/code/game/machinery/computer/atmos_control.dm
@@ -12,7 +12,7 @@
circuit = "/obj/item/weapon/circuitboard/atmoscontrol"
req_access = list(access_ce)
var/list/monitored_alarm_ids = null
- var/obj/nano_module/atmos_control/atmos_control
+ var/datum/nano_module/atmos_control/atmos_control
/obj/machinery/computer/atmoscontrol/New()
..()
@@ -31,14 +31,13 @@
return 1
ui_interact(user)
-/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob)
- if(istype(I, /obj/item/weapon/card/emag) && !emagged)
- user.visible_message("\The [user] swipes \a [I] through \the [src], causing the screen to flash!",\
- "You swipe your [I] through \the [src], the screen flashing as you gain full control.",\
- "You hear the swipe of a card through a reader, and an electronic warble.")
+/obj/machinery/computer/atmoscontrol/emag_act(var/remaining_carges, var/mob/user)
+ if(!emagged)
+ user.visible_message("\The [user] does something \the [src], causing the screen to flash!",\
+ "You cause the screen to flash as you gain full control.",\
+ "You hear an electronic warble.")
atmos_control.emagged = 1
- return
- return ..()
+ return 1
/obj/machinery/computer/atmoscontrol/ui_interact(var/mob/user)
if(!atmos_control)
diff --git a/code/game/machinery/computer/camera_circuit.dm b/code/game/machinery/computer/camera_circuit.dm
index 25baf81486..4680bb57d1 100644
--- a/code/game/machinery/computer/camera_circuit.dm
+++ b/code/game/machinery/computer/camera_circuit.dm
@@ -7,7 +7,7 @@
var/authorised = 0
var/possibleNets[0]
var/network = ""
- build_path = 0
+ build_path = null
//when adding a new camera network, you should only need to update these two procs
New()
@@ -19,36 +19,24 @@
possibleNets["Medbay"] = access_cmo
proc/updateBuildPath()
- build_path = ""
+ build_path = null
if(authorised && secured)
switch(network)
if("SS13")
- build_path = "/obj/machinery/computer/security"
+ build_path = /obj/machinery/computer/security
if("Engineering")
- build_path = "/obj/machinery/computer/security/engineering"
+ build_path = /obj/machinery/computer/security/engineering
if("Mining")
- build_path = "/obj/machinery/computer/security/mining"
+ build_path = /obj/machinery/computer/security/mining
if("Research")
- build_path = "/obj/machinery/computer/security/research"
+ build_path = /obj/machinery/computer/security/research
if("Medbay")
- build_path = "/obj/machinery/computer/security/medbay"
+ build_path = /obj/machinery/computer/security/medbay
if("Cargo")
- build_path = "/obj/machinery/computer/security/cargo"
+ build_path = /obj/machinery/computer/security/cargo
attackby(var/obj/item/I, var/mob/user)//if(health > 50)
..()
- if(istype(I,/obj/item/weapon/card/emag))
- if(network)
- var/obj/item/weapon/card/emag/E = I
- if(E.uses)
- E.uses--
- else
- return
- authorised = 1
- user << "You authorised the circuit network!"
- updateDialog()
- else
- user << "You must select a camera network circuit!"
else if(istype(I,/obj/item/weapon/screwdriver))
secured = !secured
user.visible_message("The [src] can [secured ? "no longer" : "now"] be modified.")
@@ -107,17 +95,7 @@
else if (possibleNets[network] in I.access)
authorised = 1
if(istype(I,/obj/item/weapon/card/emag))
- if(network)
- var/obj/item/weapon/card/emag/E = I
- if(E.uses)
- E.uses--
- else
- return
- authorised = 1
- usr << "You authorised the circuit network!"
- updateDialog()
- else
- usr << "You must select a camera network circuit!"
+ I.resolve_attackby(src, usr)
else if( href_list["removeauth"] )
authorised = 0
updateDialog()
@@ -125,3 +103,12 @@
updateDialog()
if(istype(src.loc,/mob))
attack_self(src.loc)
+
+/obj/item/weapon/circuitboard/camera/emag_act(var/remaining_charges, var/mob/user)
+ if(network)
+ authorised = 1
+ user << "You authorised the circuit network!"
+ updateDialog()
+ return 1
+ else
+ user << "You must select a camera network circuit!"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index b940907779..c247846a2d 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -268,11 +268,11 @@
src.updateUsrDialog()
-/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob)
- if(istype(I,/obj/item/weapon/card/emag/))
+/obj/machinery/computer/communications/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
src.emagged = 1
user << "You scramble the communication routing circuits!"
- ..()
+ return 1
/obj/machinery/computer/communications/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index b32f9e9daa..74edf74ea9 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -20,16 +20,6 @@
return 0
return 1
-/obj/machinery/computer/meteorhit(var/obj/O as obj)
- for(var/x in verbs)
- verbs -= x
- set_broken()
- var/datum/effect/effect/system/smoke_spread/smoke = PoolOrNew(/datum/effect/effect/system/smoke_spread)
- smoke.set_up(5, 0, src)
- smoke.start()
- return
-
-
/obj/machinery/computer/emp_act(severity)
if(prob(20/severity)) set_broken()
..()
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index 6928d104ca..6df502891f 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -7,7 +7,7 @@
idle_power_usage = 250
active_power_usage = 500
circuit = "/obj/item/weapon/circuitboard/crew"
- var/obj/nano_module/crew_monitor/crew_monitor
+ var/datum/nano_module/crew_monitor/crew_monitor
/obj/machinery/computer/crew/New()
crew_monitor = new(src)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index f775c5f950..779e2a1460 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -37,24 +37,6 @@
return
if(!istype(user))
return
- if(istype(O,/obj/item/weapon/card/emag/))
- // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
- // It'll take more time if there's more characters in the password..
- if(!emag)
- if(!isnull(src.linkedServer))
- icon_state = hack_icon // An error screen I made in the computers.dmi
- emag = 1
- screen = 2
- spark_system.set_up(5, 0, src)
- src.spark_system.start()
- var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
- MK.loc = src.loc
- // Will help make emagging the console not so easy to get away with.
- MK.info += "
£%@%(*$%&(£&?*(%&£/{}"
- spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
- message = rebootmsg
- else
- user << "A no server error appears on the screen."
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
user << "It is too hot to mess with!"
@@ -63,6 +45,26 @@
..()
return
+/obj/machinery/computer/message_monitor/emag_act(var/remaining_charges, var/mob/user)
+ // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
+ // It'll take more time if there's more characters in the password..
+ if(!emag && operable())
+ if(!isnull(src.linkedServer))
+ icon_state = hack_icon // An error screen I made in the computers.dmi
+ emag = 1
+ screen = 2
+ spark_system.set_up(5, 0, src)
+ src.spark_system.start()
+ var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
+ MK.loc = src.loc
+ // Will help make emagging the console not so easy to get away with.
+ MK.info += "
£%@%(*$%&(£&?*(%&£/{}"
+ spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
+ message = rebootmsg
+ return 1
+ else
+ user << "A no server error appears on the screen."
+
/obj/machinery/computer/message_monitor/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 3dd181c917..af0105ca5b 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -45,7 +45,7 @@
if(!T.implanted) continue
var/loc_display = "Unknown"
var/mob/living/carbon/M = T.imp_in
- if(M.z in config.station_levels && !istype(M.loc, /turf/space))
+ if((M.z in config.station_levels) && !istype(M.loc, /turf/space))
var/turf/mob_loc = get_turf(M)
loc_display = mob_loc.loc
if(T.malfunction)
diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm
index 8ff3a8e103..f33e3af833 100644
--- a/code/game/machinery/computer/prisonshuttle.dm
+++ b/code/game/machinery/computer/prisonshuttle.dm
@@ -47,9 +47,6 @@ var/prison_shuttle_timeleft = 0
A.icon_state = "4"
qdel(src)
- else if(istype(I,/obj/item/weapon/card/emag) && (!hacked))
- hacked = 1
- user << "You disable the lock."
else
return src.attack_hand(user)
@@ -235,3 +232,9 @@ var/prison_shuttle_timeleft = 0
start_location.move_contents_to(end_location)
return
+
+/obj/machinery/computer/prison_shuttle/emag_act(var/charges, var/mob/user)
+ if(!hacked)
+ hacked = 1
+ user << "You disable the lock."
+ return 1
diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm
index ea8cf4d726..e48a71b89f 100644
--- a/code/game/machinery/computer/specops_shuttle.dm
+++ b/code/game/machinery/computer/specops_shuttle.dm
@@ -249,11 +249,8 @@ var/specops_shuttle_timeleft = 0
/obj/machinery/computer/specops_shuttle/attack_ai(var/mob/user as mob)
return attack_hand(user)
-/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob)
- if(istype(I,/obj/item/weapon/card/emag))
- user << "The electronic systems in this console are far too advanced for your primitive hacking peripherals."
- else
- return attack_hand(user)
+/obj/machinery/computer/specops_shuttle/emag_act(var/remaining_charges, var/mob/user)
+ user << "The electronic systems in this console are far too advanced for your primitive hacking peripherals."
/obj/machinery/computer/specops_shuttle/attack_hand(var/mob/user as mob)
if(!allowed(user))
@@ -291,8 +288,8 @@ var/specops_shuttle_timeleft = 0
usr << "Central Command will not allow the Special Operations shuttle to return yet."
if(world.timeofday <= specops_shuttle_timereset)
if (((world.timeofday - specops_shuttle_timereset)/10) > 60)
- usr << "[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!"
- usr << "[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!"
+ usr << "[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!"
+ usr << "[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!"
return
usr << "The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds."
diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm
index 696273d2ab..ea0952e9f7 100644
--- a/code/game/machinery/computer/station_alert.dm
+++ b/code/game/machinery/computer/station_alert.dm
@@ -5,15 +5,15 @@
icon_state = "alert:0"
light_color = "#e6ffff"
circuit = /obj/item/weapon/circuitboard/stationalert_engineering
- var/obj/nano_module/alarm_monitor/alarm_monitor
- var/monitor_type = /obj/nano_module/alarm_monitor/engineering
+ var/datum/nano_module/alarm_monitor/alarm_monitor
+ var/monitor_type = /datum/nano_module/alarm_monitor/engineering
/obj/machinery/computer/station_alert/security
- monitor_type = /obj/nano_module/alarm_monitor/security
+ monitor_type = /datum/nano_module/alarm_monitor/security
circuit = /obj/item/weapon/circuitboard/stationalert_security
/obj/machinery/computer/station_alert/all
- monitor_type = /obj/nano_module/alarm_monitor/all
+ monitor_type = /datum/nano_module/alarm_monitor/all
circuit = /obj/item/weapon/circuitboard/stationalert_all
/obj/machinery/computer/station_alert/New()
diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm
index 9d05249d95..07b4e007a3 100644
--- a/code/game/machinery/computer/supply.dm
+++ b/code/game/machinery/computer/supply.dm
@@ -207,14 +207,11 @@
onclose(user, "computer")
return
-/obj/machinery/computer/supplycomp/attackby(I as obj, user as mob)
- if(istype(I,/obj/item/weapon/card/emag) && !hacked)
+/obj/machinery/computer/supplycomp/emag_act(var/remaining_charges, var/mob/user)
+ if(!hacked)
user << "Special supplies unlocked."
hacked = 1
- return
- else
- ..()
- return
+ return 1
/obj/machinery/computer/supplycomp/Topic(href, href_list)
if(!supply_controller)
diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm
index 3357072c28..333584a921 100644
--- a/code/game/machinery/computer/syndicate_specops_shuttle.dm
+++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm
@@ -185,11 +185,8 @@ var/syndicate_elite_shuttle_timeleft = 0
/obj/machinery/computer/syndicate_elite_shuttle/attack_ai(var/mob/user as mob)
return attack_hand(user)
-/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob)
- if(istype(I,/obj/item/weapon/card/emag))
- user << "The electronic systems in this console are far too advanced for your primitive hacking peripherals."
- else
- return attack_hand(user)
+/obj/machinery/computer/syndicate_elite_shuttle/emag_act(var/remaining_charges, var/mob/user)
+ user << "The electronic systems in this console are far too advanced for your primitive hacking peripherals."
/obj/machinery/computer/syndicate_elite_shuttle/attack_hand(var/mob/user as mob)
if(!allowed(user))
diff --git a/code/game/machinery/computer3/computer.dm b/code/game/machinery/computer3/computer.dm
index 902d8ef1a4..6b6a2f8491 100644
--- a/code/game/machinery/computer3/computer.dm
+++ b/code/game/machinery/computer3/computer.dm
@@ -75,15 +75,15 @@
set name = "Reset Computer"
set category = "Object"
set src in view(1)
-
+
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
usr << "You can't do that."
return
-
+
if(!Adjacent(usr))
usr << "You can't reach it."
return
-
+
Reset()
New(var/L, var/built = 0)
@@ -199,14 +199,6 @@
// todo does this do enough
-
- meteorhit(var/obj/O as obj)
- for(var/x in verbs)
- verbs -= x
- set_broken()
- return
-
-
emp_act(severity)
if(prob(20/severity)) set_broken()
..()
diff --git a/code/game/machinery/computer3/laptop.dm b/code/game/machinery/computer3/laptop.dm
index ccd63aef36..2e73e77115 100644
--- a/code/game/machinery/computer3/laptop.dm
+++ b/code/game/machinery/computer3/laptop.dm
@@ -124,7 +124,7 @@
return
if(!Adjacent(usr))
- usr << "You can't reach it."
+ usr << "You can't reach it."
return
close_laptop(usr)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index e00e1d0028..50de43e6b7 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -394,9 +394,9 @@
occupant.ckey = null
//Make an announcement and log the person entering storage.
- control_computer.frozen_crew += "[occupant.real_name], [occupant.mind.assigned_role] - [worldtime2text()]"
+ control_computer.frozen_crew += "[occupant.real_name], [occupant.mind.role_alt_title] - [worldtime2text()]"
- announce.autosay("[occupant.real_name], [occupant.mind.assigned_role] [on_store_message]", "[on_store_name]")
+ announce.autosay("[occupant.real_name], [occupant.mind.role_alt_title], [on_store_message]", "[on_store_name]")
visible_message("\The [initial(name)] hums and hisses as it moves [occupant.real_name] into storage.", 3)
// Delete the mob.
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index e3c8607b88..167190c336 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -127,11 +127,6 @@ for reference:
dismantle()
return
-/obj/structure/barricade/meteorhit()
- visible_message("\The [src] is smashed apart!")
- dismantle()
- return
-
/obj/structure/barricade/blob_act()
src.health -= 25
if (src.health <= 0)
@@ -191,25 +186,6 @@ for reference:
visible_message("BZZzZZzZZzZT")
return
return
- else if (istype(W, /obj/item/weapon/card/emag))
- if (src.emagged == 0)
- src.emagged = 1
- src.req_access.Cut()
- src.req_one_access.Cut()
- user << "You break the ID authentication lock on \the [src]."
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(2, 1, src)
- s.start()
- visible_message("BZZzZZzZZzZT")
- return
- else if (src.emagged == 1)
- src.emagged = 2
- user << "You short out the anchoring mechanism on \the [src]."
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(2, 1, src)
- s.start()
- visible_message("BZZzZZzZZzZT")
- return
else if (istype(W, /obj/item/weapon/wrench))
if (src.health < src.maxhealth)
src.health = src.maxhealth
@@ -252,10 +228,6 @@ for reference:
anchored = !anchored
icon_state = "barrier[src.locked]"
- meteorhit()
- src.explode()
- return
-
blob_act()
src.health -= 25
if (src.health <= 0)
@@ -285,3 +257,24 @@ for reference:
explosion(src.loc,-1,-1,0)
if(src)
qdel(src)
+
+
+/obj/machinery/deployable/barrier/emag_act(var/remaining_charges, var/mob/user)
+ if (src.emagged == 0)
+ src.emagged = 1
+ src.req_access.Cut()
+ src.req_one_access.Cut()
+ user << "You break the ID authentication lock on \the [src]."
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, src)
+ s.start()
+ visible_message("BZZzZZzZZzZT")
+ return 1
+ else if (src.emagged == 1)
+ src.emagged = 2
+ user << "You short out the anchoring mechanism on \the [src]."
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, src)
+ s.start()
+ visible_message("BZZzZZzZZzZT")
+ return 1
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index e010264d4a..4fc7562b3a 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -40,11 +40,14 @@
*/
if(istype(W, /obj/item/device/detective_scanner))
return
- if(istype(W, /obj/item/weapon/card/emag))
+ return src.attack_hand(user)
+
+/obj/machinery/button/remote/emag_act(var/remaining_charges, var/mob/user)
+ if(req_access.len || req_one_access.len)
req_access = list()
req_one_access = list()
playsound(src.loc, "sparks", 100, 1)
- return src.attack_hand(user)
+ return 1
/obj/machinery/button/remote/attack_hand(mob/user as mob)
if(..())
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index 2c5c00caaa..a2bfb1b6c2 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -171,6 +171,11 @@ obj/machinery/door/blast/regular
icon_state = "pdoor1"
maxhealth = 600
+obj/machinery/door/blast/regular/open
+ icon_state = "pdoor0"
+ density = 0
+ opacity = 0
+
// SUBTYPE: Shutters
// Nicer looking, and also weaker, shutters. Found in kitchen and similar areas.
/obj/machinery/door/blast/shutters
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 69dc698795..32b7a5b46b 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -146,10 +146,6 @@
else do_animate("deny")
return
-/obj/machinery/door/meteorhit(obj/M as obj)
- src.open()
- return
-
/obj/machinery/door/bullet_act(var/obj/item/projectile/Proj)
..()
@@ -276,13 +272,6 @@
if(src.operating) return
- if(src.density && (operable() && istype(I, /obj/item/weapon/card/emag)))
- do_animate("spark")
- sleep(6)
- open()
- operating = -1
- return 1
-
if(src.allowed(user) && operable())
if(src.density)
open()
@@ -294,6 +283,14 @@
do_animate("deny")
return
+/obj/machinery/door/emag_act(var/remaining_charges)
+ if(density && operable())
+ do_animate("spark")
+ sleep(6)
+ open()
+ operating = -1
+ return 1
+
/obj/machinery/door/proc/take_damage(var/damage)
var/initialhealth = src.health
src.health = max(0, src.health - damage)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index b130d1e63d..15b408a2dc 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -102,10 +102,7 @@
continue
var/celsius = convert_k2c(tile_info[index][1])
var/pressure = tile_info[index][2]
- if(dir_alerts[index] & (FIREDOOR_ALERT_HOT|FIREDOOR_ALERT_COLD))
- o += ""
- else
- o += ""
+ o += ""
o += "[celsius]°C "
o += ""
o += "[pressure]kPa"
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index dce2ab37bd..c87ab1ad35 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -1,26 +1,25 @@
-/obj/machinery/door/unpowered
- autoclose = 0
- var/locked = 0
-
-
- Bumped(atom/AM)
- if(src.locked)
- return
- ..()
- return
-
-
- attackby(obj/item/I as obj, mob/user as mob)
- if(istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)) return
- if(src.locked) return
- ..()
- return
-
-
-
-/obj/machinery/door/unpowered/shuttle
- icon = 'icons/turf/shuttle.dmi'
- name = "door"
- icon_state = "door1"
- opacity = 1
- density = 1
\ No newline at end of file
+/obj/machinery/door/unpowered
+ autoclose = 0
+ var/locked = 0
+
+/obj/machinery/door/unpowered/Bumped(atom/AM)
+ if(src.locked)
+ return
+ ..()
+ return
+
+/obj/machinery/door/unpowered/attackby(obj/item/I as obj, mob/user as mob)
+ if(istype(I, /obj/item/weapon/melee/energy/blade)) return
+ if(src.locked) return
+ ..()
+ return
+
+/obj/machinery/door/unpowered/emag_act()
+ return -1
+
+/obj/machinery/door/unpowered/shuttle
+ icon = 'icons/turf/shuttle.dmi'
+ name = "door"
+ icon_state = "door1"
+ opacity = 1
+ density = 1
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index f846af3727..dc3edc9328 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -163,6 +163,14 @@
return
return src.attackby(user, user)
+/obj/machinery/door/window/emag_act(var/remaining_charges, var/mob/user)
+ if (density && operable())
+ operating = -1
+ flick("[src.base_state]spark", src)
+ sleep(6)
+ open()
+ return 1
+
/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/user as mob)
//If it's in the process of opening/closing, ignore the click
@@ -170,18 +178,14 @@
return
//Emags and ninja swords? You may pass.
- if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
- src.operating = -1
- if(istype(I, /obj/item/weapon/melee/energy/blade))
+ if (istype(I, /obj/item/weapon/melee/energy/blade))
+ if(emag_act(10, user))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
playsound(src.loc, "sparks", 50, 1)
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
visible_message("The glass door was sliced open by [user]!")
- flick("[src.base_state]spark", src)
- sleep(6)
- open()
return 1
//If it's emagged, crowbar can pry electronics out.
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index ec9f4e7acc..6661468f59 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -37,7 +37,7 @@ var/list/doppler_arrays = list()
var/message = "Explosive disturbance detected - Epicenter at: grid ([x0],[y0]). Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range]. Temporal displacement of tachyons: [took]seconds."
for(var/mob/O in hearers(src, null))
- O.show_message("[src] states coldly, \"[message]\"",2)
+ O.show_message("[src] states coldly, \"[message]\"",2)
/obj/machinery/doppler_array/power_change()
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 8d883a8ddf..3a4d51715b 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -199,10 +199,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
qdel(src)
return
-/obj/machinery/hologram/meteorhit()
- qdel(src)
- return
-
/obj/machinery/hologram/holopad/Destroy()
for (var/mob/living/silicon/ai/master in masters)
clear_holo(master)
diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm
index e51025aee2..6319871022 100644
--- a/code/game/machinery/holosign.dm
+++ b/code/game/machinery/holosign.dm
@@ -8,6 +8,7 @@
use_power = 1
idle_power_usage = 2
active_power_usage = 4
+ anchored = 1
var/lit = 0
var/id = null
var/on_icon = "sign_on"
diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm
index 90305a7a78..65b1f2ca6f 100644
--- a/code/game/machinery/jukebox.dm
+++ b/code/game/machinery/jukebox.dm
@@ -174,17 +174,16 @@ datum/track/New(var/title_name, var/audio)
power_change()
update_icon()
return
- if(istype(W, /obj/item/weapon/card/emag))
- if(!emagged)
- emagged = 1
- StopPlaying()
- visible_message("\the [src] makes a fizzling sound.")
- log_and_message_admins("emagged \the [src]")
- update_icon()
- return
-
return ..()
+/obj/machinery/media/jukebox/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ emagged = 1
+ StopPlaying()
+ visible_message("\The [src] makes a fizzling sound.")
+ update_icon()
+ return 1
+
/obj/machinery/media/jukebox/proc/StopPlaying()
var/area/main_area = get_area(src)
// Always kill the current sound
diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm
index 13d55e725b..3d18d80a1e 100644
--- a/code/game/machinery/kitchen/gibber.dm
+++ b/code/game/machinery/kitchen/gibber.dm
@@ -84,16 +84,12 @@
..()
usr << "The safety guard is [emagged ? "disabled" : "enabled"]."
+/obj/machinery/gibber/emag_act(var/remaining_charges, var/mob/user)
+ emagged = !emagged
+ user << "You [emagged ? "disable" : "enable"] the gibber safety guard."
+ return 1
+
/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user)
-
- if(istype(W,/obj/item/weapon/card))
- if(!allowed(user) && !istype(W,/obj/item/weapon/card/emag))
- user << "Access denied."
- return
- emagged = !emagged
- user << "You [emagged ? "disable" : "enable"] the gibber safety guard."
- return
-
var/obj/item/weapon/grab/G = W
if(!istype(G))
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index 3125b35df6..bc52c276c3 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -136,6 +136,7 @@
/obj/machinery/smartfridge/drying_rack/proc/dry()
for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents)
+ if(S.dry) continue
if(S.dried_type == S.type)
S.dry = 1
item_quants[S.name]--
@@ -235,14 +236,12 @@
user << "\The [src] smartly refuses [O]."
return 1
-/obj/machinery/smartfridge/secure/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if(istype(O, /obj/item/weapon/card/emag))
+/obj/machinery/smartfridge/secure/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
emagged = 1
locked = -1
user << "You short out the product lock on [src]."
- return
-
- ..()
+ return 1
/obj/machinery/smartfridge/attack_ai(mob/user as mob)
attack_hand(user)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 0570211526..55cf5cdc15 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -123,6 +123,15 @@ Class Procs:
/obj/machinery/Destroy()
machines -= src
+ if(component_parts)
+ for(var/atom/A in component_parts)
+ if(A.loc == src) // If the components are inside the machine, delete them.
+ qdel(A)
+ else // Otherwise we assume they were dropped to the ground during deconstruction, and were not removed from the component_parts list by deconstruction code.
+ component_parts -= A
+ if(contents) // The same for contents.
+ for(var/atom/A in contents)
+ qdel(A)
..()
/obj/machinery/process()//If you dont use process or power why are you here
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 4ea2f416f7..9fa78ee968 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -276,18 +276,6 @@
user << "You remove the turret but did not manage to salvage anything."
qdel(src) // qdel
- if(istype(I, /obj/item/weapon/card/emag) && !emagged)
- //Emagging the turret makes it go bonkers and stun everyone. It also makes
- //the turret shoot much, much faster.
- user << "You short out [src]'s threat assessment circuits."
- visible_message("[src] hums oddly...")
- emagged = 1
- iconholder = 1
- controllock = 1
- enabled = 0 //turns off the turret temporarily
- sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
- enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
-
else if((istype(I, /obj/item/weapon/wrench)))
if(enabled || raised)
user << "You cannot unsecure an active turret!"
@@ -343,6 +331,20 @@
sleep(60)
attacked = 0
..()
+
+/obj/machinery/porta_turret/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ //Emagging the turret makes it go bonkers and stun everyone. It also makes
+ //the turret shoot much, much faster.
+ user << "You short out [src]'s threat assessment circuits."
+ visible_message("[src] hums oddly...")
+ emagged = 1
+ iconholder = 1
+ controllock = 1
+ enabled = 0 //turns off the turret temporarily
+ sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
+ enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
+ return 1
/obj/machinery/porta_turret/proc/take_damage(var/force)
health -= force
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index ca0b150fe6..7e2d521698 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -7,6 +7,7 @@
#define RC_INFO 4 //Relay Info
//Request Console Screens
+#define RCS_MAINMENU 0 // Main menu
#define RCS_RQASSIST 1 // Request supplies
#define RCS_RQSUPPLY 2 // Request assistance
#define RCS_SENDINFO 3 // Relay information
@@ -15,7 +16,6 @@
#define RCS_VIEWMSGS 6 // View messages
#define RCS_MESSAUTH 7 // Authentication before sending
#define RCS_ANNOUNCE 8 // Send announcement
-#define RCS_MAINMENU 9 // Main menu
var/req_console_assistance = list()
var/req_console_supplies = list()
@@ -29,13 +29,12 @@ var/list/obj/machinery/requests_console/allConsoles = list()
icon = 'icons/obj/terminals.dmi'
icon_state = "req_comp0"
var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department
- var/list/messages = list() //List of all messages
+ var/list/message_log = list() //List of all messages
var/departmentType = 0 //Bitflag. Zero is reply-only. Map currently uses raw numbers instead of defines.
var/newmessagepriority = 0
// 0 = no new message
// 1 = normal priority
// 2 = high priority
- // 3 = extreme priority - not implemented, will probably require some hacking... everything needs to have a hidden feature in this game.
var/screen = RCS_MAINMENU
var/silent = 0 // set to 1 for it not to beep all the time
// var/hackState = 0
@@ -49,7 +48,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
var/msgVerified = "" //Will contain the name of the person who varified it
var/msgStamped = "" //If a message is stamped, this will contain the stamp name
var/message = "";
- var/dpt = ""; //the department which will be receiving the message
+ var/recipient = ""; //the department which will be receiving the message
var/priority = -1 ; //Priority of the message being sent
light_range = 0
var/datum/announcement/announcement = new
@@ -64,7 +63,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
icon_state = "req_comp_off"
else
if(icon_state == "req_comp_off")
- icon_state = "req_comp0"
+ icon_state = "req_comp[newmessagepriority]"
/obj/machinery/requests_console/New()
..()
@@ -80,6 +79,8 @@ var/list/obj/machinery/requests_console/allConsoles = list()
req_console_supplies |= department
if (departmentType & RC_INFO)
req_console_information |= department
+
+ set_light(1)
/obj/machinery/requests_console/Destroy()
allConsoles -= src
@@ -100,105 +101,34 @@ var/list/obj/machinery/requests_console/allConsoles = list()
/obj/machinery/requests_console/attack_hand(user as mob)
if(..(user))
return
- var/dat
- dat = text("Requests Console[department] Requests Console
")
- if(!open)
- switch(screen)
- if(RCS_RQASSIST) //req. assistance
- dat += text("Which department do you need assistance from?
")
- for(var/dpt in req_console_assistance)
- if (dpt != department)
- dat += text("[dpt] (Message or ")
- dat += text("High Priority")
-// if (hackState == 1)
-// dat += text(" or EXTREME)")
- dat += text(")
")
- dat += text("
Back
")
+ ui_interact(user)
- if(RCS_RQSUPPLY) //req. supplies
- dat += text("Which department do you need supplies from?
")
- for(var/dpt in req_console_supplies)
- if (dpt != department)
- dat += text("[dpt] (Message or ")
- dat += text("High Priority")
-// if (hackState == 1)
-// dat += text(" or EXTREME)")
- dat += text(")
")
- dat += text("
Back
")
+/obj/machinery/requests_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
- if(RCS_SENDINFO) //relay information
- dat += text("Which department would you like to send information to?
")
- for(var/dpt in req_console_information)
- if (dpt != department)
- dat += text("[dpt] (Message or ")
- dat += text("High Priority")
-// if (hackState == 1)
-// dat += text(" or EXTREME)")
- dat += text(")
")
- dat += text("
Back
")
+ data["department"] = department
+ data["screen"] = screen
+ data["message_log"] = message_log
+ data["newmessagepriority"] = newmessagepriority
+ data["silent"] = silent
+ data["announcementConsole"] = announcementConsole
- if(RCS_SENTPASS) //sent successfully
- dat += text("Message sent
")
- dat += text("Continue
")
+ data["assist_dept"] = req_console_assistance
+ data["supply_dept"] = req_console_supplies
+ data["info_dept"] = req_console_information
- if(RCS_SENTFAIL) //unsuccessful; not sent
- dat += text("An error occurred.
")
- dat += text("Continue
")
+ data["message"] = message
+ data["recipient"] = recipient
+ data["priortiy"] = priority
+ data["msgStamped"] = msgStamped
+ data["msgVerified"] = msgVerified
+ data["announceAuth"] = announceAuth
- if(RCS_VIEWMSGS) //view messages
- for (var/obj/machinery/requests_console/Console in allConsoles)
- if (Console.department == department)
- Console.newmessagepriority = 0
- Console.icon_state = "req_comp0"
- Console.set_light(1)
- newmessagepriority = 0
- icon_state = "req_comp0"
- for(var/msg in messages)
- dat += text("[msg]
")
- dat += text("Back to main menu
")
-
- if(RCS_MESSAUTH) //authentication before sending
- dat += text("Message Authentication
")
- dat += text("Message for [dpt]: [message]
")
- dat += text("You may authenticate your message now by scanning your ID or your stamp
")
- dat += text("Validated by: [msgVerified]
");
- dat += text("Stamped by: [msgStamped]
");
- dat += text("Send
");
- dat += text("
Back
")
-
- if(RCS_ANNOUNCE) //send announcement
- dat += text("Station wide announcement
")
- if(announceAuth)
- dat += text("Authentication accepted
")
- else
- dat += text("Swipe your card to authenticate yourself.
")
- dat += text("Message: [message] Write
")
- if (announceAuth && message)
- dat += text("Announce
");
- dat += text("
Back
")
-
- else //main menu
- screen = RCS_MAINMENU
- reset_announce()
- if (newmessagepriority == 1)
- dat += text("There are new messages
")
- if (newmessagepriority == 2)
- dat += text("NEW PRIORITY MESSAGES
")
- dat += text("View Messages
")
-
- dat += text("Request Assistance
")
- dat += text("Request Supplies
")
- dat += text("Relay Anonymous Information
")
- if(announcementConsole)
- dat += text("Send station-wide announcement
")
- if (silent)
- dat += text("Speaker OFF")
- else
- dat += text("Speaker ON")
-
- user << browse("[dat]", "window=request_console")
- onclose(user, "req_console")
- return
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "request_console.tmpl", "[department] Request Console", 520, 410)
+ ui.set_initial_data(data)
+ ui.open()
/obj/machinery/requests_console/Topic(href, href_list)
if(..()) return
@@ -206,38 +136,30 @@ var/list/obj/machinery/requests_console/allConsoles = list()
add_fingerprint(usr)
if(reject_bad_text(href_list["write"]))
- dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name
+ recipient = href_list["write"] //write contains the string of the receiving department's name
var/new_message = sanitize(input("Write your message:", "Awaiting Input", ""))
if(new_message)
message = new_message
screen = RCS_MESSAUTH
switch(href_list["priority"])
+ if("1") priority = 1
if("2") priority = 2
- else priority = -1
+ else priority = 0
else
- dpt = "";
- msgVerified = ""
- msgStamped = ""
- screen = RCS_MAINMENU
- priority = -1
+ reset_message(1)
if(href_list["writeAnnouncement"])
var/new_message = sanitize(input("Write your message:", "Awaiting Input", ""))
if(new_message)
message = new_message
- switch(href_list["priority"])
- if("2") priority = 2
- else priority = -1
else
- reset_announce()
- screen = RCS_MAINMENU
+ reset_message(1)
if(href_list["sendAnnouncement"])
if(!announcementConsole) return
announcement.Announce(message, msg_sanitized = 1)
- reset_announce()
- screen = RCS_MAINMENU
+ reset_message(1)
if( href_list["department"] && message )
var/log_msg = message
@@ -245,38 +167,37 @@ var/list/obj/machinery/requests_console/allConsoles = list()
screen = RCS_SENTFAIL
for (var/obj/machinery/message_server/MS in world)
if(!MS.active) continue
- MS.send_rc_message(href_list["department"],department,log_msg,msgStamped,msgVerified,priority)
+ MS.send_rc_message(ckey(href_list["department"]),department,log_msg,msgStamped,msgVerified,priority)
pass = 1
if(pass)
screen = RCS_SENTPASS
- messages += "Message sent to [dpt]
[message]"
+ message_log += "Message sent to [recipient]
[message]"
else
audible_message(text("\icon[src] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4)
-
//Handle screen switching
- var/tempScreen = text2num(href_list["setScreen"])
- if(tempScreen)
+ if(href_list["setScreen"])
+ var/tempScreen = text2num(href_list["setScreen"])
if(tempScreen == RCS_ANNOUNCE && !announcementConsole)
return
+ if(tempScreen == RCS_VIEWMSGS)
+ for (var/obj/machinery/requests_console/Console in allConsoles)
+ if (Console.department == department)
+ Console.newmessagepriority = 0
+ Console.icon_state = "req_comp0"
+ Console.set_light(1)
if(tempScreen == RCS_MAINMENU)
- dpt = ""
- msgVerified = ""
- msgStamped = ""
- message = ""
- priority = -1
+ reset_message()
screen = tempScreen
//Handle silencing the console
- switch( href_list["setSilent"] )
- if(null) //skip
- if("1") silent = 1
- else silent = 0
+ if(href_list["toggleSilent"])
+ silent = !silent
updateUsrDialog()
return
- //err... hacking code, which has no reason for existing... but anyway... it's supposed to unlock priority 3 messanging on that console (EXTREME priority...) the code for that actually exists.
+ //err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messanging on that console (EXTREME priority...), but the code for that was removed.
/obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob)
/*
if (istype(O, /obj/item/weapon/crowbar))
@@ -301,6 +222,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
user << "You can't do much with that."*/
if (istype(O, /obj/item/weapon/card/id))
+ if(inoperable(MAINT)) return
if(screen == RCS_MESSAUTH)
var/obj/item/weapon/card/id/T = O
msgVerified = text("Verified by [T.registered_name] ([T.assignment])")
@@ -311,27 +233,24 @@ var/list/obj/machinery/requests_console/allConsoles = list()
announceAuth = 1
announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name
else
- reset_announce()
+ reset_message()
user << "You are not authorized to send announcements."
updateUsrDialog()
if (istype(O, /obj/item/weapon/stamp))
+ if(inoperable(MAINT)) return
if(screen == RCS_MESSAUTH)
var/obj/item/weapon/stamp/T = O
msgStamped = text("Stamped with the [T.name]")
updateUsrDialog()
return
-/obj/machinery/requests_console/proc/reset_announce()
- announceAuth = 0
+/obj/machinery/requests_console/proc/reset_message(var/mainmenu = 0)
message = ""
+ recipient = ""
+ priority = 0
+ msgVerified = ""
+ msgStamped = ""
+ announceAuth = 0
announcement.announcer = ""
-
-#undef RCS_RQASSIST
-#undef RCS_RQSUPPLY
-#undef RCS_SENDINFO
-#undef RCS_SENTPASS
-#undef RCS_SENTFAIL
-#undef RCS_VIEWMSGS
-#undef RCS_MESSAUTH
-#undef RCS_ANNOUNCE
-#undef RCS_MAINMENU
+ if(mainmenu)
+ screen = RCS_MAINMENU
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index cb487ae58c..ac561009b6 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -684,7 +684,7 @@
user << "There is no room inside the cycler for [G.affecting.name]."
return
- visible_message("[user] starts putting [G.affecting.name] into the suit cycler.", 3)
+ visible_message("[user] starts putting [G.affecting.name] into the suit cycler.", 3)
if(do_after(user, 20))
if(!G || !G.affecting) return
@@ -708,24 +708,6 @@
src.updateUsrDialog()
return
- else if(istype(I,/obj/item/weapon/card/emag))
-
- if(emagged)
- user << "The cycler has already been subverted."
- return
-
- var/obj/item/weapon/card/emag/E = I
- src.updateUsrDialog()
- E.uses--
-
- //Clear the access reqs, disable the safeties, and open up all paintjobs.
- user << "You run the sequencer across the interface, corrupting the operating protocols."
- departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
- emagged = 1
- safeties = 0
- req_access = list()
- return
-
else if(istype(I,/obj/item/clothing/head/helmet/space) && !istype(I, /obj/item/clothing/head/helmet/space/rig))
if(locked)
@@ -773,6 +755,20 @@
return
..()
+
+/obj/machinery/suit_cycler/emag_act(var/remaining_charges, var/mob/user)
+ if(emagged)
+ user << "The cycler has already been subverted."
+ return
+
+ //Clear the access reqs, disable the safeties, and open up all paintjobs.
+ user << "You run the sequencer across the interface, corrupting the operating protocols."
+ departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
+ emagged = 1
+ safeties = 0
+ req_access = list()
+ src.updateUsrDialog()
+ return 1
/obj/machinery/suit_cycler/attack_hand(mob/user as mob)
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index c6fee28b40..820d09045b 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -353,7 +353,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- This following recording is intended for research and feedback in the use of department radio channels ---
var/part_blackbox_b = " \[[freq_text]\] " // Tweaked for security headsets -- TLE
- var/blackbox_msg = "[part_a][name][part_blackbox_b][quotedmsg][part_c]"
+ var/blackbox_msg = "[part_a][name][part_blackbox_b][quotedmsg][part_c]"
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
//BR.messages_admin += blackbox_admin_msg
@@ -533,12 +533,15 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE
var/part_c = ""
+ part_a = ""
+ part_a += "syndradio"
else if (display_freq==COMM_FREQ)
- part_a = ""
+ part_a += "comradio"
else if (display_freq in DEPT_FREQS)
- part_a = ""
+ part_a += "deptradio"
+
+ part_a += "'>"
// --- This following recording is intended for research and feedback in the use of department radio channels ---
diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm
index ef3c7d6ea9..2f6165a733 100644
--- a/code/game/machinery/telecomms/logbrowser.dm
+++ b/code/game/machinery/telecomms/logbrowser.dm
@@ -212,9 +212,13 @@
A.icon_state = "4"
A.anchored = 1
qdel(src)
- else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
- playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
- emagged = 1
- user << "You you disable the security protocols"
src.updateUsrDialog()
return
+
+/obj/machinery/computer/telecomms/server/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
+ emagged = 1
+ user << "You you disable the security protocols"
+ src.updateUsrDialog()
+ return 1
diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm
index ca132cc06e..7dd30dd8c3 100644
--- a/code/game/machinery/telecomms/telemonitor.dm
+++ b/code/game/machinery/telecomms/telemonitor.dm
@@ -150,9 +150,13 @@
A.icon_state = "4"
A.anchored = 1
qdel(src)
- else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
- playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
- emagged = 1
- user << "You you disable the security protocols"
src.updateUsrDialog()
return
+
+/obj/machinery/computer/telecomms/monitor/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
+ emagged = 1
+ user << "You you disable the security protocols"
+ src.updateUsrDialog()
+ return 1
diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm
index 6917675653..1123733103 100644
--- a/code/game/machinery/telecomms/traffic_control.dm
+++ b/code/game/machinery/telecomms/traffic_control.dm
@@ -233,9 +233,13 @@
A.icon_state = "4"
A.anchored = 1
qdel(src)
- else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
- playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
- emagged = 1
- user << "You you disable the security protocols"
src.updateUsrDialog()
return
+
+/obj/machinery/computer/telecomms/traffic/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
+ emagged = 1
+ user << "You you disable the security protocols"
+ src.updateUsrDialog()
+ return 1
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index 223b503f4f..a1e2287f58 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -84,13 +84,6 @@
if(stat & BROKEN)
return
- if(!emagged && istype(W, /obj/item/weapon/card/emag))
- user << "You short out the turret controls' access analysis module."
- emagged = 1
- locked = 0
- ailock = 0
- return
-
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(src.allowed(usr))
if(emagged)
@@ -100,6 +93,14 @@
user << "You [ locked ? "lock" : "unlock"] the panel."
return
return ..()
+
+/obj/machinery/turretid/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ user << "You short out the turret controls' access analysis module."
+ emagged = 1
+ locked = 0
+ ailock = 0
+ return 1
/obj/machinery/turretid/attack_ai(mob/user as mob)
if(isLocked(user))
@@ -191,13 +192,17 @@
..()
if(stat & NOPOWER)
icon_state = "control_off"
+ set_light(0)
else if (enabled)
if (lethal)
icon_state = "control_kill"
+ set_light(1.5, 1,"#990000")
else
icon_state = "control_stun"
+ set_light(1.5, 1,"#FF9900")
else
icon_state = "control_standby"
+ set_light(1.5, 1,"#003300")
/obj/machinery/turretid/emp_act(severity)
if(enabled)
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index e04034ad93..a3ac073a90 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -399,10 +399,6 @@
qdel(src)
return
- meteorhit()
- qdel(src)
- return
-
attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = {"
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 43d0f107c0..9c79441f32 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -176,6 +176,12 @@
return
return
+
+/obj/machinery/vending/emag_act(var/remaining_charges, var/mob/user)
+ if (!emagged)
+ src.emagged = 1
+ user << "You short out the product lock on \the [src]"
+ return 1
/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -207,10 +213,6 @@
if (I || istype(W, /obj/item/weapon/spacecash))
attack_hand(user)
return
- else if (istype(W, /obj/item/weapon/card/emag))
- src.emagged = 1
- user << "You short out the product lock on \the [src]"
- return
else if(istype(W, /obj/item/weapon/screwdriver))
src.panel_open = !src.panel_open
user << "You [src.panel_open ? "open" : "close"] the maintenance panel."
@@ -592,7 +594,7 @@
return
for(var/mob/O in hearers(src, null))
- O.show_message("\The [src] beeps, \"[message]\"",2)
+ O.show_message("\The [src] beeps, \"[message]\"",2)
return
/obj/machinery/vending/power_change()
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 7ebeb641d8..c1cadaef5c 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -5,8 +5,8 @@
icon_state = "sleeper_0"
origin_tech = list(TECH_DATA = 2, TECH_BIO = 3)
energy_drain = 20
- range = MELEE
- construction_cost = list(DEFAULT_WALL_MATERIAL=5000,"glass"=10000)
+ range = MELEE
+ construction_cost = list(DEFAULT_WALL_MATERIAL=5000,"glass"=10000)
equip_cooldown = 20
var/mob/living/carbon/occupant = null
var/datum/global_iterator/pr_mech_sleeper
@@ -644,7 +644,7 @@
return stop()
var/energy_drain = S.energy_drain*10
if(!S.processed_reagents.len || S.reagents.total_volume >= S.reagents.maximum_volume || !S.chassis.has_charge(energy_drain))
- S.occupant_message("Reagent processing stopped.")
+ S.occupant_message("Reagent processing stopped.")
S.log_message("Reagent processing stopped.")
return stop()
var/amount = S.synth_speed / S.processed_reagents.len
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 284bce3a33..2b17096547 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -1052,7 +1052,7 @@
if(M.stat>1) return
if(chassis.occupant.a_intent == I_HURT)
chassis.occupant_message("You obliterate [target] with [src.name], leaving blood and guts everywhere.")
- chassis.visible_message("[chassis] destroys [target] in an unholy fury.")
+ chassis.visible_message("[chassis] destroys [target] in an unholy fury.")
if(chassis.occupant.a_intent == I_DISARM)
chassis.occupant_message("You tear [target]'s limbs off with [src.name].")
chassis.visible_message("[chassis] rips [target]'s arms off.")
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 641c86e70e..07c54ceb2b 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -192,27 +192,6 @@
M << "You don't have required permissions to use [src]"
return 0
-
-/obj/machinery/mecha_part_fabricator/proc/emag()
- sleep()
- switch(emagged)
- if(0)
- emagged = 0.5
- src.visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"")
- sleep(10)
- src.visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"")
- sleep(15)
- src.visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
- sleep(30)
- src.visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"")
- req_access = null
- emagged = 1
- if(0.5)
- src.visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
- if(1)
- src.visible_message("\icon[src] [src] beeps: \"No records in User DB\"")
- return
-
/obj/machinery/mecha_part_fabricator/proc/convert_part_set(set_name as text)
var/list/parts = part_sets[set_name]
if(istype(parts, /list))
@@ -724,7 +703,26 @@
qdel(res)
return result
-
+/obj/machinery/mecha_part_fabricator/emag_act(var/remaining_charges, var/mob/user)
+ sleep()
+ switch(emagged)
+ if(0)
+ emagged = 0.5
+ src.visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"")
+ sleep(10)
+ src.visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"")
+ sleep(15)
+ src.visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
+ sleep(30)
+ src.visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"")
+ req_access = null
+ emagged = 1
+ return 1
+ if(0.5)
+ src.visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"")
+ if(1)
+ src.visible_message("\icon[src] [src] beeps: \"No records in User DB\"")
+
/obj/machinery/mecha_part_fabricator/attackby(obj/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/screwdriver))
if (!opened)
@@ -771,10 +769,6 @@
user << "You can't load the [src.name] while it's opened."
return 1
- if(istype(W, /obj/item/weapon/card/emag))
- emag()
- return
-
var/material
switch(W.type)
if(/obj/item/stack/material/gold)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 2d5c2201bd..ddf0f2bdd6 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -648,10 +648,6 @@
return
*/
-//TODO
-/obj/mecha/meteorhit()
- return ex_act(rand(1,3))//should do for now
-
/obj/mecha/emp_act(severity)
if(get_charge())
use_power((cell.charge/2)/severity)
@@ -690,13 +686,14 @@
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
-
+ /*
if(istype(W, /obj/item/device/mmi))
if(mmi_move_inside(W,user))
user << "[src]-MMI interface initialized successfuly"
else
user << "[src]-MMI interface initialization failed."
return
+ */
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
var/obj/item/mecha_parts/mecha_equipment/E = W
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index d9e88e70e0..cd6d1e76d3 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -82,11 +82,6 @@
healthcheck()
return
-/obj/effect/alien/resin/meteorhit()
- health-=50
- healthcheck()
- return
-
/obj/effect/alien/resin/hitby(AM as mob|obj)
..()
for(var/mob/O in viewers(src, null))
diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm
index eac107923e..9b15464544 100644
--- a/code/game/objects/effects/chem/water.dm
+++ b/code/game/objects/effects/chem/water.dm
@@ -3,6 +3,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
mouse_opacity = 0
+ pass_flags = PASSTABLE | PASSGRILLE
/obj/effect/effect/water/New(loc)
..()
@@ -30,7 +31,7 @@
else if(ismob(A) && !M)
M = A
if(M)
- reagents.splash_mob(M, reagents.total_volume)
+ reagents.splash(M, reagents.total_volume)
break
if(T == get_turf(target))
break
@@ -53,4 +54,3 @@
name = "chemicals"
icon = 'icons/obj/chempuff.dmi'
icon_state = ""
- pass_flags = PASSTABLE | PASSGRILLE
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index b81089d9fb..1c723c04ad 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -20,10 +20,12 @@ var/global/list/image/splatter_cache=list()
var/basecolor="#A10808" // Color when wet.
var/list/datum/disease2/disease/virus2 = list()
var/amount = 5
+ var/drytime
/obj/effect/decal/cleanable/blood/Destroy()
for(var/datum/disease/D in viruses)
D.cure(0)
+ processing_objects -= src
return ..()
/obj/effect/decal/cleanable/blood/New()
@@ -38,7 +40,11 @@ var/global/list/image/splatter_cache=list()
if (B.blood_DNA)
blood_DNA |= B.blood_DNA.Copy()
qdel(B)
- spawn(DRYING_TIME * (amount+1))
+ drytime = world.time + DRYING_TIME * (amount+1)
+ processing_objects += src
+
+/obj/effect/decal/cleanable/blood/process()
+ if(world.time > drytime)
dry()
/obj/effect/decal/cleanable/blood/update_icon()
@@ -91,6 +97,7 @@ var/global/list/image/splatter_cache=list()
desc = drydesc
color = adjust_brightness(color, -50)
amount = 0
+ processing_objects -= src
/obj/effect/decal/cleanable/blood/attack_hand(mob/living/carbon/human/user)
..()
@@ -125,8 +132,7 @@ var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood/drip/New()
..()
- spawn(1)
- drips |= icon_state
+ drips |= icon_state
/obj/effect/decal/cleanable/blood/writing
icon_state = "tracks"
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index b38a0f1551..ec3881cdbe 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -487,28 +487,34 @@ steam.start() -- spawns the effect
M.Weaken(rand(1,5))
return
else
- var/devastation = -1
+ var/devst = -1
var/heavy = -1
var/light = -1
var/flash = -1
- // Clamp all values to max_explosion_range
+ // Clamp all values to fractions of max_explosion_range, following the same pattern as for tank transfer bombs
if (round(amount/12) > 0)
- devastation = min (max_explosion_range, devastation + round(amount/12))
+ devst = devst + amount/12
if (round(amount/6) > 0)
- heavy = min (max_explosion_range, heavy + round(amount/6))
+ heavy = heavy + amount/6
if (round(amount/3) > 0)
- light = min (max_explosion_range, light + round(amount/3))
+ light = light + amount/3
- if (flash && flashing_factor)
- flash += (round(amount/4) * flashing_factor)
+ if (flashing && flashing_factor)
+ flash = (amount/4) * flashing_factor
for(var/mob/M in viewers(8, location))
M << "The solution violently explodes."
- explosion(location, devastation, heavy, light, flash)
+ explosion(
+ location,
+ round(min(devst, BOMBCAP_DVSTN_RADIUS)),
+ round(min(heavy, BOMBCAP_HEAVY_RADIUS)),
+ round(min(light, BOMBCAP_LIGHT_RADIUS)),
+ round(min(flash, BOMBCAP_FLASH_RADIUS))
+ )
proc/holder_damage(var/atom/holder)
if(holder)
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index aeac044f38..e5f769858f 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -88,16 +88,7 @@
return 1
-/obj/effect/landmark/start/ninja
- name = "ninja"
-
-/obj/effect/landmark/start/ninja/New()
- ..()
- ninjastart += loc
- qdel(src)
-
//Costume spawner landmarks
-
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
var/list/options = typesof(/obj/effect/landmark/costume)
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 58c053aa66..6ad69f099b 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -16,16 +16,16 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
explosion_rec(epicenter, power)
return
+ var/start = world.timeofday
+ epicenter = get_turf(epicenter)
+ if(!epicenter) return
+
///// Z-Level Stuff
if(z_transfer && (devastation_range > 0 || heavy_impact_range > 0))
//transfer the explosion in both directions
explosion_z_transfer(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
///// Z-Level Stuff
- var/start = world.timeofday
- epicenter = get_turf(epicenter)
- if(!epicenter) return
-
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range)
//playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) )
//playsound(epicenter, "explosion", 100, 1, round(devastation_range,1) )
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index ffa85880a3..72b5229cc0 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -40,13 +40,19 @@
var/zoomdevicename = null //name used for message when binoculars/scope is used
var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars.
+ var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
var/item_state = null // Used to specify the item state for the on-mob overlays.
- var/item_state_slots = null //overrides the default item_state for particular slots.
+
+ //** These specify item/icon overrides for _slots_
+
+ var/list/item_state_slots = list() //overrides the default item_state for particular slots.
// Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used.
// If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question.
// Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed.
- var/list/item_icons = null
+ var/list/item_icons = list()
+
+ //** These specify item/icon overrides for _species_
/* Species-specific sprites, concept stolen from Paradise//vg/.
ex:
@@ -55,13 +61,11 @@
)
If index term exists and icon_override is not set, this sprite sheet will be used.
*/
- var/list/sprite_sheets = null
- var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
+ var/list/sprite_sheets = list()
- /* Species-specific sprite sheets for inventory sprites
- Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
- */
- var/list/sprite_sheets_obj = null
+ // Species-specific sprite sheets for inventory sprites
+ // Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
+ var/list/sprite_sheets_obj = list()
/obj/item/Destroy()
if(ismob(loc))
@@ -147,7 +151,7 @@
if (user.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
- user << "You try to move your [temp.name], but cannot!"
+ user << "You try to move your [temp.name], but cannot!"
return
if (istype(src.loc, /obj/item/weapon/storage))
@@ -604,3 +608,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
/obj/item/proc/pwr_drain()
return 0 // Process Kill
+
+/obj/item/proc/resolve_attackby(atom/A, mob/source)
+ return A.attackby(src,source)
diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm
index a88d4f0e39..4b69e5db7c 100644
--- a/code/game/objects/items/apc_frame.dm
+++ b/code/game/objects/items/apc_frame.dm
@@ -1,19 +1,19 @@
// APC HULL
-/obj/item/apc_frame
+/obj/item/frame/apc
name = "\improper APC frame"
desc = "Used for repairing or building APCs"
icon = 'icons/obj/apc_repair.dmi'
icon_state = "apc_frame"
flags = CONDUCT
-/obj/item/apc_frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
+/obj/item/frame/apc/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(W, /obj/item/weapon/wrench))
new /obj/item/stack/material/steel( get_turf(src.loc), 2 )
qdel(src)
-/obj/item/apc_frame/proc/try_build(turf/on_wall)
+/obj/item/frame/apc/try_build(turf/on_wall)
if (get_dist(on_wall,usr)>1)
return
var/ndir = get_dir(usr,on_wall)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 10adef3d88..fbdb7667a1 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -1058,6 +1058,21 @@ var/global/list/obj/item/device/pda/PDAs = list()
log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]")
new_message = 1
+/obj/item/device/pda/verb/verb_reset_pda()
+ set category = "Object"
+ set name = "Reset PDA"
+ set src in usr
+
+ if(issilicon(usr))
+ return
+
+ if(can_use(usr))
+ mode = 0
+ nanomanager.update_uis(src)
+ usr << "You press the reset button on \the [src]."
+ else
+ usr << "You cannot do this while restrained."
+
/obj/item/device/pda/verb/verb_remove_id()
set category = "Object"
set name = "Remove id"
@@ -1200,7 +1215,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
user.show_message("Analyzing Results for [C]:")
user.show_message(" Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]", 1)
- user.show_message(text(" Damage Specifics: []-[]-[]-[]",
+ user.show_message(text(" Damage Specifics: []-[]-[]-[]",
(C.getOxyLoss() > 50) ? "warning" : "", C.getOxyLoss(),
(C.getToxLoss() > 50) ? "warning" : "", C.getToxLoss(),
(C.getFireLoss() > 50) ? "warning" : "", C.getFireLoss(),
@@ -1216,7 +1231,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
user.show_message("Localized Damage, Brute/Burn:",1)
if(length(damaged)>0)
for(var/obj/item/organ/external/org in damaged)
- user.show_message(text(" []: []-[]",
+ user.show_message(text(" []: []-[]",
capitalize(org.name), (org.brute_dam > 0) ? "warning" : "notice", org.brute_dam, (org.burn_dam > 0) ? "warning" : "notice", org.burn_dam),1)
else
user.show_message(" Limbs are OK.",1)
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index a6a51386d5..e4d1c57a0d 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -91,7 +91,7 @@
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
if(!ai.client)
- user << "ERROR: [name] data core is offline. Unable to download."
+ user << "ERROR: AI [ai.name] is offline. Unable to download."
return 0
if(carded_ai)
@@ -112,7 +112,6 @@
ai.cancel_camera()
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
- ai.aiRadio.disabledAi = 1
carded_ai = ai
if(ai.client)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index f68451f329..65e8a560df 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -48,38 +48,43 @@
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
- if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") //don't have dexterity
- user << "You don't have the dexterity to do this!"
- return
-
var/mob/living/carbon/human/H = M //mob has protective eyewear
- if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
- user << "You're going to need to remove that [(H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask": "glasses"] first."
- return
+ if(istype(H))
+ for(var/obj/item/clothing/C in list(H.head,H.wear_mask,H.glasses))
+ if(istype(C) && C.flags & (HEADCOVERSEYES|MASKCOVERSEYES|GLASSESCOVERSEYES))
+ user << "You're going to need to remove [C.name] first."
+ return
- if(M == user) //they're using it on themselves
- if(!M.blinded)
- flick("flash", M.flash)
- M.visible_message("[M] directs [src] to \his eyes.", \
- "You wave the light in front of your eyes! Trippy!")
- else
- M.visible_message("[M] directs [src] to \his eyes.", \
- "You wave the light in front of your eyes.")
- return
+ var/obj/item/organ/vision
+ if(H.species.vision_organ)
+ vision = H.internal_organs_by_name[H.species.vision_organ]
+ if(!vision)
+ user << "You can't find any [H.species.vision_organ ? H.species.vision_organ : "eyes"] on [H]!"
- user.visible_message("[user] directs [src] to [M]'s eyes.", \
- "You direct [src] to [M]'s eyes.")
+ user.visible_message("\The [user] directs [src] to [M]'s eyes.", \
+ "You direct [src] to [M]'s eyes.")
+ if(H == user) //can't look into your own eyes buster
+ if(M.stat == DEAD || M.blinded) //mob is dead or fully blind
+ user << "\The [M]'s pupils do not react to the light!"
+ return
+ if(XRAY in M.mutations)
+ user << "\The [M] pupils give an eerie glow!"
+ if(vision.is_bruised())
+ user << "There's visible damage to [M]'s [vision.name]!"
+ else if(M.eye_blurry)
+ user << "\The [M]'s pupils react slower than normally."
+ if(M.getBrainLoss() > 15)
+ user << "There's visible lag between left and right pupils' reactions."
- if(istype(M, /mob/living/carbon/human)) //robots and aliens are unaffected
- if(M.stat == DEAD || M.sdisabilities & BLIND) //mob is dead or fully blind
- user << "[M] pupils does not react to the light!"
- else if(XRAY in M.mutations) //mob has X-RAY vision
- flick("flash", M.flash) //Yes, you can still get flashed wit X-Ray.
- user << "[M] pupils give an eerie glow!"
- else //they're okay!
- if(!M.blinded)
- flick("flash", M.flash) //flash the affected mob
- user << "[M]'s pupils narrow."
+ var/list/pinpoint = list("oxycodone"=1,"tramadol"=5)
+ var/list/dilating = list("space_drugs"=5,"mindbreaker"=1)
+ if(M.reagents.has_any_reagent(pinpoint) || H.ingested.has_any_reagent(pinpoint))
+ user << "\The [M]'s pupils are already pinpoint and cannot narrow any more."
+ else if(M.reagents.has_any_reagent(dilating) || H.ingested.has_any_reagent(dilating))
+ user << "\The [M]'s pupils narrow slightly, but are still very dilated."
+ else
+ user << "\The [M]'s pupils narrow."
+ flick("flash", M.flash)
else
return ..()
@@ -89,6 +94,7 @@
icon_state = "penlight"
item_state = ""
flags = CONDUCT
+ slot_flags = SLOT_EARS
brightness_on = 2
w_class = 1
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index 3471d1fcfe..f849b17c99 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -67,14 +67,10 @@
user << "It has [uses] lights remaining."
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/weapon/card/emag) && emagged == 0)
- Emag()
- return
-
if(istype(W, /obj/item/stack/material/glass))
var/obj/item/stack/material/glass/G = W
if(uses >= max_uses)
- user << "[src.name] is full."
+ user << "[src.name] is full."
return
else if(G.use(1))
AddUses(5)
@@ -173,14 +169,11 @@
U << "There is a working [target.fitting] already inserted."
return
-/obj/item/device/lightreplacer/proc/Emag()
+/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
emagged = !emagged
playsound(src.loc, "sparks", 100, 1)
- if(emagged)
- name = "Shortcircuited [initial(name)]"
- else
- name = initial(name)
update_icon()
+ return 1
//Can you use it?
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 2e08de6d81..0357a8b80b 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -46,10 +46,9 @@
spamcheck = 0
return
-/obj/item/device/megaphone/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/weapon/card/emag) && !emagged)
+/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
user << "You overload \the [src]'s voice synthesizer."
emagged = 1
insults = rand(1, 3)//to prevent dickflooding
- return
- return
+ return 1
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index 72a99f494e..48fa43ba64 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -1,11 +1,12 @@
/obj/item/device/encryptionkey/
- name = "standard encrpytion key"
+ name = "standard encryption key"
desc = "An encryption key for a radio headset. Contains cypherkeys."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
item_state = ""
w_class = 1
+ slot_flags = SLOT_EARS
var/translate_binary = 0
var/translate_hive = 0
var/syndie = 0
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 5c14d8debe..849ceac3af 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -173,14 +173,14 @@ REAGENT SCANNER
if (ID in virusDB)
var/datum/data/record/V = virusDB[ID]
user.show_message("Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]")
-// user.show_message(text("Warning: Unknown pathogen detected in subject's blood."))
+// user.show_message(text("Warning: Unknown pathogen detected in subject's blood."))
if (M.getCloneLoss())
user.show_message("Subject appears to have been imperfectly cloned.")
for(var/datum/disease/D in M.viruses)
if(!D.hidden[SCANNER])
user.show_message(text("Warning: [D.form] Detected\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
// if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
-// user.show_message("Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.")
+// user.show_message("Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.")
if (M.has_brain_worms())
user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.")
else if (M.getBrainLoss() >= 100 || !M.has_brain())
@@ -221,7 +221,7 @@ REAGENT SCANNER
if(blood_volume <= 500 && blood_volume > 336)
user.show_message("Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
else if(blood_volume <= 336)
- user.show_message("Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
+ user.show_message("Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
else
user.show_message("Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm
index 932b3d6a6b..9f1041af87 100644
--- a/code/game/objects/items/devices/spy_bug.dm
+++ b/code/game/objects/items/devices/spy_bug.dm
@@ -9,6 +9,7 @@
flags = CONDUCT
force = 5.0
w_class = 1.0
+ slot_flags = SLOT_EARS
throwforce = 5.0
throw_range = 15
throw_speed = 3
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 405e77db7a..e59d3e993b 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -48,16 +48,15 @@
timestamp += timerecorded
storedinfo += "*\[[time2text(timerecorded*10,"mm:ss")]\] *[strip_html_properly(recordedtext)]*" //"*" at front as a marker
-/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/weapon/card/emag))
- if(emagged == 0)
- emagged = 1
- recording = 0
- user << "PZZTTPFFFT"
- icon_state = "taperecorderidle"
- else
- user << "It is already emagged!"
+/obj/item/device/taperecorder/emag_act(var/remaining_charges, var/mob/user)
+ if(emagged == 0)
+ emagged = 1
+ recording = 0
+ user << "PZZTTPFFFT"
+ icon_state = "taperecorderidle"
+ return 1
+ else
+ user << "It is already emagged!"
/obj/item/device/taperecorder/proc/explode()
var/turf/T = get_turf(loc)
diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplink.dm
similarity index 54%
rename from code/game/objects/items/devices/uplinks.dm
rename to code/game/objects/items/devices/uplink.dm
index 96874bd946..345e9ddd06 100644
--- a/code/game/objects/items/devices/uplinks.dm
+++ b/code/game/objects/items/devices/uplink.dm
@@ -6,159 +6,26 @@ A list of items and costs is stored under the datum of every game mode, alongsid
*/
-/datum/uplink_item/
- var/name = ""
- var/cost = 0
- var/path = null
- var/reference = ""
- var/description = ""
-
-datum/uplink_item/New(var/itemPath, var/itemCost, var/itemName, var/itemReference, var/itemDescription)
- cost = itemCost
- path = itemPath
- name = itemName
- reference = itemReference
- description = itemDescription
-
-datum/uplink_item/proc/description()
- if(!description)
- // Fallback description
- var/obj/temp = src.path
- description = replacetext(initial(temp.desc), "\n", "
")
- return description
-
-/datum/uplink_item/proc/generate_item(var/newloc)
- var/list/L = list()
- if(ispath(path))
- L += new path(newloc)
- else if(islist(path))
- for(var/item_path in path)
- L += new item_path(newloc)
- return L
-
-datum/nano_item_lists
- var/list/items_nano
- var/list/items_reference
-
/obj/item/device/uplink
- var/welcome // Welcoming menu message
- var/uses // Numbers of crystals
- var/list/ItemsCategory // List of categories with lists of items
- var/list/ItemsReference // List of references with an associated item
- var/list/nanoui_items // List of items for NanoUI use
- var/nanoui_menu = 0 // The current menu we are in
- var/list/nanoui_data = new // Additional data for NanoUI use
-
- var/list/purchase_log = new
- var/uplink_owner = null//text-only
+ var/welcome = "Illegal Uplink Console" // Welcoming menu message
+ var/uses = DEFAULT_TELECRYSTAL_AMOUNT // Numbers of crystals
+ var/list/purchase_log
+ var/datum/mind/owner = null
var/used_TC = 0
/obj/item/device/uplink/nano_host()
return loc
-/obj/item/device/uplink/New()
+/obj/item/device/uplink/New(var/location, var/datum/mind/owner)
..()
- welcome = ticker.mode.uplink_welcome
- uses = ticker.mode.uplink_uses
- ItemsCategory = ticker.mode.uplink_items
-
+ src.owner = owner
+ purchase_log = list()
world_uplinks += src
/obj/item/device/uplink/Destroy()
world_uplinks -= src
..()
-/obj/item/device/uplink/proc/generate_items()
- var/datum/nano_item_lists/IL = generate_item_lists()
- nanoui_items = IL.items_nano
- ItemsReference = IL.items_reference
-
-// BS12 no longer use this menu but there are forks that do, hency why we keep it
-/obj/item/device/uplink/proc/generate_menu()
- var/dat = "[src.welcome]
"
- dat += "Tele-Crystals left: [src.uses]
"
- dat += "
"
- dat += "Request item:
"
- dat += "Each item costs a number of tele-crystals as indicated by the number following their name.
"
-
- var/category_items = 1
- for(var/category in ItemsCategory)
- if(category_items < 1)
- dat += "We apologize, as you could not afford anything from this category.
"
- dat += "
"
- dat += "[category]
"
- category_items = 0
-
- for(var/datum/uplink_item/I in ItemsCategory[category])
- if(I.cost > uses)
- continue
- dat += "[I.name] ([I.cost])
"
- category_items++
-
- dat += "Random Item (??)
"
- dat += "
"
- return dat
-
-/*
- Built the item lists for use with NanoUI
-*/
-/obj/item/device/uplink/proc/generate_item_lists()
- var/list/nano = new
- var/list/reference = new
-
- for(var/category in ItemsCategory)
- nano[++nano.len] = list("Category" = category, "items" = list())
- for(var/datum/uplink_item/I in ItemsCategory[category])
- nano[nano.len]["items"] += list(list("Name" = I.name, "Description" = I.description(),"Cost" = I.cost, "obj_path" = I.reference))
- reference[I.reference] = I
-
- var/datum/nano_item_lists/result = new
- result.items_nano = nano
- result.items_reference = reference
- return result
-
-//If 'random' was selected
-/obj/item/device/uplink/proc/chooseRandomItem()
- if(uses <= 0)
- return
-
- var/list/random_items = new
- for(var/IR in ItemsReference)
- var/datum/uplink_item/UI = ItemsReference[IR]
- if(UI.cost <= uses)
- random_items += UI
- return pick(random_items)
-
-/obj/item/device/uplink/Topic(href, href_list)
- if(..())
- return 1
-
- if(href_list["buy_item"] == "random")
- var/datum/uplink_item/UI = chooseRandomItem()
- href_list["buy_item"] = UI.reference
- return buy(UI, "RN")
- else
- var/datum/uplink_item/UI = ItemsReference[href_list["buy_item"]]
- return buy(UI, UI ? UI.reference : "")
- return 0
-
-/obj/item/device/uplink/proc/buy(var/datum/uplink_item/UI, var/reference)
- if(UI && UI.cost <= uses)
- uses -= UI.cost
- used_TC += UI.cost
- feedback_add_details("traitor_uplink_items_bought", reference)
-
- var/list/L = UI.generate_item(get_turf(usr))
- if(ishuman(usr))
- var/mob/living/carbon/human/A = usr
- for(var/obj/I in L)
- A.put_in_any_hand_if_possible(I)
-
- purchase_log[UI] = purchase_log[UI] + 1
-
- return 1
- return 0
-
// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
/* How to create an uplink in 3 easy steps!
@@ -175,6 +42,11 @@ datum/nano_item_lists
name = "hidden uplink"
desc = "There is something wrong if you're examining this."
var/active = 0
+ var/nanoui_menu = 0 // The current menu we are in
+ var/datum/uplink_category/category = 0 // The current category we are in
+ var/exploit_id // Id of the current exploit record we are viewing
+ var/list/nanoui_data // Data for NanoUI use
+
// The hidden uplink MUST be inside an obj/item's contents.
/obj/item/device/uplink/hidden/New()
@@ -182,6 +54,8 @@ datum/nano_item_lists
if(!istype(src.loc, /obj/item))
qdel(src)
..()
+ nanoui_data = list()
+ update_nano_data()
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
/obj/item/device/uplink/hidden/proc/toggle()
@@ -212,20 +86,13 @@ datum/nano_item_lists
data["welcome"] = welcome
data["crystals"] = uses
data["menu"] = nanoui_menu
- if(!nanoui_items)
- generate_items()
- data["nano_items"] = nanoui_items
data += nanoui_data
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
- if (!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ if (!ui) // No auto-refresh
ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600, state = inventory_state)
- // when the ui is first opened this is the data it will use
ui.set_initial_data(data)
- // open the new ui window
ui.open()
@@ -235,43 +102,54 @@ datum/nano_item_lists
// The purchasing code.
/obj/item/device/uplink/hidden/Topic(href, href_list)
- if (usr.stat || usr.restrained())
+ if(..())
return 1
- if (!( istype(usr, /mob/living/carbon/human)))
- return 1
var/mob/user = usr
- var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
- if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
- usr.set_machine(src)
- if(..(href, href_list))
- return 1
- else if(href_list["lock"])
- toggle()
- ui.close()
- return 1
- if(href_list["return"])
- nanoui_menu = round(nanoui_menu/10)
- update_nano_data()
- if(href_list["menu"])
- nanoui_menu = text2num(href_list["menu"])
- update_nano_data(href_list["id"])
+ if(href_list["buy_item"])
+ var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items)
+ UI.buy(src, usr)
+ else if(href_list["lock"])
+ toggle()
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
+ ui.close()
+ else if(href_list["return"])
+ nanoui_menu = round(nanoui_menu/10)
+ else if(href_list["menu"])
+ nanoui_menu = text2num(href_list["menu"])
+ if(href_list["id"])
+ exploit_id = href_list["id"]
+ if(href_list["category"])
+ category = locate(href_list["category"]) in uplink.categories
- interact(usr)
+ update_nano_data()
return 1
-/obj/item/device/uplink/hidden/proc/update_nano_data(var/id)
- if(nanoui_menu == 1)
+/obj/item/device/uplink/hidden/proc/update_nano_data()
+ if(nanoui_menu == 0)
+ var/categories[0]
+ for(var/datum/uplink_category/category in uplink.categories)
+ if(category.can_view(src))
+ categories[++categories.len] = list("name" = category.name, "ref" = "\ref[category]")
+ nanoui_data["categories"] = categories
+ else if(nanoui_menu == 1)
+ var/items[0]
+ for(var/datum/uplink_item/item in category.items)
+ if(item.can_view(src))
+ var/cost = item.cost(uses)
+ if(!cost) cost = "???"
+ items[++items.len] = list("name" = item.name, "description" = replacetext(item.description(), "\n", "
"), "can_buy" = item.can_buy(src), "cost" = cost, "ref" = "\ref[item]")
+ nanoui_data["items"] = items
+ else if(nanoui_menu == 2)
var/permanentData[0]
for(var/datum/data/record/L in sortRecord(data_core.locked))
permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"])
nanoui_data["exploit_records"] = permanentData
-
- if(nanoui_menu == 11)
+ else if(nanoui_menu == 21)
nanoui_data["exploit_exists"] = 0
for(var/datum/data/record/L in data_core.locked)
- if(L.fields["id"] == id)
+ if(L.fields["id"] == exploit_id)
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
diff --git a/code/game/objects/items/devices/uplink_categories.dm b/code/game/objects/items/devices/uplink_categories.dm
new file mode 100644
index 0000000000..f90c4797bc
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_categories.dm
@@ -0,0 +1,40 @@
+/datum/uplink_category
+ var/name = ""
+ var/list/datum/uplink_item/items
+
+/datum/uplink_category/New()
+ ..()
+ items = list()
+
+/datum/uplink_category/proc/can_view(obj/item/device/uplink/U)
+ for(var/datum/uplink_item/item in items)
+ if(item.can_view(U))
+ return 1
+ return 0
+
+/datum/uplink_category/ammunition
+ name = "Ammunition"
+
+/datum/uplink_category/visible_weapons
+ name = "Highly Visible and Dangerous Weapons"
+
+/datum/uplink_category/stealthy_weapons
+ name = "Stealthy and Inconspicuous Weapons"
+
+/datum/uplink_category/stealth_items
+ name = "Stealth and Camouflage Items"
+
+/datum/uplink_category/tools
+ name = "Devices and Tools"
+
+/datum/uplink_category/implants
+ name = "Implants"
+
+/datum/uplink_category/medical
+ name = "Medical"
+
+/datum/uplink_category/hardsuit_modules
+ name = "Hardsuit Modules"
+
+/datum/uplink_category/badassery
+ name = "Badassery"
diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm
new file mode 100644
index 0000000000..9765519622
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_items.dm
@@ -0,0 +1,527 @@
+var/datum/uplink/uplink = new()
+
+/datum/uplink
+ var/list/items_assoc
+ var/list/datum/uplink_item/items
+ var/list/datum/uplink_category/categories
+
+/datum/uplink/New()
+ items_assoc = list()
+ items = init_subtypes(/datum/uplink_item)
+ categories = init_subtypes(/datum/uplink_category)
+
+ for(var/datum/uplink_item/item in items)
+ if(!item.name)
+ items -= item
+ continue
+
+ items_assoc[item.type] = item
+
+ for(var/datum/uplink_category/category in categories)
+ if(item.category == category.type)
+ category.items += item
+
+ for(var/datum/uplink_category/category in categories)
+ category.items = dd_sortedObjectList(category.items)
+
+/datum/uplink_item
+ var/name
+ var/desc
+ var/item_cost = 0
+ var/datum/uplink_category/category // Item category
+ var/list/datum/antagonist/antag_roles // Antag roles this item is displayed to. If empty, display to all.
+
+/datum/uplink_item/item
+ var/path = null
+
+/datum/uplink_item/New()
+ ..()
+ antag_roles = list()
+
+/datum/uplink_item/proc/buy(var/obj/item/device/uplink/U, var/mob/user)
+ purchase_log(U)
+ var/cost = cost(U.uses)
+ var/goods = get_goods(U, get_turf(user))
+
+ U.uses -= cost
+ U.used_TC += cost
+ return goods
+
+/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
+ if(cost(U.uses) > U.uses)
+ return 0
+
+ return can_view(U)
+
+/datum/uplink_item/proc/can_view(obj/item/device/uplink/U)
+ // Making the assumption that if no uplink was supplied, then we don't care about antag roles
+ if(!U || !antag_roles.len)
+ return 1
+
+ // With no owner, there's no need to check antag status.
+ if(!U.owner)
+ return 0
+
+ for(var/antag_role in antag_roles)
+ var/datum/antagonist/antag = all_antag_types[antag_role]
+ if(antag.is_antagonist(U.owner))
+ return 1
+ return 0
+
+/datum/uplink_item/proc/cost(var/telecrystals)
+ return item_cost
+
+/datum/uplink_item/proc/description()
+ return desc
+
+// get_goods does not necessarily return physical objects, it is simply a way to acquire the uplink item without paying
+/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc)
+ return 0
+
+/datum/uplink_item/proc/log_icon()
+ return
+
+/datum/uplink_item/proc/purchase_log(obj/item/device/uplink/U)
+ feedback_add_details("traitor_uplink_items_bought", "[src]")
+ U.purchase_log[src] = U.purchase_log[src] + 1
+
+datum/uplink_item/dd_SortValue()
+ return cost(INFINITY)
+
+/********************************
+* *
+* Physical Uplink Entires *
+* *
+********************************/
+/datum/uplink_item/item/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/obj/item/I = ..()
+ if(istype(I, /list))
+ var/list/L = I
+ if(L.len) I = L[1]
+
+ if(istype(I) && ishuman(user))
+ var/mob/living/carbon/human/A = user
+ A.put_in_any_hand_if_possible(I)
+ return I
+
+/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc)
+ var/obj/item/I = new path(loc)
+ return I
+
+/datum/uplink_item/item/description()
+ if(!desc)
+ // Fallback description
+ var/obj/temp = src.path
+ desc = initial(temp.desc)
+ return ..()
+
+/datum/uplink_item/item/log_icon()
+ var/obj/I = path
+ return "\icon[I]"
+
+/*************
+* Ammunition *
+*************/
+/datum/uplink_item/item/ammo
+ item_cost = 2
+ category = /datum/uplink_category/ammunition
+
+/datum/uplink_item/item/ammo/a357
+ name = ".357"
+ path = /obj/item/ammo_magazine/a357
+
+/datum/uplink_item/item/ammo/mc9mm
+ name = ".9mm"
+ path = /obj/item/ammo_magazine/mc9mm
+
+/datum/uplink_item/item/ammo/darts
+ name = "Darts"
+ path = /obj/item/ammo_magazine/chemdart
+
+/datum/uplink_item/item/ammo/sniperammo
+ name = "14.5mm"
+ path = /obj/item/weapon/storage/box/sniperammo
+
+/***************************************
+* Highly Visible and Dangerous Weapons *
+***************************************/
+/datum/uplink_item/item/visible_weapons
+ category = /datum/uplink_category/visible_weapons
+
+/datum/uplink_item/item/visible_weapons/emp
+ name = "5xEMP Grenades"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/emps
+
+/datum/uplink_item/item/visible_weapons/energy_sword
+ name = "Energy Sword"
+ item_cost = 4
+ path = /obj/item/weapon/melee/energy/sword
+
+/datum/uplink_item/item/visible_weapons/dartgun
+ name = "Dart Gun"
+ item_cost = 5
+ path = /obj/item/weapon/gun/projectile/dartgun
+
+/datum/uplink_item/item/visible_weapons/crossbow
+ name = "Energy Crossbow"
+ item_cost = 5
+ path = /obj/item/weapon/gun/energy/crossbow
+
+/datum/uplink_item/item/visible_weapons/g9mm
+ name = "Silenced 9mm"
+ item_cost = 5
+ path = /obj/item/weapon/storage/box/syndie_kit/g9mm
+
+/datum/uplink_item/item/visible_weapons/riggedlaser
+ name = "Exosuit Rigged Laser"
+ item_cost = 6
+ path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser
+
+/datum/uplink_item/item/visible_weapons/revolver
+ name = "Revolver"
+ item_cost = 6
+ path = /obj/item/weapon/gun/projectile/revolver
+
+/datum/uplink_item/item/visible_weapons/heavysniper
+ name = "Anti-materiel Rifle"
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT
+ path = /obj/item/weapon/gun/projectile/heavysniper
+
+/*************************************
+* Stealthy and Inconspicuous Weapons *
+*************************************/
+/datum/uplink_item/item/stealthy_weapons
+ category = /datum/uplink_category/stealthy_weapons
+
+/datum/uplink_item/item/stealthy_weapons/soap
+ name = "Subversive Soap"
+ item_cost = 1
+ path = /obj/item/weapon/soap/syndie
+
+/datum/uplink_item/item/stealthy_weapons/concealed_cane
+ name = "Concealed Cane Sword"
+ item_cost = 1
+ path = /obj/item/weapon/cane/concealed
+
+/datum/uplink_item/item/stealthy_weapons/detomatix
+ name = "Detomatix PDA Cartridge"
+ item_cost = 3
+ path = /obj/item/weapon/cartridge/syndicate
+
+/datum/uplink_item/item/stealthy_weapons/parapen
+ name = "Paralysis Pen"
+ item_cost = 3
+ path = /obj/item/weapon/pen/reagent/paralysis
+
+/datum/uplink_item/item/stealthy_weapons/cigarette_kit
+ name = "Cigarette Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/cigarette
+
+/datum/uplink_item/item/stealthy_weapons/random_toxin
+ name = "Random Toxin - Beaker"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/toxin
+
+/*******************************
+* Stealth and Camouflage Items *
+*******************************/
+/datum/uplink_item/item/stealth_items
+ category = /datum/uplink_category/stealth_items
+
+/datum/uplink_item/item/stealth_items/id
+ name = "Agent ID card"
+ item_cost = 2
+ path = /obj/item/weapon/card/id/syndicate
+
+/datum/uplink_item/item/stealth_items/syndigaloshes
+ name = "No-Slip Shoes"
+ item_cost = 2
+ path = /obj/item/clothing/shoes/syndigaloshes
+
+/datum/uplink_item/item/stealth_items/spy
+ name = "Bug Kit"
+ item_cost = 2
+ path = /obj/item/weapon/storage/box/syndie_kit/spy
+
+/datum/uplink_item/item/stealth_items/chameleon_kit
+ name = "Chameleon Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/chameleon
+
+/datum/uplink_item/item/stealth_items/chameleon_projector
+ name = "Chameleon-Projector"
+ item_cost = 4
+ path = /obj/item/device/chameleon
+
+/datum/uplink_item/item/stealth_items/chameleon_projector
+ name = "Chameleon-Projector"
+ item_cost = 4
+ path = /obj/item/device/chameleon
+
+/datum/uplink_item/item/stealth_items/voice
+ name = "Voice Changer"
+ item_cost = 4
+ path = /obj/item/clothing/mask/gas/voice
+
+/datum/uplink_item/item/stealth_items/camera_floppy
+ name = "Camera Network Access - Floppy"
+ item_cost = 6
+ path = /obj/item/weapon/disk/file/cameras/syndicate
+
+/********************
+* Devices and Tools *
+********************/
+/datum/uplink_item/item/tools
+ category = /datum/uplink_category/tools
+
+/datum/uplink_item/item/tools/toolbox
+ name = "Fully Loaded Toolbox"
+ item_cost = 1
+ path = /obj/item/weapon/storage/toolbox/syndicate
+
+/datum/uplink_item/item/tools/plastique
+ name = "C-4 (Destroys walls)"
+ item_cost = 2
+ path = /obj/item/weapon/plastique
+
+/datum/uplink_item/item/tools/encryptionkey_radio
+ name = "Encrypted Radio Channel Key"
+ item_cost = 2
+ path = /obj/item/device/encryptionkey/syndicate
+
+/datum/uplink_item/item/tools/encryptionkey_binary
+ name = "Binary Translator Key"
+ item_cost = 3
+ path = /obj/item/device/encryptionkey/binary
+
+/datum/uplink_item/item/tools/emag
+ name = "Cryptographic Sequencer"
+ item_cost = 3
+ path = /obj/item/weapon/card/emag
+
+/datum/uplink_item/item/tools/clerical
+ name = "Morphic Clerical Kit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/clerical
+
+/datum/uplink_item/item/tools/space_suit
+ name = "Space Suit"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/space
+
+/datum/uplink_item/item/tools/thermal
+ name = "Thermal Imaging Glasses"
+ item_cost = 3
+ path = /obj/item/clothing/glasses/thermal/syndi
+
+/datum/uplink_item/item/tools/heavy_vest
+ name = "Heavy Armor Vest"
+ item_cost = 4
+ path = /obj/item/clothing/suit/storage/vest/heavy/merc
+
+/datum/uplink_item/item/tools/powersink
+ name = "Powersink (DANGER!)"
+ item_cost = 5
+ path = /obj/item/device/powersink
+
+/datum/uplink_item/item/tools/ai_module
+ name = "Hacked AI Upload Module"
+ item_cost = 7
+ path = /obj/item/weapon/aiModule/syndicate
+
+/datum/uplink_item/item/tools/singularity_beacon
+ name = "Singularity Beacon (DANGER!)"
+ item_cost = 7
+ path = /obj/item/device/radio/beacon/syndicate
+
+/datum/uplink_item/item/tools/teleporter
+ name = "Teleporter Circuit Board"
+ item_cost = 20
+ path = /obj/item/weapon/circuitboard/teleporter
+
+/datum/uplink_item/item/tools/teleporter/New()
+ ..()
+ antag_roles = list(MODE_MERCENARY)
+
+/***********
+* Implants *
+***********/
+/datum/uplink_item/item/implants
+ category = /datum/uplink_category/implants
+
+/datum/uplink_item/item/implants/imp_freedom
+ name = "Freedom Implant"
+ item_cost = 3
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_freedom
+
+/datum/uplink_item/item/implants/imp_compress
+ name = "Compressed Matter Implant"
+ item_cost = 4
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_compress
+
+/datum/uplink_item/item/implants/imp_explosive
+ name = "Explosive Implant (DANGER!)"
+ item_cost = 6
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_explosive
+
+/datum/uplink_item/item/implants/imp_uplink
+ name = "Uplink Implant (Contains 5 Telecrystals)"
+ item_cost = 10
+ path = /obj/item/weapon/storage/box/syndie_kit/imp_uplink
+
+/**********
+* Medical *
+**********/
+/datum/uplink_item/item/medical
+ category = /datum/uplink_category/medical
+
+/datum/uplink_item/item/medical/sinpockets
+ name = "Box of Sin-Pockets"
+ item_cost = 1
+ path = /obj/item/weapon/storage/box/sinpockets
+
+/datum/uplink_item/item/medical/surgery
+ name = "Surgery kit"
+ item_cost = 6
+ path = /obj/item/weapon/storage/firstaid/surgery
+
+/datum/uplink_item/item/medical/combat
+ name = "Combat medical kit"
+ item_cost = 6
+ path = /obj/item/weapon/storage/firstaid/combat
+
+/*******************
+* Hardsuit Modules *
+*******************/
+/datum/uplink_item/item/hardsuit_modules
+ category = /datum/uplink_category/hardsuit_modules
+
+/datum/uplink_item/item/hardsuit_modules/thermal
+ name = "Thermal Scanner"
+ item_cost = 2
+ path = /obj/item/rig_module/vision/thermal
+
+/datum/uplink_item/item/hardsuit_modules/energy_net
+ name = "Net Projector"
+ item_cost = 3
+ path = /obj/item/rig_module/fabricator/energy_net
+
+/datum/uplink_item/item/ewar_voice
+ name = "Electrowarfare Suite and Voice Synthesiser"
+ item_cost = 4
+ path = /obj/item/weapon/storage/box/syndie_kit/ewar_voice
+
+/datum/uplink_item/item/hardsuit_modules/maneuvering_jets
+ name = "Maneuvering Jets"
+ item_cost = 4
+ path = /obj/item/rig_module/maneuvering_jets
+
+/datum/uplink_item/item/hardsuit_modules/egun
+ name = "Mounted Energy Gun"
+ item_cost = 6
+ path = /obj/item/rig_module/mounted/egun
+
+/datum/uplink_item/item/hardsuit_modules/power_sink
+ name = "Power Sink"
+ item_cost = 6
+ path = /obj/item/rig_module/power_sink
+
+/datum/uplink_item/item/hardsuit_modules/laser_canon
+ name = "Mounted Laser Cannon"
+ item_cost = 8
+ path = /obj/item/rig_module/mounted
+
+/************
+* Badassery *
+************/
+/datum/uplink_item/item/badassery
+ category = /datum/uplink_category/badassery
+
+/datum/uplink_item/item/badassery/balloon
+ name = "For showing that You Are The BOSS (Useless Balloon)"
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT
+ path = /obj/item/toy/syndicateballoon
+
+/datum/uplink_item/item/badassery/balloon/NT
+ name = "For showing that you love NT SOO much (Useless Balloon)"
+ path = /obj/item/toy/nanotrasenballoon
+
+/**************
+* Random Item *
+**************/
+/datum/uplink_item/item/badassery/random_one
+ name = "Random Item"
+ desc = "Buys you one random item."
+
+/datum/uplink_item/item/badassery/random_one/buy(var/obj/item/device/uplink/U, var/mob/user)
+ var/datum/uplink_item/item = default_uplink_selection.get_random_item(U.uses)
+ return item.buy(U, user)
+
+/datum/uplink_item/item/badassery/random_one/can_buy(obj/item/device/uplink/U)
+ return default_uplink_selection.get_random_item(U.uses, U) != null
+
+/datum/uplink_item/item/badassery/random_many
+ name = "Random Items"
+ desc = "Buys you as many random items you can afford. Convenient packaging NOT included."
+
+/datum/uplink_item/item/badassery/random_many/cost(var/telecrystals)
+ return max(1, telecrystals)
+
+/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc)
+ var/list/bought_items = list()
+ for(var/datum/uplink_item/UI in get_random_uplink_items(U, U.uses, loc))
+ UI.purchase_log(U)
+ var/obj/item/I = UI.get_goods(U, loc)
+ if(istype(I))
+ bought_items += I
+
+ return bought_items
+
+/datum/uplink_item/item/badassery/random_many/purchase_log(obj/item/device/uplink/U)
+ feedback_add_details("traitor_uplink_items_bought", "[src]")
+
+/****************
+* Surplus Crate *
+****************/
+/datum/uplink_item/item/badassery/surplus
+ name = "Surplus Crate"
+ item_cost = 40
+ var/item_worth = 60
+ var/icon
+
+/datum/uplink_item/item/badassery/surplus/New()
+ ..()
+ antag_roles = list(MODE_MERCENARY)
+ desc = "A crate containing [item_worth] telecrystal\s worth of surplus leftovers."
+
+/datum/uplink_item/item/badassery/surplus/get_goods(var/obj/item/device/uplink/U, var/loc)
+ var/obj/structure/largecrate/C = new(loc)
+ var/random_items = get_random_uplink_items(null, item_worth, C)
+ for(var/datum/uplink_item/I in random_items)
+ I.purchase_log(U)
+ I.get_goods(U, C)
+
+ return C
+
+/datum/uplink_item/item/badassery/surplus/log_icon()
+ if(!icon)
+ var/obj/structure/largecrate/C = /obj/structure/largecrate
+ icon = image(initial(C.icon), initial(C.icon_state))
+
+ return "\icon[icon]"
+
+/****************
+* Support procs *
+****************/
+/proc/get_random_uplink_items(var/obj/item/device/uplink/U, var/remaining_TC, var/loc)
+ var/list/bought_items = list()
+ while(remaining_TC)
+ var/datum/uplink_item/I = default_uplink_selection.get_random_item(remaining_TC, U, bought_items)
+ if(!I)
+ break
+ bought_items += I
+ remaining_TC -= I.cost(remaining_TC)
+
+ return bought_items
diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm
new file mode 100644
index 0000000000..5e843388c5
--- /dev/null
+++ b/code/game/objects/items/devices/uplink_random_lists.dm
@@ -0,0 +1,102 @@
+var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_random_selection/default()
+
+/datum/uplink_random_item
+ var/uplink_item // The uplink item
+ var/keep_probability // The probability we'll decide to keep this item if selected
+ var/reselect_probability // Probability that we'll decide to keep this item if previously selected.
+ // Is done together with the keep_probability check. Being selected more than once does not affect this probability.
+
+/datum/uplink_random_item/New(var/uplink_item, var/keep_probability = 100, var/reselect_propbability = 33)
+ ..()
+ src.uplink_item = uplink_item
+ src.keep_probability = keep_probability
+ src.reselect_probability = reselect_probability
+
+/datum/uplink_random_selection
+ var/list/datum/uplink_random_item/items
+
+/datum/uplink_random_selection/New()
+ ..()
+ items = list()
+
+/datum/uplink_random_selection/proc/get_random_item(var/telecrystals, obj/item/device/uplink/U, var/list/bought_items)
+ var/const/attempts = 50
+
+ for(var/i = 0; i < attempts; i++)
+ var/datum/uplink_random_item/RI = pick(items)
+ if(!prob(RI.keep_probability))
+ continue
+ var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
+ if(I.cost(telecrystals) > telecrystals)
+ continue
+ if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
+ continue
+ if(U && !I.can_buy(U))
+ continue
+ return I
+
+/datum/uplink_random_selection/default/New()
+ ..()
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/g9mm)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/mc9mm)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/revolver)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysniper, 15, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/emp, 50)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/soap, 5, 100)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/concealed_cane, 50, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/detomatix, 20, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/parapen)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/cigarette_kit)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/id)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/spy)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/camera_floppy, 10, 0)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_binary)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/emag, 100, 50)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/heavy_vest)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/surgery, reselect_propbability = 10)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/combat, reselect_propbability = 10)
+
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/thermal, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/energy_net, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/ewar_voice, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/maneuvering_jets, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/egun, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/power_sink, reselect_propbability = 15)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/laser_canon, reselect_propbability = 5)
+
+#ifdef DEBUG
+/proc/debug_uplink_purchage_log()
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/A = all_antag_types[antag_type]
+ A.print_player_summary()
+
+/proc/debug_uplink_item_assoc_list()
+ for(var/key in uplink.items_assoc)
+ world << "[key] - [uplink.items_assoc[key]]"
+#endif
diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/whistle.dm
index d2627ed094..0ebc4a27e1 100644
--- a/code/game/objects/items/devices/whistle.dm
+++ b/code/game/objects/items/devices/whistle.dm
@@ -47,12 +47,10 @@ obj/item/device/hailer/attack_self(mob/living/carbon/user as mob)
spawn(20)
spamcheck = 0
-/obj/item/device/hailer/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/weapon/card/emag))
- if(isnull(insults))
- user << "You overload \the [src]'s voice synthesizer."
- insults = rand(1, 3)//to prevent dickflooding
- else
- user << "The hailer is fried. You can't even fit the sequencer into the input slot."
+/obj/item/device/hailer/emag_act(var/remaining_charges, var/mob/user)
+ if(isnull(insults))
+ user << "You overload \the [src]'s voice synthesizer."
+ insults = rand(1, 3)//to prevent dickflooding
+ return 1
else
- return .. ()
+ user << "The hailer is fried. You can't even fit the sequencer into the input slot."
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index f4c03bf2bc..96ddeccec6 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -326,12 +326,10 @@
user << "You insert the flash into the eye socket!"
-/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob)
- if(istype(W,/obj/item/weapon/card/emag))
- if(sabotaged)
- user << "[src] is already sabotaged!"
- else
- user << "You slide [W] into the dataport on [src] and short out the safeties."
- sabotaged = 1
- return
- ..()
+/obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user)
+ if(sabotaged)
+ user << "[src] is already sabotaged!"
+ else
+ user << "You short out the safeties."
+ sabotaged = 1
+ return 1
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 10f445b769..3b1e18f851 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -61,7 +61,7 @@
else if(O.reagents.total_volume >= 1)
if(O.reagents.has_reagent("pacid", 1))
user << "The acid chews through the balloon!"
- O.reagents.splash_mob(user, reagents.total_volume)
+ O.reagents.splash(user, reagents.total_volume)
qdel(src)
else
src.desc = "A translucent balloon with some form of liquid sloshing around in it."
@@ -314,6 +314,7 @@
icon = 'icons/obj/toy.dmi'
icon_state = "foamdart"
w_class = 1.0
+ slot_flags = SLOT_EARS
/obj/effect/foam_dart_dummy
name = ""
@@ -398,7 +399,7 @@
if((ishuman(H))) //i guess carp and shit shouldn't set them off
var/mob/living/carbon/M = H
if(M.m_intent == "run")
- M << "You step on the snap pop!"
+ M << "You step on the snap pop!"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 0, src)
@@ -486,6 +487,8 @@
icon = 'icons/obj/toy.dmi'
icon_state = "bosunwhistle"
var/cooldown = 0
+ w_class = 1
+ slot_flags = SLOT_EARS
/obj/item/toy/bosunwhistle/attack_self(mob/user as mob)
if(cooldown < world.time - 35)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 3c2b02feed..9afe2e83e4 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -69,59 +69,24 @@
item_state = "card-id"
origin_tech = list(TECH_MAGNET = 2, TECH_ILLEGAL = 2)
var/uses = 10
- // List of devices that cost a use to emag.
- var/list/devices = list(
- /obj/item/robot_parts,
- /obj/item/weapon/storage/lockbox,
- /obj/item/weapon/storage/secure,
- /obj/item/weapon/circuitboard,
- /obj/item/weapon/rig,
- /obj/item/device/eftpos,
- /obj/item/device/lightreplacer,
- /obj/item/device/taperecorder,
- /obj/item/device/hailer,
- /obj/item/device/megaphone,
- /obj/item/clothing/accessory/badge/holo,
- /obj/structure/closet/crate/secure,
- /obj/structure/closet/secure_closet,
- /obj/machinery/librarycomp,
- /obj/machinery/computer,
- /obj/machinery/power,
- /obj/machinery/suspension_gen,
- /obj/machinery/shield_capacitor,
- /obj/machinery/shield_gen,
- /obj/machinery/clonepod,
- /obj/machinery/deployable,
- /obj/machinery/button/remote,
- /obj/machinery/porta_turret,
- /obj/machinery/shieldgen,
- /obj/machinery/turretid,
- /obj/machinery/vending,
- /mob/living/bot,
- /obj/machinery/door,
- /obj/machinery/telecomms,
- /obj/machinery/mecha_part_fabricator,
- /obj/machinery/gibber,
- /obj/vehicle
- )
+/obj/item/weapon/card/emag/resolve_attackby(atom/A, mob/user)
+ var/used_uses = A.emag_act(uses, user)
+ if(used_uses < 0)
+ return ..(A, user)
-/obj/item/weapon/card/emag/afterattack(var/obj/item/weapon/O as obj, mob/user as mob)
-
- for(var/type in devices)
- if(istype(O,type))
- uses--
- break
+ uses -= used_uses
+ A.add_fingerprint(user)
+ log_and_message_admins("emagged \an [A].")
if(uses<1)
- user.visible_message("[src] fizzles and sparks - it seems it's been used once too often, and is now broken.")
+ user.visible_message("\The [src] fizzles and sparks - it seems it's been used once too often, and is now spent.")
user.drop_item()
var/obj/item/weapon/card/emag_broken/junk = new(user.loc)
junk.add_fingerprint(user)
qdel(src)
- return
- ..()
+ return 1
/obj/item/weapon/card/id
name = "identification card"
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index a9ca4b8dc0..c11720d1e8 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -39,6 +39,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
var/smoketime = 5
w_class = 1.0
origin_tech = list(TECH_MATERIAL = 1)
+ slot_flags = SLOT_EARS
attack_verb = list("burnt", "singed")
/obj/item/weapon/flame/match/process()
@@ -55,8 +56,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM
return
/obj/item/weapon/flame/match/dropped(mob/user as mob)
+ //If dropped, put ourselves out
+ //not before lighting up the turf we land on, though.
if(lit)
- burn_out()
+ spawn(0)
+ var/turf/location = src.loc
+ if(istype(location))
+ location.hotspot_expose(700, 5)
+ burn_out()
return ..()
/obj/item/weapon/flame/match/proc/burn_out()
@@ -199,6 +206,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
throw_speed = 0.5
item_state = "cigoff"
w_class = 1
+ slot_flags = SLOT_EARS
attack_verb = list("burnt", "singed")
icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi
icon_off = "cigoff"
@@ -283,6 +291,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "cigbutt"
w_class = 1
+ slot_flags = SLOT_EARS
throwforce = 1
/obj/item/weapon/cigbutt/New()
@@ -457,9 +466,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "[base_state]"
item_state = "[base_state]"
if(istype(src, /obj/item/weapon/flame/lighter/zippo) )
- user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what they're doing.")
+ user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what they're doing.")
else
- user.visible_message("[user] quietly shuts off the [src].")
+ user.visible_message("[user] quietly shuts off the [src].")
set_light(0)
processing_objects.Remove(src)
diff --git a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm
index 56fbf2bff2..ef6b4c4d57 100644
--- a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm
+++ b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm
@@ -36,16 +36,18 @@
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
if (..(C))
network = C.network
+
+/obj/item/weapon/circuitboard/security/emag_act(var/remaining_charges, var/mob/user)
+ if(emagged)
+ user << "Circuit lock is already removed."
+ return
+ user << "You override the circuit lock and open controls."
+ emagged = 1
+ locked = 0
+ return 1
/obj/item/weapon/circuitboard/security/attackby(obj/item/I as obj, mob/user as mob)
- if(istype(I,/obj/item/weapon/card/emag))
- if(emagged)
- user << "Circuit lock is already removed."
- return
- user << "You override the circuit lock and open controls."
- emagged = 1
- locked = 0
- else if(istype(I,/obj/item/weapon/card/id))
+ if(istype(I,/obj/item/weapon/card/id))
if(emagged)
user << "Circuit lock does not respond."
return
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index 29c3f64820..218d2fb21c 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -5,6 +5,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "lipstick"
w_class = 1.0
+ slot_flags = SLOT_EARS
var/colour = "red"
var/open = 0
@@ -71,6 +72,7 @@
name = "purple comb"
desc = "A pristine purple comb made from flexible plastic."
w_class = 1.0
+ slot_flags = SLOT_EARS
icon = 'icons/obj/items.dmi'
icon_state = "purplecomb"
item_state = "purplecomb"
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index b94fd2d360..7c685a9e1d 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -9,6 +9,7 @@
throw_speed = 1
throw_range = 5
w_class = 1.0
+ slot_flags = SLOT_EARS
var/uses = 1
var/nofail
var/is_bullet = 0
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index 4eec1009e5..aa7f6df8e4 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -15,8 +15,8 @@
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
var/spray_particles = 6
- var/spray_amount = 2 //units of liquid per particle
- var/max_water = 120
+ var/spray_amount = 8 //units of liquid per particle
+ var/max_water = 240
var/last_use = 1.0
var/safety = 1
var/sprite_name = "fire_extinguisher"
@@ -30,7 +30,8 @@
throwforce = 2
w_class = 2.0
force = 3.0
- max_water = 60
+ max_water = 120
+ spray_particles = 5
sprite_name = "miniFE"
/obj/item/weapon/extinguisher/New()
@@ -49,6 +50,24 @@
user << "The safety is [safety ? "on" : "off"]."
return
+/obj/item/weapon/extinguisher/proc/propel_object(var/obj/O, mob/user, movementdirection)
+ if(O.anchored) return
+
+ var/obj/structure/bed/chair/C
+ if(istype(O, /obj/structure/bed/chair))
+ C = O
+
+ var/list/move_speed = list(1, 1, 1, 2, 2, 3)
+ for(var/i in 1 to 6)
+ if(C) C.propelled = (6-i)
+ O.Move(get_step(user,movementdirection), movementdirection)
+ sleep(move_speed[i])
+
+ //additional movement
+ for(var/i in 1 to 3)
+ O.Move(get_step(user,movementdirection), movementdirection)
+ sleep(3)
+
/obj/item/weapon/extinguisher/afterattack(var/atom/target, var/mob/user, var/flag)
//TODO; Add support for reagents in water.
@@ -73,35 +92,9 @@
var/direction = get_dir(src,target)
- if(user.buckled && isobj(user.buckled) && !user.buckled.anchored )
+ if(user.buckled && isobj(user.buckled))
spawn(0)
- var/obj/structure/bed/chair/C = null
- if(istype(user.buckled, /obj/structure/bed/chair))
- C = user.buckled
- var/obj/B = user.buckled
- var/movementdirection = turn(direction,180)
- if(C) C.propelled = 4
- B.Move(get_step(user,movementdirection), movementdirection)
- sleep(1)
- B.Move(get_step(user,movementdirection), movementdirection)
- if(C) C.propelled = 3
- sleep(1)
- B.Move(get_step(user,movementdirection), movementdirection)
- sleep(1)
- B.Move(get_step(user,movementdirection), movementdirection)
- if(C) C.propelled = 2
- sleep(2)
- B.Move(get_step(user,movementdirection), movementdirection)
- if(C) C.propelled = 1
- sleep(2)
- B.Move(get_step(user,movementdirection), movementdirection)
- if(C) C.propelled = 0
- sleep(3)
- B.Move(get_step(user,movementdirection), movementdirection)
- sleep(3)
- B.Move(get_step(user,movementdirection), movementdirection)
- sleep(3)
- B.Move(get_step(user,movementdirection), movementdirection)
+ propel_object(user.buckled, user, turn(direction,180))
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
@@ -111,19 +104,15 @@
for(var/a = 1 to spray_particles)
spawn(0)
+ if(!src || !reagents.total_volume) return
+
var/obj/effect/effect/water/W = PoolOrNew(/obj/effect/effect/water, get_turf(src))
var/turf/my_target
- if(a == 1)
- my_target = T
- else if(a == 2)
- my_target = T1
- else if(a == 3)
- my_target = T2
+ if(a <= the_targets.len)
+ my_target = the_targets[a]
else
my_target = pick(the_targets)
W.create_reagents(spray_amount)
- if(!src)
- return
reagents.trans_to_obj(W, spray_amount)
W.set_color()
W.set_up(my_target)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 56236a754f..95e1875d40 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -5,6 +5,7 @@
desc = "A hand made chemical grenade."
w_class = 2.0
force = 2.0
+ det_time = null
var/stage = 0
var/state = 0
var/path = 0
@@ -25,6 +26,7 @@
detonator.detached()
usr.put_in_hands(detonator)
detonator=null
+ det_time = null
stage=0
icon_state = initial(icon_state)
else if(beakers.len)
@@ -60,6 +62,12 @@
user.remove_from_mob(det)
det.loc = src
detonator = det
+ if(istimer(detonator.a_left))
+ var/obj/item/device/assembly/timer/T = detonator.a_left
+ det_time = 10*T.time
+ if(istimer(detonator.a_right))
+ var/obj/item/device/assembly/timer/T = detonator.a_right
+ det_time = 10*T.time
icon_state = initial(icon_state) +"_ass"
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
stage = 1
@@ -70,7 +78,7 @@
user << "You lock the assembly."
name = "grenade"
else
-// user << "You need to add at least one beaker before locking the assembly."
+// user << "You need to add at least one beaker before locking the assembly."
user << "You lock the empty assembly."
name = "fake grenade"
playsound(src.loc, 'sound/items/Screwdriver.ogg', 25, -3)
@@ -142,6 +150,13 @@
if(!has_reagents)
icon_state = initial(icon_state) +"_locked"
playsound(src.loc, 'sound/items/Screwdriver2.ogg', 50, 1)
+ spawn(0) //Otherwise det_time is erroneously set to 0 after this
+ if(istimer(detonator.a_left)) //Make sure description reflects that the timer has been reset
+ var/obj/item/device/assembly/timer/T = detonator.a_left
+ det_time = 10*T.time
+ if(istimer(detonator.a_right))
+ var/obj/item/device/assembly/timer/T = detonator.a_right
+ det_time = 10*T.time
return
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index f501753807..1565d321b6 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -47,6 +47,8 @@
if(det_time > 1)
user << "The timer is set to [det_time/10] seconds."
return
+ if(det_time == null)
+ return
user << "\The [src] is set for instant detonation."
@@ -89,16 +91,16 @@
/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(isscrewdriver(W))
switch(det_time)
- if ("1")
+ if (1)
det_time = 10
user << "You set the [name] for 1 second detonation time."
- if ("10")
+ if (10)
det_time = 30
user << "You set the [name] for 3 second detonation time."
- if ("30")
+ if (30)
det_time = 50
user << "You set the [name] for 5 second detonation time."
- if ("50")
+ if (50)
det_time = 1
user << "You set the [name] for instant detonation."
add_fingerprint(user)
diff --git a/code/game/objects/items/weapons/material/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm
index 033042b853..d5e7cd67bb 100644
--- a/code/game/objects/items/weapons/material/ashtray.dm
+++ b/code/game/objects/items/weapons/material/ashtray.dm
@@ -62,8 +62,8 @@ var/global/list/ashtray_cache = list()
cig.transfer_fingerprints_to(butt)
qdel(cig)
W = butt
- spawn(1)
- TemperatureAct(150)
+ //spawn(1)
+ // TemperatureAct(150)
else if (cig.lit == 0)
user << "You place [cig] in [src] without even smoking it. Why would you do that?"
diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm
index fe33163dba..c396f8d4b9 100644
--- a/code/game/objects/items/weapons/material/material_weapons.dm
+++ b/code/game/objects/items/weapons/material/material_weapons.dm
@@ -17,12 +17,22 @@
var/thrown_force_divisor = 0.5
var/default_material = DEFAULT_WALL_MATERIAL
var/material/material
+ var/drops_debris = 1
/obj/item/weapon/material/New(var/newloc, var/material_key)
..(newloc)
if(!material_key)
material_key = default_material
set_material(material_key)
+ if(!material)
+ qdel(src)
+ return
+
+ matter = material.get_matter()
+ if(matter.len)
+ for(var/material_type in matter)
+ if(!isnull(matter[material_type]))
+ matter[material_type] *= force_divisor // May require a new var instead.
/obj/item/weapon/material/proc/update_force()
if(edge || sharp)
@@ -61,33 +71,37 @@
health--
check_health()
-/obj/item/weapon/material/proc/check_health()
+/obj/item/weapon/material/proc/check_health(var/consumed)
if(health<=0)
- shatter()
+ shatter(consumed)
-/obj/item/weapon/material/proc/shatter()
+/obj/item/weapon/material/proc/shatter(var/consumed)
var/turf/T = get_turf(src)
T.visible_message("\The [src] [material.destruction_desc]!")
if(istype(loc, /mob/living))
var/mob/living/M = loc
M.drop_from_inventory(src)
playsound(src, "shatter", 70, 1)
- material.place_shard(T)
+ if(!consumed && drops_debris) material.place_shard(T)
qdel(src)
-
+/*
+Commenting this out pending rebalancing of radiation based on small objects.
/obj/item/weapon/material/process()
if(!material.radioactivity)
return
for(var/mob/living/L in range(1,src))
- L.apply_effect(round(material.radioactivity/3),IRRADIATE,0)
+ L.apply_effect(round(material.radioactivity/30),IRRADIATE,0)
+*/
+/*
+// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately.
/obj/item/weapon/material/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
TemperatureAct(exposed_temperature)
// This might need adjustment. Will work that out later.
/obj/item/weapon/material/proc/TemperatureAct(temperature)
health -= material.combustion_effect(get_turf(src), temperature, 0.1)
- check_health()
+ check_health(1)
/obj/item/weapon/material/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/weldingtool))
@@ -95,4 +109,5 @@
if(material.ignition_point && WT.remove_fuel(0, user))
TemperatureAct(150)
else
- return ..()
\ No newline at end of file
+ return ..()
+*/
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index 2bb0f91e2f..c2ff0401ff 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -14,6 +14,7 @@
attack_verb = list("stabbed", "slashed", "sliced", "cut")
default_material = "glass"
unbreakable = 1 //It's already broken.
+ drops_debris = 0
/obj/item/weapon/material/shard/suicide_act(mob/user)
viewers(user) << pick("\The [user] is slitting \his wrists with \the [src]! It looks like \he's trying to commit suicide.",
diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm
index 05709898d6..8cc8ee5cfa 100644
--- a/code/game/objects/items/weapons/scrolls.dm
+++ b/code/game/objects/items/weapons/scrolls.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll"
var/uses = 4.0
- w_class = 2.0
+ w_class = 1
item_state = "paper"
throw_speed = 4
throw_range = 20
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index f42685b792..e4df419e18 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -214,8 +214,10 @@
name = "captain's satchel"
desc = "An exclusive satchel for Nanotrasen officers."
icon_state = "satchel-cap"
- item_state = "captainpack"
- item_state_slots = null
+ item_state_slots = list(
+ slot_l_hand_str = "satchel-cap",
+ slot_r_hand_str = "satchel-cap",
+ )
//ERT backpacks.
/obj/item/weapon/storage/backpack/ert
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index b5466f7a39..297ac1d4b1 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -34,23 +34,13 @@
return
else
user << "Access Denied"
- else if((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken)
- broken = 1
- locked = 0
- desc = "It appears to be broken."
- icon_state = src.icon_broken
- if(istype(W, /obj/item/weapon/melee/energy/blade))
+ else if(istype(W, /obj/item/weapon/melee/energy/blade))
+ if(emag_act(INFINITY, user, "The locker has been sliced open by [user] with an energy blade!", "You hear metal being sliced and sparks flying."))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src.loc, "sparks", 50, 1)
- for(var/mob/O in viewers(user, 3))
- O.show_message(text("The locker has been sliced open by [] with an energy blade!", user), 1, text("You hear metal being sliced and sparks flying."), 2)
- else
- for(var/mob/O in viewers(user, 3))
- O.show_message(text("The locker has been broken by [] with an electromagnetic card!", user), 1, text("You hear a faint electrical spark."), 2)
-
if(!locked)
..()
else
@@ -65,6 +55,23 @@
..()
return
+/obj/item/weapon/storage/lockbox/emag_act(var/remaining_charges, var/mob/user, var/visual_feedback = "", var/audible_feedback = "")
+ if(!broken)
+ if(visual_feedback)
+ visual_feedback = "[visual_feedback]"
+ else
+ visual_feedback = "The locker has been sliced open by [user] with an electromagnetic card!"
+ if(audible_feedback)
+ audible_feedback = "[audible_feedback]"
+ else
+ audible_feedback = "You hear a faint electrical spark."
+
+ broken = 1
+ locked = 0
+ desc = "It appears to be broken."
+ icon_state = src.icon_broken
+ visible_message(visual_feedback, audible_feedback)
+ return 1
/obj/item/weapon/storage/lockbox/loyalty
name = "lockbox of loyalty implants"
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index ef5d8db334..ebd76a64a5 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -33,22 +33,12 @@
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(locked)
- if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (!src.emagged))
- emagged = 1
- src.overlays += image('icons/obj/storage.dmi', icon_sparking)
- sleep(6)
- src.overlays = null
- overlays += image('icons/obj/storage.dmi', icon_locking)
- locked = 0
- if(istype(W, /obj/item/weapon/melee/energy/blade))
- var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
- spark_system.set_up(5, 0, src.loc)
- spark_system.start()
- playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
- playsound(src.loc, "sparks", 50, 1)
- user << "You slice through the lock on [src]."
- else
- user << "You short out the lock on [src]."
+ if (emag_act(INFINITY, user, "You slice through the lock of \the [src]"))
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, src.loc)
+ spark_system.start()
+ playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(src.loc, "sparks", 50, 1)
return
if (istype(W, /obj/item/weapon/screwdriver))
@@ -136,6 +126,17 @@
return
return
+/obj/item/weapon/storage/secure/emag_act(var/remaining_charges, var/mob/user, var/feedback)
+ if(!emagged)
+ emagged = 1
+ src.overlays += image('icons/obj/storage.dmi', icon_sparking)
+ sleep(6)
+ src.overlays = null
+ overlays += image('icons/obj/storage.dmi', icon_locking)
+ locked = 0
+ user << (feedback ? feedback : "You short out the lock of \the [src].")
+ return 1
+
// -----------------------------
// Secure Briefcase
// -----------------------------
@@ -157,7 +158,7 @@
attack_hand(mob/user as mob)
if ((src.loc == user) && (src.locked == 1))
- usr << "[src] is locked and cannot be opened!"
+ usr << "[src] is locked and cannot be opened!"
else if ((src.loc == user) && (!src.locked))
src.open(usr)
else
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index b33d72f6fb..6b3fdd04ae 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -139,8 +139,7 @@
new /obj/item/clothing/gloves/chameleon(src)
new /obj/item/clothing/mask/chameleon(src)
new /obj/item/clothing/glasses/chameleon(src)
- new /obj/item/weapon/gun/projectile/chameleon(src)
- new /obj/item/ammo_magazine/chameleon(src)
+ new /obj/item/weapon/gun/energy/chameleon(src)
/obj/item/weapon/storage/box/syndie_kit/clerical
name = "clerical kit"
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index cc54970009..39eb9fb25f 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -100,7 +100,7 @@
/obj/item/weapon/melee/baton/attack(mob/M, mob/user)
if(status && (CLUMSY in user.mutations) && prob(50))
- user << "span class='danger'>You accidentally hit yourself with the [src]!"
+ user << "You accidentally hit yourself with the [src]!"
user.Weaken(30)
deductcharge(hitcost)
return
@@ -130,7 +130,7 @@
target_zone = get_zone_with_miss_chance(user.zone_sel.selecting, L)
if(!target_zone)
- L.visible_message(">span class='danger'>\The [user] misses [L] with \the [src]!")
+ L.visible_message("\The [user] misses [L] with \the [src]!")
return 0
var/mob/living/carbon/human/H = L
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 0eecde46a5..7e96ad2c08 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -83,6 +83,7 @@
sharp = 1
edge = 1
w_class = 1
+ slot_flags = SLOT_EARS
throwforce = 5.0
throw_speed = 3
throw_range = 5
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 86effc923c..8c5b1de026 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -268,19 +268,22 @@
if(!istype(src.loc,/obj/item/device/transfer_valve))
message_admins("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].")
log_game("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].")
- //world << "[x],[y] tank is exploding: [pressure] kPa"
+
//Give the gas a chance to build up more pressure through reacting
air_contents.react()
air_contents.react()
air_contents.react()
+
pressure = air_contents.return_pressure()
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
- range = min(range, max_explosion_range) // was 8 - - - Changed to a configurable define -- TLE
- var/turf/epicenter = get_turf(loc)
- //world << "Exploding Pressure: [pressure] kPa, intensity: [range]"
-
- explosion(epicenter, round(range*0.25), round(range*0.5), round(range), round(range*1.5))
+ explosion(
+ get_turf(loc),
+ round(min(BOMBCAP_DVSTN_RADIUS, range*0.25)),
+ round(min(BOMBCAP_HEAVY_RADIUS, range*0.50)),
+ round(min(BOMBCAP_LIGHT_RADIUS, range*1.00)),
+ round(min(BOMBCAP_FLASH_RADIUS, range*1.50)),
+ )
qdel(src)
else if(pressure > TANK_RUPTURE_PRESSURE)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index d51a9a1e3b..7bd266f241 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -38,7 +38,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "screwdriver"
flags = CONDUCT
- slot_flags = SLOT_BELT
+ slot_flags = SLOT_BELT | SLOT_EARS
force = 5.0
w_class = 1.0
throwforce = 5.0
@@ -262,6 +262,8 @@
//Removes fuel from the welding tool. If a mob is passed, it will perform an eyecheck on the mob. This should probably be renamed to use()
/obj/item/weapon/weldingtool/proc/remove_fuel(var/amount = 1, var/mob/M = null)
+ if(!welding)
+ return 0
if(get_fuel() >= amount)
reagents.remove_reagent("fuel", amount)
if(M)
@@ -292,7 +294,7 @@
var/turf/T = get_turf(src)
//If we're turning it on
if(set_welding && !welding)
- if (remove_fuel(1))
+ if (get_fuel() > 0)
if(M)
M << "You switch the [src] on."
else if(T)
diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index f6af73843c..d62b89f3fa 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -20,20 +20,20 @@
/obj/item/weapon/beartrap/attack_self(mob/user as mob)
..()
- if(deployed && can_use(user))
+ if(!deployed && can_use(user))
user.visible_message(
- "[user] starts to deploy \the [src].",
- "You begin deploying \the [src]!",
+ "[user] starts to deploy \the [src].",
+ "You begin deploying \the [src]!",
"You hear the slow creaking of a spring."
)
-
+
if (do_after(user, 60))
user.visible_message(
- "[user] has deployed \the [src].",
+ "[user] has deployed \the [src].",
"You have deployed \the [src]!",
"You hear a latch click loudly."
)
-
+
deployed = 1
user.drop_from_inventory(src)
update_icon()
@@ -42,7 +42,7 @@
/obj/item/weapon/beartrap/attack_hand(mob/user as mob)
if(buckled_mob && can_use(user))
user.visible_message(
- "[user] begins freeing [buckled_mob] from \the [src].",
+ "[user] begins freeing [buckled_mob] from \the [src].",
"You carefully begin to free [buckled_mob] from \the [src].",
)
if(do_after(user, 60))
@@ -51,13 +51,13 @@
anchored = 0
else if(deployed && can_use(user))
user.visible_message(
- "[user] starts to disarm \the [src].",
+ "[user] starts to disarm \the [src].",
"You begin disarming \the [src]!",
"You hear a latch click followed by the slow creaking of a spring."
)
if(do_after(user, 60))
user.visible_message(
- "[user] has disarmed \the [src].",
+ "[user] has disarmed \the [src].",
"You have disarmed \the [src]!"
)
deployed = 0
@@ -86,15 +86,18 @@
//trap the victim in place
if(!blocked)
set_dir(L.dir)
+ can_buckle = 1
buckle_mob(L)
L << "The steel jaws of \the [src] bite into you, trapping you in place!"
+ deployed = 0
+ can_buckle = initial(can_buckle)
/obj/item/weapon/beartrap/Crossed(AM as mob|obj)
- if(isliving(AM))
+ if(deployed && isliving(AM))
var/mob/living/L = AM
if(L.m_intent == "run")
L.visible_message(
- "[L] steps on \the [src].",
+ "[L] steps on \the [src].",
"You step on \the [src]!",
"You hear a loud metallic snap!"
)
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 867c5155e0..e9670ce4d7 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -217,10 +217,6 @@
health = 0
healthcheck()
-/obj/effect/energy_net/meteorhit()
- health = 0
- healthcheck()
-
/obj/effect/energy_net/attack_hand(var/mob/user)
var/mob/living/carbon/human/H = user
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 8039814f4f..1f25043e89 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -32,9 +32,6 @@
if(prob(50))
qdel(src)
-/obj/structure/meteorhit(obj/O as obj)
- qdel(src)
-
/obj/structure/attack_tk()
return
@@ -50,9 +47,6 @@
if(3.0)
return
-/obj/structure/meteorhit(obj/O as obj)
- qdel(src)
-
/obj/structure/New()
..()
if(climbable)
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index e66d5c488a..68aeecd912 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -210,13 +210,6 @@
A.loc = src.loc
qdel(src)
-/obj/structure/closet/meteorhit(obj/O as obj)
- if(O.icon_state == "flaming")
- for(var/mob/M in src)
- M.meteorhit(O)
- src.dump_contents()
- qdel(src)
-
/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(src.opened)
if(istype(W, /obj/item/weapon/grab))
@@ -227,8 +220,11 @@
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(!WT.remove_fuel(0,user))
- user << "You need more welding fuel to complete this task."
- return
+ if(!WT.isOn())
+ return
+ else
+ user << "You need more welding fuel to complete this task."
+ return
new /obj/item/stack/material/steel(src.loc)
for(var/mob/M in viewers(src))
M.show_message("\The [src] has been cut apart by [user] with \the [WT].", 3, "You hear welding.", 2)
@@ -246,8 +242,11 @@
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(!WT.remove_fuel(0,user))
- user << "You need more welding fuel to complete this task."
- return
+ if(!WT.isOn())
+ return
+ else
+ user << "You need more welding fuel to complete this task."
+ return
src.welded = !src.welded
src.update_icon()
for(var/mob/M in viewers(src))
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
index 66609f5661..c732faeeea 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
@@ -83,22 +83,26 @@
src.desc = "Owned by [I.registered_name]."
else
user << "Access Denied"
- else if( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken)
- broken = 1
- locked = 0
- desc = "It appears to be broken."
- icon_state = src.icon_broken
- if(istype(W, /obj/item/weapon/melee/energy/blade))
+ else if(istype(W, /obj/item/weapon/melee/energy/blade))
+ if(emag_act(INFINITY, user, "The locker has been sliced open by [user] with \an [W]!", "You hear metal being sliced and sparks flying."))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src.loc, "sparks", 50, 1)
- for(var/mob/O in viewers(user, 3))
- O.show_message("The locker has been sliced open by [user] with an energy blade!", 1, "You hear metal being sliced and sparks flying.", 2)
else
user << "Access Denied"
return
+
+/obj/structure/closet/secure_closet/personal/emag_act(var/remaining_charges, var/mob/user, var/visual_feedback, var/audible_feedback)
+ if(!broken)
+ broken = 1
+ locked = 0
+ desc = "It appears to be broken."
+ icon_state = src.icon_broken
+ if(visual_feedback)
+ visible_message("[visual_feedback]", "[audible_feedback]")
+ return 1
/obj/structure/closet/secure_closet/personal/verb/reset()
set src in oview(1) // One square distance
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index 55cd3b51ca..3bc5dfc393 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -78,28 +78,31 @@
user.drop_item()
if(W)
W.loc = src.loc
- else if((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken)
- broken = 1
- locked = 0
- desc = "It appears to be broken."
- icon_state = icon_off
- flick(icon_broken, src)
- if(istype(W, /obj/item/weapon/melee/energy/blade))
+ else if(istype(W, /obj/item/weapon/melee/energy/blade))
+ if(emag_act(INFINITY, user, "The locker has been sliced open by [user] with \an [W]!", "You hear metal being sliced and sparks flying."))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src.loc, "sparks", 50, 1)
- for(var/mob/O in viewers(user, 3))
- O.show_message("The locker has been sliced open by [user] with an energy blade!", 1, "You hear metal being sliced and sparks flying.", 2)
- else
- for(var/mob/O in viewers(user, 3))
- O.show_message("The locker has been broken by [user] with an electromagnetic card!", 1, "You hear a faint electrical spark.", 2)
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
return ..(W,user)
else
togglelock(user)
+/obj/structure/closet/secure_closet/attack_hand(var/remaining_charges, var/mob/user, var/visual_feedback, var/audible_feedback)
+ if(!broken)
+ broken = 1
+ locked = 0
+ desc = "It appears to be broken."
+ icon_state = icon_off
+ flick(icon_broken, src)
+
+ if(visual_feedback)
+ visible_message(visual_feedback, audible_feedback)
+ else
+ visible_message("The locker has been broken by [user] with an electromagnetic card!", "You hear a faint electrical spark.")
+
/obj/structure/closet/secure_closet/attack_hand(mob/user as mob)
src.add_fingerprint(user)
if(src.locked)
diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm
index b59cd62dfa..5458f3da94 100644
--- a/code/game/objects/structures/crates_lockers/closets/statue.dm
+++ b/code/game/objects/structures/crates_lockers/closets/statue.dm
@@ -80,12 +80,15 @@
/obj/structure/closet/statue/toggle()
return
-/obj/structure/closet/statue/bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
+/obj/structure/closet/statue/proc/check_health()
if(health <= 0)
for(var/mob/M in src)
shatter(M)
+/obj/structure/closet/statue/bullet_act(var/obj/item/projectile/Proj)
+ health -= Proj.damage
+ check_health()
+
return
/obj/structure/closet/statue/attack_generic(var/mob/user, damage, attacktext, environment_smash)
@@ -97,19 +100,17 @@
for(var/mob/M in src)
shatter(M)
-/obj/structure/closet/statue/meteorhit(obj/O as obj)
- if(O.icon_state == "flaming")
- for(var/mob/M in src)
- M.meteorhit(O)
- shatter(M)
+/obj/structure/closet/statue/ex_act(severity)
+ for(var/mob/M in src)
+ M.ex_act(severity)
+ health -= 60 / severity
+ check_health()
/obj/structure/closet/statue/attackby(obj/item/I as obj, mob/user as mob)
health -= I.force
user.do_attack_animation(src)
visible_message("[user] strikes [src] with [I].")
- if(health <= 0)
- for(var/mob/M in src)
- shatter(M)
+ check_health()
/obj/structure/closet/statue/MouseDrop_T()
return
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index ad28bb4019..2e76ad3c88 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -187,7 +187,15 @@
/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters)))
return ..()
- if(locked && (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)))
+ if(istype(W, /obj/item/weapon/melee/energy/blade))
+ emag_act(INFINITY, user)
+ if(!opened)
+ src.togglelock(user)
+ return
+ return ..()
+
+/obj/structure/closet/crate/secure/emag_act(var/remaining_charges, var/mob/user)
+ if(!broken)
overlays.Cut()
overlays += emag
overlays += sparks
@@ -196,11 +204,7 @@
src.locked = 0
src.broken = 1
user << "You unlock \the [src]."
- return
- if(!opened)
- src.togglelock(user)
- return
- return ..()
+ return 1
/obj/structure/closet/crate/secure/emp_act(severity)
for(var/obj/O in src)
diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm
index 54a9fc8092..c697f1a4c1 100644
--- a/code/game/objects/structures/crates_lockers/largecrate.dm
+++ b/code/game/objects/structures/crates_lockers/largecrate.dm
@@ -13,8 +13,8 @@
if(istype(W, /obj/item/weapon/crowbar))
new /obj/item/stack/material/wood(src)
var/turf/T = get_turf(src)
- for(var/obj/O in contents)
- O.loc = T
+ for(var/atom/movable/AM in contents)
+ if(AM.simulated) AM.loc = T
user.visible_message("[user] pries \the [src] open.", \
"You pry open \the [src].", \
"You hear splitting wood.")
@@ -73,4 +73,4 @@
/obj/structure/largecrate/animal/chick
name = "chicken crate"
held_count = 5
- held_type = /mob/living/simple_animal/chick
\ No newline at end of file
+ held_type = /mob/living/simple_animal/chick
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 3c5d5ec849..bc6217f774 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -43,13 +43,6 @@
occupied = 0
qdel(src)
-
-/obj/structure/displaycase/meteorhit(obj/O as obj)
- new /obj/item/weapon/material/shard( src.loc )
- new /obj/item/weapon/gun/energy/captain( src.loc )
- qdel(src)
-
-
/obj/structure/displaycase/proc/healthcheck()
if (src.health <= 0)
if (!( src.destroyed ))
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index 872b8ff988..c8ccd4b32b 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -37,7 +37,7 @@
if (user.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
- user << "You try to move your [temp.name], but cannot!"
+ user << "You try to move your [temp.name], but cannot!"
return
if(has_extinguisher)
user.put_in_hands(has_extinguisher)
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 38caaa3230..d217b10197 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -149,7 +149,7 @@
if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
user.drop_item()
P.loc = src.loc
- user << "You fit the pipe into the [src]!"
+ user << "You fit the pipe into the [src]!"
else
..()
@@ -248,7 +248,7 @@
dismantle()
else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
- user << "Now slicing apart the girder..."
+ user << "Now slicing apart the girder..."
if(do_after(user,30))
user << "You slice apart the girder!"
dismantle()
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index fa7a448bd6..331529b87d 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -19,9 +19,6 @@
/obj/structure/grille/blob_act()
qdel(src)
-/obj/structure/grille/meteorhit(var/obj/M)
- qdel(src)
-
/obj/structure/grille/update_icon()
if(destroyed)
icon_state = "[initial(icon_state)]-b"
@@ -114,9 +111,12 @@
"You have [anchored ? "fastened the grille to" : "unfastened the grill from"] the floor.")
return
-//window placing begin
- else if(istype(W,/obj/item/stack/material/glass))
- var/obj/item/stack/material/glass/ST = W
+//window placing begin //TODO CONVERT PROPERLY TO MATERIAL DATUM
+ else if(istype(W,/obj/item/stack/material))
+ var/obj/item/stack/material/ST = W
+ if(!ST.material.created_window)
+ return 0
+
var/dir_to_set = 1
if(loc == user.loc)
dir_to_set = user.dir
@@ -146,7 +146,7 @@
user << "There is already a window facing this way there."
return
- var/wtype = ST.created_window
+ var/wtype = ST.material.created_window
if (ST.use(1))
var/obj/structure/window/WD = new wtype(loc, dir_to_set, 1)
user << "You place the [WD] on [src]."
@@ -154,9 +154,7 @@
return
//window placing end
- else if(istype(W, /obj/item/weapon/material/shard))
- health -= W.force * 0.1
- else if(!shock(user, 70))
+ else if(!(W.flags & CONDUCT) || !shock(user, 70))
user.do_attack_animation(src)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
switch(W.damtype)
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index cd8fad5ec5..f31b098b5b 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -63,9 +63,6 @@
/obj/structure/inflatable/blob_act()
deflate(1)
-/obj/structure/inflatable/meteorhit()
- deflate(1)
-
/obj/structure/inflatable/attack_hand(mob/user as mob)
add_fingerprint(user)
return
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index 237250e3fd..cac56d23b9 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -37,7 +37,7 @@
else if(istype(I, /obj/item/weapon/mop))
if(I.reagents.total_volume < I.reagents.maximum_volume) //if it's not completely soaked we assume they want to wet it, otherwise store it
if(reagents.total_volume < 1)
- user << "[src] is out of water!"
+ user << "[src] is out of water!"
else
reagents.trans_to_obj(I, 5) //
user << "You wet [I] in [src]."
diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm
index 8c3cc5e6f2..13d6694822 100644
--- a/code/game/objects/structures/lamarr_cage.dm
+++ b/code/game/objects/structures/lamarr_cage.dm
@@ -39,13 +39,6 @@
Break()
qdel(src)
-
-/obj/structure/lamarr/meteorhit(obj/O as obj)
- new /obj/item/weapon/material/shard( src.loc )
- Break()
- qdel(src)
-
-
/obj/structure/lamarr/proc/healthcheck()
if (src.health <= 0)
if (!( src.destroyed ))
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 8141dcf5a3..fe667b5b79 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -14,7 +14,7 @@
if(shattered) return
if(ishuman(user))
- var/obj/nano_module/appearance_changer/AC = ui_users[user]
+ var/datum/nano_module/appearance_changer/AC = ui_users[user]
if(!AC)
AC = new(src, user)
AC.name = "SalonPro Nano-Mirror(TM)"
@@ -60,7 +60,7 @@
return 0
if(damage)
- user.visible_message("[user] smashes [src]!")
+ user.visible_message("[user] smashes [src]!")
shatter()
else
user.visible_message("[user] hits [src] and bounces off!")
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index ace1293fc7..fcad40a0f0 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -20,7 +20,7 @@
/obj/structure/mopbucket/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/mop))
if(reagents.total_volume < 1)
- user << "[src] is out of water!"
+ user << "[src] is out of water!"
else
reagents.trans_to_obj(I, 5)
user << "You wet [I] in [src]."
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index daca23e8b7..ace39fafff 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -159,7 +159,7 @@
if (user != O)
for(var/mob/B in viewers(user, 3))
if ((B.client && !( B.blinded )))
- B << "\The [user] stuffs [O] into [src]!"
+ B << "\The [user] stuffs [O] into [src]!"
return
diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm
index 199635cd0f..0bbfe9f2f0 100644
--- a/code/game/objects/structures/safe.dm
+++ b/code/game/objects/structures/safe.dm
@@ -167,11 +167,6 @@ obj/structure/safe/blob_act()
obj/structure/safe/ex_act(severity)
return
-
-obj/structure/safe/meteorhit(obj/O as obj)
- return
-
-
//FLOOR SAFES
/obj/structure/safe/floor
name = "floor safe"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 265f073d5c..2b670320d0 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -22,6 +22,7 @@
/obj/structure/bed/New(var/newloc, var/new_material, var/new_padding_material)
..(newloc)
+ color = null
if(!new_material)
new_material = DEFAULT_WALL_MATERIAL
material = get_material_by_name(new_material)
@@ -61,6 +62,12 @@
name = "[material.display_name] [initial(name)]"
desc += " It's made of [material.use_name]."
+/obj/structure/bed/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(istype(mover) && mover.checkpass(PASSTABLE))
+ return 1
+ else
+ return ..()
+
/obj/structure/bed/ex_act(severity)
switch(severity)
if(1.0)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 06322fb98d..1d6ae5ed58 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -2,6 +2,7 @@
name = "chair"
desc = "You sit in this. Either by will or force."
icon_state = "chair_preview"
+ color = "#666666"
base_icon = "chair"
buckle_lying = 0 //force people to sit up in chairs when buckled
var/propelled = 0 // Check for fire-extinguisher-driven chairs
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 95e2f4d29d..545b72cb95 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -225,6 +225,12 @@
if(M.back)
if(M.back.clean_blood())
M.update_inv_back(0)
+
+ //flush away reagents on the skin
+ if(M.touching)
+ var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first
+ M.touching.remove_any(remove_amount)
+
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/washgloves = 1
@@ -352,7 +358,7 @@
if (user.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
- user << "You try to move your [temp.name], but cannot!"
+ user << "You try to move your [temp.name], but cannot!"
return
if(isrobot(user) || isAI(user))
@@ -377,12 +383,12 @@
if(ishuman(user))
user:update_inv_gloves()
for(var/mob/V in viewers(src, null))
- V.show_message("[user] washes their hands using \the [src].")
+ V.show_message("[user] washes their hands using \the [src].")
/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob)
if(busy)
- user << "Someone's already washing here."
+ user << "Someone's already washing here."
return
var/obj/item/weapon/reagent_containers/RG = O
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 26bc16e070..1fec557b8d 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -125,10 +125,6 @@
/obj/structure/window/blob_act()
shatter()
-
-/obj/structure/window/meteorhit()
- shatter()
-
//TODO: Make full windows a separate type of window.
//Once a full window, it will always be a full window, so there's no point
//having the same type for both.
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index 0b84ebbbde..79a2cf1fdc 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -38,9 +38,12 @@ var/can_call_ert
trigger_armed_response_team(1)
client/verb/JoinResponseTeam()
+
+ set name = "Join Response Team"
set category = "IC"
if(!MayRespawn(1))
+ usr << "You cannot join the response team at this time."
return
if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player))
@@ -50,18 +53,9 @@ client/verb/JoinResponseTeam()
if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
usr << "You are jobbanned from the emergency reponse team!"
return
-
- if(ert.current_antagonists.len > 5) usr << "The emergency response team is already full!"
-
- for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando")
- L.name = null//Reserving the place.
- var/new_name = sanitizeSafe(input(usr, "Pick a name","Name") as null|text, MAX_NAME_LEN)
- if(!new_name)//Somebody changed his mind, place is available again.
- L.name = "Commando"
- return
- create_response_team(L.loc, new_name)
- qdel(L)
-
+ if(ert.current_antagonists.len > 5)
+ usr << "The emergency response team is already full!"
+ ert.create_default(usr)
else
usr << "You need to be an observer or new player to use this."
@@ -130,25 +124,3 @@ proc/trigger_armed_response_team(var/force = 0)
sleep(600 * 5)
send_emergency_team = 0 // Can no longer join the ERT.
-
-/client/proc/create_response_team(obj/spawn_location, commando_name)
-
- var/mob/living/carbon/human/M = new(null)
-
-
- M.real_name = commando_name
- M.name = commando_name
- M.age = rand(25,45)
-
- M.check_dna(M)
- M.dna.ready_dna(M)//Creates DNA.
-
- M.mind = new
- M.mind.current = M
- M.mind.original = M
- if(!(M.mind in ticker.minds))
- ticker.minds += M.mind//Adds them to regular mind list.
- M.loc = spawn_location
- ert.add_antagonist(M.mind)
-
- return M
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 3ca8d64f6a..9fd83061de 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -503,7 +503,7 @@ turf/simulated/floor/proc/update_icon()
return
else
if(is_wood_floor())
- user << "You unscrew the planks."
+ user << "You unscrew the planks."
new floor_type(src)
make_plating()
diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm
index 1adaba850f..fa6ee92855 100644
--- a/code/game/turfs/simulated/wall_icon.dm
+++ b/code/game/turfs/simulated/wall_icon.dm
@@ -129,6 +129,6 @@
return
/turf/simulated/wall/proc/can_join_with(var/turf/simulated/wall/W)
- if(material && W.material && material.name == W.material.name)
+ if(material && W.material && material.icon_base == W.material.icon_base)
return 1
return 0
\ No newline at end of file
diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm
index 1b6f77cbd4..9a15491990 100644
--- a/code/game/turfs/simulated/wall_types.dm
+++ b/code/game/turfs/simulated/wall_types.dm
@@ -1,7 +1,7 @@
/turf/simulated/wall/r_wall
icon_state = "rgeneric"
/turf/simulated/wall/r_wall/New(var/newloc)
- ..(newloc, DEFAULT_WALL_MATERIAL,"plasteel") //3strong
+ ..(newloc, "plasteel","plasteel") //3strong
/turf/simulated/wall/cult
icon_state = "cult"
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 794c6bf0f7..af371f7a48 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -235,16 +235,6 @@ var/list/global/wall_cache = list()
// F.sd_LumReset() //TODO: ~Carn
return
-/turf/simulated/wall/meteorhit(obj/M as obj)
- var/rotting = (locate(/obj/effect/overlay/wallrot) in src)
- if (prob(15) && !rotting)
- dismantle_wall()
- else if(prob(70) && !rotting)
- ChangeTurf(/turf/simulated/floor/plating)
- else
- ReplaceWithLattice()
- return 0
-
/turf/simulated/wall/proc/radiate()
var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0)
if(!total_radiation)
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index fa4f88083f..9d40b49bcf 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -125,7 +125,7 @@
if(target in admins)
admin_stuff += "/([key])"
if(target != src)
- admin_stuff += "(JMP)"
+ admin_stuff += "([admin_jump_link(mob, target.holder)])"
if(target.mob in heard)
send = 1
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index 1f7db7a71b..176cb4f973 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -81,7 +81,7 @@
viewers(src) << pick("[src] is attempting to bite \his tongue off! It looks like \he's trying to commit suicide.", \
"[src] is jamming \his thumbs into \his eye sockets! It looks like \he's trying to commit suicide.", \
- "[src] is twisting \his own neck! It looks like \he's trying to commit suicide.", \
+ "[src] is twisting \his own neck! It looks like \he's trying to commit suicide.", \
"[src] is holding \his breath! It looks like \he's trying to commit suicide.")
adjustOxyLoss(max(175 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index d27359acfc..447178ecb3 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -20,6 +20,10 @@ var/global/floorIsLava = 0
var/msg = rendered
C << msg
+proc/admin_notice(var/message, var/rights)
+ for(var/mob/M in mob_list)
+ if(check_rights(rights, 0, M))
+ M << message
///////////////////////////////////////////////////////////////////////////////////////////////Panels
@@ -54,7 +58,7 @@ var/global/floorIsLava = 0
TP -
PM -
SM -
- JMP\]
+ [admin_jump_link(M, src)]\]
Mob type = [M.type]
Kick |
Warn |
@@ -1160,7 +1164,7 @@ var/global/floorIsLava = 0
out += "Core antag id: [ticker.mode.antag_tag]."
if(ticker.mode.round_autoantag)
- out += "Autotraitor enabled ([ticker.mode.antag_prob]% spawn chance)"
+ out += "Autotraitor enabled ([ticker.mode.get_antag_prob()]% spawn chance)"
if(ticker.mode.antag_scaling_coeff)
out += " (scaling with [ticker.mode.antag_scaling_coeff])"
out += "
"
@@ -1302,15 +1306,15 @@ var/global/floorIsLava = 0
if(2) //Admins
var/ref_mob = "\ref[M]"
- return "[key_name(C, link, name, highlight_special)](?) (PP) (VV) (SM) (JMP) (CA)"
+ return "[key_name(C, link, name, highlight_special)](?) (PP) (VV) (SM) ([admin_jump_link(M, src)]) (CA)"
if(3) //Devs
var/ref_mob = "\ref[M]"
- return "[key_name(C, link, name, highlight_special)](VV)(JMP)"
+ return "[key_name(C, link, name, highlight_special)](VV)([admin_jump_link(M, src)])"
if(4) //Mentors
var/ref_mob = "\ref[M]"
- return "[key_name(C, link, name, highlight_special)] (?) (PP) (VV) (SM) (JMP)"
+ return "[key_name(C, link, name, highlight_special)] (?) (PP) (VV) (SM) ([admin_jump_link(M, src)])"
/proc/ishost(whom)
diff --git a/code/defines/procs/admin.dm b/code/modules/admin/admin_attack_log.dm
similarity index 76%
rename from code/defines/procs/admin.dm
rename to code/modules/admin/admin_attack_log.dm
index bf16c5267d..72e85e1d94 100644
--- a/code/defines/procs/admin.dm
+++ b/code/modules/admin/admin_attack_log.dm
@@ -1,7 +1,6 @@
-proc/admin_notice(var/message, var/rights)
- for(var/mob/M in mob_list)
- if(check_rights(rights, 0, M))
- M << message
+/mob/var/lastattacker = null
+/mob/var/lastattacked = null
+/mob/var/attack_log = list( )
proc/log_and_message_admins(var/message as text, var/mob/user = usr)
log_admin(user ? "[key_name(user)] [message]" : "EVENT [message]")
@@ -23,10 +22,12 @@ proc/admin_log_and_message_admins(var/message as text)
message_admins(usr ? "[key_name_admin(usr)] [message]" : "EVENT [message]", 1)
proc/admin_attack_log(var/mob/attacker, var/mob/victim, var/attacker_message, var/victim_message, var/admin_message)
- victim.attack_log += text("\[[time_stamp()]\] [key_name(attacker)] - [victim_message]")
- attacker.attack_log += text("\[[time_stamp()]\] [key_name(victim)] - [attacker_message]")
+ if(victim)
+ victim.attack_log += text("\[[time_stamp()]\] [key_name(attacker)] - [victim_message]")
+ if(attacker)
+ attacker.attack_log += text("\[[time_stamp()]\] [key_name(victim)] - [attacker_message]")
- msg_admin_attack("[key_name(attacker)] [admin_message] [key_name(victim)] (INTENT: [uppertext(attacker.a_intent)]) (JMP)")
+ msg_admin_attack("[key_name(attacker)] [admin_message] [key_name(victim)] (INTENT: [attacker? uppertext(attacker.a_intent) : "N/A"]) (JMP)")
proc/admin_attacker_log_many_victims(var/mob/attacker, var/list/mob/victims, var/attacker_message, var/victim_message, var/admin_message)
if(!victims || !victims.len)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index af1e049b39..b415a317fc 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -177,6 +177,10 @@ var/list/admin_verbs_debug = list(
/client/proc/toggledebuglogs,
/client/proc/SDQL_query,
/client/proc/SDQL2_query,
+ /client/proc/Jump,
+ /client/proc/jumptomob,
+ /client/proc/jumptocoord,
+ /client/proc/dsay
)
var/list/admin_verbs_paranoid_debug = list(
@@ -735,7 +739,7 @@ var/list/admin_verbs_mentor = list(
var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in silicon_mob_list
if(!S) return
- var/obj/nano_module/law_manager/L = new(S)
+ var/datum/nano_module/law_manager/L = new(S)
L.ui_interact(usr, state = admin_state)
admin_log_and_message_admins("has opened [S]'s law manager.")
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm
index a00a208d3b..c5a54694c8 100644
--- a/code/modules/admin/player_notes.dm
+++ b/code/modules/admin/player_notes.dm
@@ -27,26 +27,6 @@ datum/admins/proc/notes_gethtml(var/ckey)
. += "[dir]
"
return
-
-//handles adding notes to the end of a ckey's buffer
-//originally had seperate entries such as var/by to record who left the note and when
-//but the current bansystem is a heap of dung.
-/proc/notes_add(var/ckey, var/note)
- if(!ckey)
- ckey = ckey(input(usr,"Who would you like to add notes for?","Enter a ckey",null) as text|null)
- if(!ckey) return
-
- if(!note)
- note = html_encode(input(usr,"Enter your note:","Enter some text",null) as message|null)
- if(!note) return
-
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return
- notesfile.cd = "/[ckey]"
- notesfile.eof = 1 //move to the end of the buffer
- notesfile << "[time2text(world.realtime,"DD-MMM-YYYY")] | [note][(usr && usr.ckey)?" ~[usr.ckey]":""]"
- return
-
//handles removing entries from the buffer, or removing the entire directory if no start_index is given
/proc/notes_remove(var/ckey, var/start_index, var/end_index)
var/savefile/notesfile = new(NOTESFILE)
@@ -85,7 +65,7 @@ datum/admins/proc/notes_gethtml(var/ckey)
//Hijacking this file for BS12 playernotes functions. I like this ^ one systemm alright, but converting sounds too bothersome~ Chinsky.
-/proc/notes_add(var/key, var/note, var/mob/usr)
+/proc/notes_add(var/key, var/note, var/mob/user)
if (!key || !note)
return
@@ -111,9 +91,9 @@ datum/admins/proc/notes_gethtml(var/ckey)
var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
var/datum/player_info/P = new
- if (usr)
- P.author = usr.key
- P.rank = usr.client.holder.rank
+ if (user)
+ P.author = user.key
+ P.rank = user.client.holder.rank
else
P.author = "Adminbot"
P.rank = "Friendly Robot"
@@ -123,8 +103,8 @@ datum/admins/proc/notes_gethtml(var/ckey)
infos += P
info << infos
- message_admins("\blue [key_name_admin(usr)] has edited [key]'s notes.")
- log_admin("[key_name(usr)] has edited [key]'s notes.")
+ message_admins("\blue [key_name_admin(user)] has edited [key]'s notes.")
+ log_admin("[key_name(user)] has edited [key]'s notes.")
qdel(info)
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 828667aa13..a25d2de043 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -410,43 +410,11 @@
dat += "Launching now..."
dat += "[ticker.delay_end ? "End Round Normally" : "Delay Round End"]
"
-
- //todo
-
+ dat += "
"
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/A = all_antag_types[antag_type]
+ dat += A.get_check_antag_output(src)
dat += "