diff --git a/.travis.yml b/.travis.yml
index e825828ab42..563545ca020 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 506657df12e..922275bcc91 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 8d084dc4c95..1f652ffaaba 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 00000000000..ac5f7120fd6
--- /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 936d80890d7..6e1acef8ce1 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 f2a96d460da..ecca29bfd19 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 50f55703d34..d5d0f586852 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 00000000000..abb0366382d
--- /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 29d55e629fa..e44a60ebc2b 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 5a56b34e617..b22266274a7 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 0ba005455c6..f3419b074af 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 7380e709f45..668f715cf58 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 469df7305a0..7a4d10fc888 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 c3a77b4b0e7..5163bfb2706 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 a70822942fe..65f34ed580c 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 00000000000..ebf22a21c92
--- /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 1ab79f26b5d..f93409a8203 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 aad02b1c6c6..11431682a14 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 00000000000..e3c653a4e51
--- /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 35af4e6f804..00000000000
--- 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 00000000000..da0e5b33a12
--- /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 00000000000..2f4bc6da3a5
--- /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 02ec5304fc2..00000000000
--- 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 92556a817ab..a578c1bf4fd 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 58997fa68e1..432c3f6bbe8 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 00000000000..ed8f1d95632
--- /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 00000000000..1d69aaa96f8
--- /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 00000000000..eaca01986c6
--- /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 c8453663fb4..00000000000
--- 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 00000000000..0fd5fb2a93f
--- /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 d03f5c3d8aa..376f25c34ac 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 946ff1dfc28..d847d4ef7a8 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 72a6a56d627..1ddc6457d94 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 4fed41aa13a..5af82ff05d5 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 a7949011fc5..4d25b1c3fec 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 2923008a7b8..74866d92474 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 55b67cc29a5..f6307b8ae8b 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 adaa2b24f5d..f3999535aff 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 ced1d58b382..59d12b50ada 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 c8b8b95b2a6..a4f14dccf8e 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 e1d2e0b9921..b569f1c0779 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 ff93e692989..47923ef89b6 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 3862bd474fc..00000000000
--- 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 7d9da106366..c93a19d5673 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 29619503774..eb15d45f513 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 a1c0acf0081..f6c7d46063d 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 d70c181830a..3a6c2c1b3cc 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 4900efb291f..f644391bf78 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 74fb9ee5079..fdc955718ba 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 13cdb511e81..492b932e462 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 edbaa4544c9..8a2f46598b4 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 00000000000..9af35241441
--- /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 19378de1670..b5280168982 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 1be9d0330f5..f757ed5e9e3 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 335360d40d0..51cb427c0cb 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 293631f2a84..6f5e6ab7322 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 5d8ac9d0717..37ec7d9a2a7 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 493650359e9..88de996e71e 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 b39ce3f147b..2b0e776ce1f 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 85cbf3a7052..0812c514299 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 d0855e47810..3aca20b7603 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 fbf9bf5e7b1..95e043db28b 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 c84d030cc46..21550121cdf 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 58c3fc0e246..f8d611bcbfc 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 83112ea778f..eca7dbcef9d 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 ad9a964ca9d..88d8f8dd7ec 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 935856269c1..36a6e76e553 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 d8c776bc364..8f048db0437 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 b4e75b046ff..af33673a1f7 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 cf275eb5ce8..17d0552779a 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 d8d2a3bb0e6..f5798737018 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 07b075a5f1b..c11108b4907 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 25baf81486d..4680bb57d1d 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 b9409077799..c247846a2df 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 b32f9e9daa0..74edf74ea9b 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 6928d104ca7..6df502891f2 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 f775c5f9508..779e2a14607 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 3dd181c917b..af0105ca5b7 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 8ff3a8e103f..f33e3af8335 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 ea8cf4d7268..e48a71b89fd 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 696273d2ab8..ea0952e9f71 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 9d05249d958..07b4e007a32 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 3357072c28d..333584a9213 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 902d8ef1a45..6b6a2f84914 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 ccd63aef36b..2e73e771152 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 e00e1d00285..50de43e6b7d 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 e3c8607b88d..167190c3362 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 e010264d4ad..4fc7562b3af 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 2c5c00caaae..a2bfb1b6c27 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 69dc6987957..32b7a5b46b6 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 b130d1e63d1..15b408a2dce 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 dce2ab37bda..c87ab1ad35c 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 f846af37275..dc3edc93283 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 ec9f4e7accc..6661468f59e 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 8d883a8ddf7..3a4d51715b8 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 e51025aee2f..63198710227 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 90305a7a786..65b1f2ca6fa 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 13d55e725b7..3d18d80a1e2 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 3125b35df65..bc52c276c34 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 0570211526d..55cf5cdc15c 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 4ea2f416f77..9fa78ee9688 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 ca0b150fe66..7e2d5216985 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 cb487ae58c5..ac561009b61 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 c6fee28b40c..820d09045b8 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 ef3c7d6ea92..2f6165a7330 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 ca132cc06e7..7dd30dd8c3d 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 6917675653b..1123733103f 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 223b503f4f7..a1e2287f589 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 e04034ad93c..a3ac073a90b 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 43d0f107c0d..9c79441f321 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 7ebeb641d89..c1cadaef5c5 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 284bce3a33a..2b17096547c 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 641c86e70e1..07c54ceb2b9 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 2d5c2201bd3..ddf0f2bdd6b 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 d9e88e70e06..cd6d1e76d38 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 eac107923ed..9b154645443 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 b81089d9fb4..1c723c04ada 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 b38a0f15515..ec3881cdbe6 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 aeac044f38e..e5f769858fb 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 58c053aa669..6ad69f099b6 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 ffa85880a33..72b5229cc05 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 a88d4f0e396..4b69e5db7c8 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 10adef3d886..fbdb7667a1f 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 a6a51386d55..e4d1c57a0d0 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 f68451f329d..65e8a560df2 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 3471d1fcfe1..f849b17c991 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 2e08de6d819..0357a8b80b6 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 72a99f494ed..48fa43ba644 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 5c14d8debe5..849ceac3af4 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 932b3d6a6be..9f1041af876 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 405e77db7a0..e59d3e993b5 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 96874bd946b..345e9ddd067 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 00000000000..f90c4797bc5
--- /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 00000000000..97655196222
--- /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 00000000000..5e843388c54
--- /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 d2627ed094c..0ebc4a27e1c 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 f4c03bf2bc7..96ddeccec64 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 10f445b769a..3b1e18f8513 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 3c2b02feeda..9afe2e83e4d 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 a9ca4b8dc0e..c11720d1e8f 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 56fbf2bff28..ef6b4c4d57c 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 29c3f648202..218d2fb21cf 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 b94fd2d3606..7c685a9e1d4 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 4eec1009e50..aa7f6df8e46 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 56236a754f4..95e1875d403 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 f5017538072..1565d321b67 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 033042b8530..d5e7cd67bb7 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 fe33163dbab..c396f8d4b9b 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 2bb0f91e2f0..c2ff0401ff5 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 05709898d64..8cc8ee5cfa0 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 f42685b7925..e4df419e18e 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 b5466f7a394..297ac1d4b18 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 ef5d8db3345..ebd76a64a50 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 b33d72f6fbc..6b3fdd04ae5 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 cc549700092..39eb9fb25fa 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 0eecde46a58..7e96ad2c08e 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 86effc923c4..8c5b1de0264 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 d51a9a1e3bd..7bd266f2410 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 f6af73843c2..d62b89f3fae 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 867c5155e08..e9670ce4d72 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 8039814f4fe..1f25043e894 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 e66d5c488a6..68aeecd9127 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 66609f5661e..c732faeeea5 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 55cd3b51ca6..3bc5dfc393b 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 b59cd62dfa3..5458f3da948 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 ad28bb40195..2e76ad3c885 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 54a9fc8092b..c697f1a4c11 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 3c5d5ec8494..bc6217f7746 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 872b8ff9885..c8ccd4b32bd 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 38caaa3230b..d217b101970 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 fa7a448bd66..331529b87d8 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 cd8fad5ec5e..f31b098b5b3 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 237250e3fdd..cac56d23b9a 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 8c3cc5e6f2a..13d6694822d 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 8141dcf5a39..fe667b5b79d 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 ace1293fc7d..fcad40a0f0f 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 daca23e8b7a..ace39fafff1 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 199635cd0fe..0bbfe9f2f01 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 265f073d5cc..2b670320d02 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 06322fb98dd..1d6ae5ed583 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 95e2f4d29df..545b72cb959 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 26bc16e070a..1fec557b8d4 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 0b84ebbbdec..79a2cf1fdc5 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 3ca8d64f6a3..9fd83061def 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 1adaba850f6..fa6ee92855e 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 1b6f77cbd44..9a154919905 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 794c6bf0f74..af371f7a48f 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 fa4f88083f5..9d40b49bcf5 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 1f7db7a71be..176cb4f9735 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 d27359acfc7..447178ecb30 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 bf16c5267d6..72e85e1d940 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 af1e049b39e..b415a317fc2 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 a00a208d3b5..c5a54694c81 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 828667aa132..a25d2de0438 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 += "