Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into 6/25/2015_bay_sync

Conflicts:
	.travis.yml
	code/modules/clothing/spacesuits/rig/modules/combat.dm
	code/modules/clothing/spacesuits/rig/modules/utility.dm
	code/modules/mob/living/silicon/ai/ai.dm
	icons/mob/rig_back.dmi
	polaris.dme
This commit is contained in:
Neerti
2015-06-25 18:50:18 -04:00
426 changed files with 8890 additions and 7959 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -33,3 +33,5 @@ Notes for people who used ZAS before:
#define AIR_BLOCKED 1
#define ZONE_BLOCKED 2
#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

View File

@@ -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.

View File

@@ -80,6 +80,8 @@ var/list/be_special_flags = list(
#define MODE_MALFUNCTION "malf"
#define MODE_TRAITOR "traitor"
#define DEFAULT_TELECRYSTAL_AMOUNT 12
/////////////////
////WIZARD //////
/////////////////

View File

@@ -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"
@@ -148,3 +149,8 @@
#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)
#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)

View File

@@ -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)
. += "<a href='?priv_msg=\ref[C]'>"
if(C && C.holder && C.holder.fakekey && !include_name)
. += "Administrator"
else
. += key
if(include_link)
if(C) . += "</a>"
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)
. += "/(<font color='#FFA500'>[name]</font>)" //Orange
else
. += "/([name])"
return .
/proc/key_name_admin(var/whom, var/include_name = 1)
return key_name(whom, 1, include_name)

17
code/_helpers/matrices.dm Normal file
View File

@@ -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)

View File

@@ -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)
. += "<a href='?priv_msg=\ref[C]'>"
if(C && C.holder && C.holder.fakekey && !include_name)
. += "Administrator"
else
. += key
if(include_link)
if(C) . += "</a>"
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)
. += "/(<font color='#FFA500'>[name]</font>)" //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)

View File

@@ -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

View File

@@ -74,28 +74,26 @@ var/const/tk_maxrange = 15
var/atom/movable/focus = null
var/mob/living/host = null
dropped(mob/user as mob)
/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
//stops TK grabs being equipped anywhere but into hands
equipped(var/mob/user, var/slot)
//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
attack_self(mob/user as mob)
/obj/item/tk_grab/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
/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)
@@ -137,19 +135,17 @@ var/const/tk_maxrange = 15
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
attack(mob/living/M as mob, mob/living/user as mob, def_zone)
/obj/item/tk_grab/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
return
proc/focus_object(var/obj/target, var/mob/living/user)
/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)
@@ -159,8 +155,7 @@ var/const/tk_maxrange = 15
apply_focus_overlay()
return
proc/apply_focus_overlay()
/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"
@@ -175,34 +170,8 @@ var/const/tk_maxrange = 15
qdel(O)
return
update_icon()
/obj/item/tk_grab/update_icon()
overlays.Cut()
if(focus && focus.icon && focus.icon_state)
overlays += icon(focus.icon,focus.icon_state)
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
*/

View File

@@ -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)

View File

@@ -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")

View File

@@ -29,7 +29,7 @@
*/
datum/mind
/datum/mind
var/key
var/name //replaces mob/var/original_name
var/mob/living/current
@@ -58,13 +58,14 @@ 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)
/datum/mind/New(var/key)
src.key = key
/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
@@ -86,10 +87,10 @@ datum/mind
if(active)
new_character.key = key //now transfer the key to link the client to our new body
proc/store_memory(new_text)
/datum/mind/proc/store_memory(new_text)
memory += "[new_text]<BR>"
proc/show_memory(mob/recipient)
/datum/mind/proc/show_memory(mob/recipient)
var/output = "<B>[current.real_name]'s Memory</B><HR>"
output += memory
@@ -103,7 +104,7 @@ datum/mind
recipient << browse(output,"window=memory")
proc/edit_memory()
/datum/mind/proc/edit_memory()
if(!ticker || !ticker.mode)
alert("Not before round-start!", "Alert")
return
@@ -137,12 +138,12 @@ datum/mind
out += "<br><a href='?src=\ref[src];obj_add=1'>\[add\]</a>"
usr << browse(out, "window=edit_memory[src]")
Topic(href, href_list)
/datum/mind/Topic(href, href_list)
if(!check_rights(R_ADMIN)) return
if(href_list["add_antagonist"])
var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
if(antag) antag.add_antagonist(src)
if(antag) antag.add_antagonist(src, 1, 1, 0, 1, 1) // Ignore equipment and role type for this.
else if(href_list["remove_antagonist"])
var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
@@ -316,61 +317,10 @@ datum/mind
H << "<span class='notice'><font size =3><B>Your loyalty implant has been deactivated.</font></span>"
log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
if("add")
H << "<span class='danger'><font size =3>You somehow have become the recepient of a loyalty transplant, and it just activated!</font>"
H << "<span class='danger'><font size =3>You somehow have become the recepient of a loyalty transplant, and it just activated!</font></span>"
H.implant_loyalty(H, override = TRUE)
log_admin("[key_name_admin(usr)] has loyalty implanted [current].")
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("<span class='notice'>[key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]</span>")
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("<span class='notice'>[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]</span>", 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("<span class='notice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]</span>")
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"])
@@ -432,66 +382,33 @@ datum/mind
else if (href_list["obj_announce"])
var/obj_count = 1
current << "<span class='notice'>Your current objectives:</span>"
current << "\blue Your current objectives:"
for(var/datum/objective/objective in objectives)
current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
edit_memory()
/*
proc/clear_memory(var/silent = 1)
var/datum/game_mode/current_mode = ticker.mode
// 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)
// 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()
/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
proc/take_uplink()
/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)
// 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)
@@ -511,6 +428,19 @@ datum/mind
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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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 "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[move to vent\]</a>"
/datum/antagonist/xenos/random_spawn()
/datum/antagonist/xenos/attempt_random_spawn()
if(config.aliens_allowed) ..()
/datum/antagonist/xenos/proc/get_vents()

View File

@@ -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 = "<tr><td><b>[role_text]:</b>"
var/extra = get_extra_panel_options(player)
if(is_antagonist(player))
dat += "<a href='?src=\ref[player];remove_antagonist=[id]'>\[-\]</a>"
dat += "<a href='?src=\ref[player];equip_antagonist=[id]'>\[equip\]</a>"
if(starting_locations && starting_locations.len)
dat += "<a href='?src=\ref[player];move_antag_to_spawn=[id]'>\[move to spawn\]</a>"
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 << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
if(istype(player.current, /mob/dead))
create_default(player.current)
else
dat += "<a href='?src=\ref[player];add_antagonist=[id]'>\[+\]</a>"
dat += "</td></tr>"
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 = "<br><font size = 2><b>The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:</b></font>"
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 += "<font color='green'><B>Success!</B></font>"
feedback_add_details(feedback_tag,"[O.type]|SUCCESS")
else
text += "<font color='red'>Fail.</font>"
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 += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
else
text += "<br><font color='green'><B>The [role_text] was successful!</B></font>"
if(global_objectives && global_objectives.len)
text += "<BR/><FONT size = 2>Their objectives were:<FONT>"
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 = "<br><b>Objective [num]:</b> [O.explanation_text] "
if(append_success)
if(O.check_completion())
text += "<font color='green'><B>Success!</B></font>"
else
text += "<font color='red'>Fail.</font>"
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 = "<br><b>[ply.name]</b> (<b>[ply.key]</b>) as \a <b>[role]</b> ("
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 <b>[ply.current.real_name]</b>"
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 += "<br>[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()

View File

@@ -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 << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>"
current_antagonists -= player
player.special_role = null
update_icons_removed(player)
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
return 1
return 0

View File

@@ -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 << "<span class='danger'><font size=3>You are a [role_text]!</font></span>"
if(leader_welcome_text && player.current == leader)
player.current << "<span class='notice'>[leader_welcome_text]</span>"
else
player.current << "<span class='notice'>[welcome_text]</span>"
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: <b>[code]</b>"
P.name = "nuclear bomb code"
if(code_owner)
code_owner.store_memory("<B>Nuclear Bomb Code</B>: [code]", 0, 0)
code_owner.current << "The nuclear authorization code is: <B>[code]</B>"
else
world << "<spam class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>"
return
spawned_nuke = code
return code

View File

@@ -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: <b>[code]</b>"
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("<B>Nuclear Bomb Code</B>: [code]", 0, 0)
code_owner.current << "The nuclear authorization code is: <B>[code]</B>"
else
world << "<span class='danger'>Could not spawn nuclear bomb. Contact a developer.</span>"
return
spawned_nuke = code
return code
/datum/antagonist/proc/greet(var/datum/mind/player)
// Basic intro text.
player.current << "<span class='danger'><font size=3>You are a [role_text]!</font></span>"
if(leader_welcome_text && player == leader)
player.current << "<span class='notice'>[leader_welcome_text]</span>"
else
player.current << "<span class='notice'>[welcome_text]</span>"
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)

View File

@@ -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

View File

@@ -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()

View File

@@ -1,6 +1,7 @@
/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(!ignore_role)
if(player.assigned_role in protected_jobs)
return 0
if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs))
@@ -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))

View File

@@ -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 << "<span class='danger'><font size = 3>[victory_text]</span>"
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")

View File

@@ -0,0 +1,61 @@
/datum/antagonist/proc/get_panel_entry(var/datum/mind/player)
var/dat = "<tr><td><b>[role_text]:</b>"
var/extra = get_extra_panel_options(player)
if(is_antagonist(player))
dat += "<a href='?src=\ref[player];remove_antagonist=[id]'>\[-\]</a>"
dat += "<a href='?src=\ref[player];equip_antagonist=[id]'>\[equip\]</a>"
if(starting_locations && starting_locations.len)
dat += "<a href='?src=\ref[player];move_antag_to_spawn=[id]'>\[move to spawn\]</a>"
if(extra) dat += "[extra]"
else
dat += "<a href='?src=\ref[player];add_antagonist=[id]'>\[+\]</a>"
dat += "</td></tr>"
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 = "<br><table cellspacing=5><tr><td><B>[role_text_plural]</B></td><td></td></tr>"
for(var/datum/mind/player in current_antagonists)
var/mob/M = player.current
dat += "<tr>"
if(M)
dat += "<td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>"
if(!M.client) dat += " <i>(logged out)</i>"
if(M.stat == DEAD) dat += " <b><font color=red>(DEAD)</font></b>"
dat += "</td>"
dat += "<td>\[<A href='?src=\ref[caller];priv_msg=\ref[M]'>PM</A>\]\[<A href='?src=\ref[caller];traitor=\ref[M]'>TP</A>\]</td>"
else
dat += "<td><i>Mob not found!</i></td>"
dat += "</tr>"
dat += "</table>"
if(flags & ANTAG_HAS_NUKE)
dat += "<br><table><tr><td><B>Nuclear disk(s)</B></td></tr>"
for(var/obj/item/weapon/disk/nuclear/N in world)
dat += "<tr><td>[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 <a href='?src=\ref[caller];adminplayeropts=\ref[M]'>[M.real_name]</a> "
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])</td></tr>"
dat += "</table>"
dat += get_additional_check_antag_output(caller)
dat += "<hr>"
return dat
//Overridden elsewhere.
/datum/antagonist/proc/get_additional_check_antag_output(var/datum/admins/caller)
return ""

View File

@@ -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)

View File

@@ -0,0 +1,86 @@
/datum/antagonist/proc/print_player_summary()
if(!current_antagonists.len)
return 0
var/text = "<br><br><font size = 2><b>The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:</b></font>"
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 += "<font color='green'><B>Success!</B></font>"
feedback_add_details(feedback_tag,"[O.type]|SUCCESS")
else
text += "<font color='red'>Fail.</font>"
feedback_add_details(feedback_tag,"[O.type]|FAIL")
failed = 1
num++
if(!config.objectives_disabled)
if(failed)
text += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
else
text += "<br><font color='green'><B>The [role_text] was successful!</B></font>"
if(global_objectives && global_objectives.len)
text += "<BR><FONT size = 2>Their objectives were:<FONT>"
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 = "<br><b>Objective [num]:</b> [O.explanation_text] "
if(append_success)
if(O.check_completion())
text += "<font color='green'><B>Success!</B></font>"
else
text += "<font color='red'>Fail.</font>"
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 = "<br><b>[ply.name]</b> (<b>[ply.key]</b>) as \a <b>[role]</b> ("
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 <b>[ply.current.real_name]</b>"
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 += "<br>[purchases]"
return text

View File

@@ -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 << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
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 << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>"
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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()
..()

View File

@@ -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")

View File

@@ -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.</span>"
welcome_text = "<span class='info'>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.</span>"
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("<B>Directive:</B> <span class='danger'>[directive]</span><br>")
player << "<b>Remember your directive:</b> [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)

View File

@@ -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 += "<B>The Raiders were repelled!</B>"
world << "<span class='danger'><font size = 3>[win_type] [win_group] victory!</font>"
world << "<span class='danger'><font size = 3>[win_type] [win_group] victory!</font></span>"
world << "[win_msg]"
feedback_set_details("round_end_result","heist - [win_type] [win_group]")

View File

@@ -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.<br>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("<B>Remember:</B> do not forget to prepare your spells.")
wizard.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]"
wizard.current.name = wizard.current.real_name

View File

@@ -13,7 +13,7 @@
/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player)
return "<br><b>Changeling ID:</b> [player.changeling.changelingID].<br><b>Genomes Absorbed:</b> [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()

View File

@@ -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 << "<span class='danger'>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 << "<span class='danger'>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.</span>"
player.memory = ""
if(show_message)
player.current.visible_message("<FONT size = 3>[player.current] looks like they just reverted to their old faith!</FONT>")
@@ -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

View File

@@ -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 += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
var/mob/M = N.current
if(!M)
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
else
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
var/turf/mob_loc = get_turf(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><i>Head not found!</i></td></tr>"
*/
/datum/antagonist/revolutionary/create_global_objectives()
if(!..())
return
@@ -166,7 +196,7 @@ var/datum/antagonist/revolutionary/revs
if(choice == "Yes!")
M << "<span class='notice'>You join the revolution!</span>"
src << "<span class='notice'>[M] joins the revolution!</span>"
revs.add_antagonist(M.mind)
revs.add_antagonist(M.mind, 0, 0, 1)
else if(choice == "No!")
M << "<span class='danger'>You reject this traitorous cause!</span>"
src << "<span class='danger'>\The [M] does not support the revolution!</span>"

View File

@@ -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(!..())
@@ -148,8 +148,7 @@ var/datum/antagonist/traitor/traitors
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
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."
@@ -158,8 +157,7 @@ var/datum/antagonist/traitor/traitors
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

View File

@@ -67,9 +67,6 @@
return flags & INSERT_CONTAINER
*/
/atom/proc/meteorhit(obj/meteor as obj)
return
/atom/proc/allow_drop()
return 1
@@ -224,6 +221,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

View File

@@ -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

View File

@@ -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 = "</font color><b>[copytext(input, i, i+1)]</b><font color='blue'>"
else
if(ui) //This is for allowing block clicks to be differentiated
pushstring = "<a href='?src=\ref[src];uimenuset=[num2text(blockpos)];uimenusubset=[num2text(subpos)]'>[copytext(input, i, i+1)]</a>"
else
pushstring = "<a href='?src=\ref[src];semenuset=[num2text(blockpos)];semenusubset=[num2text(subpos)]'>[copytext(input, i, i+1)]</a>"
string += pushstring // push the string to the return string
if(subpos >= blocksize) // add a line break for every block
string += " </font color><font color='#285B5B'>|</font color><font color='blue'> "
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 << "<span class='notice'>You feel no need to breathe.</span>"
M.mutations.Add(mNobreath)
if(ismuton(REMOTEVIEWBLOCK,M))
if(probinj(45,inj) || (mRemote in old_mutations))
M << "<span class='notice'>Your mind expands.</span>"
M.mutations.Add(mRemote)
if(ismuton(REGENERATEBLOCK,M))
if(probinj(45,inj) || (mRegen in old_mutations))
M << "<span class='notice'>You feel strange.</span>"
M.mutations.Add(mRegen)
if(ismuton(INCREASERUNBLOCK,M))
if(probinj(45,inj) || (mRun in old_mutations))
M << "<span class='notice'>You feel quick.</span>"
M.mutations.Add(mRun)
if(ismuton(REMOTETALKBLOCK,M))
if(probinj(45,inj) || (mRemotetalk in old_mutations))
M << "<span class='notice'>You expand your mind outwards.</span>"
M.mutations.Add(mRemotetalk)
if(ismuton(MORPHBLOCK,M))
if(probinj(45,inj) || (mMorph in old_mutations))
M.mutations.Add(mMorph)
M << "<span class='notice'>Your skin feels strange.</span>"
if(ismuton(BLENDBLOCK,M))
if(probinj(45,inj) || (mBlend in old_mutations))
M.mutations.Add(mBlend)
M << "<span class='notice'>You feel alone.</span>"
if(ismuton(HALLUCINATIONBLOCK,M))
if(probinj(45,inj) || (mHallucination in old_mutations))
M.mutations.Add(mHallucination)
M << "<span class='notice'>Your mind says 'Hello'.</span>"
if(ismuton(NOPRINTSBLOCK,M))
if(probinj(45,inj) || (mFingerprints in old_mutations))
M.mutations.Add(mFingerprints)
M << "<span class='notice'>Your fingers feel numb.</span>"
if(ismuton(SHOCKIMMUNITYBLOCK,M))
if(probinj(45,inj) || (mShock in old_mutations))
M.mutations.Add(mShock)
M << "<span class='notice'>You feel strange.</span>"
if(ismuton(SMALLSIZEBLOCK,M))
if(probinj(45,inj) || (mSmallsize in old_mutations))
M << "<span class='notice'>Your skin feels rubbery.</span>"
M.mutations.Add(mSmallsize)
if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK))
if(probinj(5,inj) || (HULK in old_mutations))
M << "<span class='notice'>Your muscles hurt.</span>"
M.mutations.Add(HULK)
if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK))
M.disabilities |= EPILEPSY
M << "<span class='warning'>You get a headache.</span>"
if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK))
M << "<span class='warning'>You feel strange.</span>"
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 << "<span class='warning'>You start coughing.</span>"
if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK))
M << "<span class='warning'>You feel lightheaded.</span>"
M.mutations.Add(CLUMSY)
if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK))
M.disabilities |= TOURETTES
M << "<span class='warning'>You twitch.</span></span>"
if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK))
if(probinj(30,inj) || (XRAY in old_mutations))
M << "<span class='notice'>The walls suddenly disappear.</span>"
// 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 << "<span class='warning'>You feel nervous.</span>"
if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK))
if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations))
M << "<span class='warning'>Your body feels warm.</span>"
M.mutations.Add(COLD_RESISTANCE)
if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK))
M.sdisabilities |= BLIND
M << "<span class='warning'>You can't seem to see anything.</span>"
if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK))
if(probinj(15,inj) || (TK in old_mutations))
M << "<span class='warning'>You feel smarter.</span>"
M.mutations.Add(TK)
if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK))
M.sdisabilities |= DEAF
M.ear_deaf = 1
M << "<span class='warning'>It's kinda quiet..</span>"
if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK))
M.disabilities |= NEARSIGHTED
M << "<span class='warning'>Your eyes feel weird...</span>"
/* 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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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)
/*

View File

@@ -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)

View File

@@ -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

View File

@@ -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,11 +477,8 @@ 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
if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
continue
antag_templates -= antag
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
@@ -685,7 +536,7 @@ proc/display_roundstart_logout_report()
msg += "<b>[L.name]</b> ([ckey(D.mind.key)]), the [L.job] (<font color='red'><b>Ghosted</b></font>)\n"
continue //Ghosted while alive
msg += "</span>" // close the <span class='notice'> from right at the top
msg += "</span>" // close the span from right at the top
for(var/mob/M in mob_list)
if(M.client && M.client.holder)

View File

@@ -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))

View File

@@ -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

View File

@@ -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."

View File

@@ -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

View File

@@ -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)
//then, ram the turf if it still exists
if(T)
T.ex_act(hitpwr)
//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/ex_act(severity)
if (severity < 4)
qdel(src)
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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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("<span class='notice'>\The [user] has disconnected [src]'s detecting unit!</span>", "<span class='notice'>You have disconnected [src]'s detecting unit.</span>")
else if (istype(W, /obj/item/weapon/wirecutters))
user.visible_message("<span class='notice'>\The [user] has cut the wires inside \the [src]!</span>", "<span class='notice'>You have cut the wires inside \the [src].</span>")
new/obj/item/stack/cable_coil(get_turf(src), 5)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
buildstage = 1
update_icon()

View File

@@ -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("<span class='warning'>\The [user] hits \the [src] with \a [W]!</span>")

View File

@@ -175,15 +175,15 @@
C.add_fingerprint(user)
cell = C
C.loc = src
user.visible_message("<span class='notice'>[user] opens the panel on [src] and inserts [C].<span class='notice'>", "<span class='notice'>You open the panel on [src] and insert [C].<span class='notice'>")
user.visible_message("<span class='notice'>[user] opens the panel on [src] and inserts [C].</span>", "<span class='notice'>You open the panel on [src] and insert [C].</span>")
return
if(istype(I, /obj/item/weapon/screwdriver))
if(!cell)
user << "<span class='warning'>There is no power cell installed.<span class='notice'>"
user << "<span class='warning'>There is no power cell installed.</span>"
return
user.visible_message("<span class='notice'>[user] opens the panel on [src] and removes [cell].<span class='notice'>", "<span class='notice'>You open the panel on [src] and remove [cell].<span class='notice'>")
user.visible_message("<span class='notice'>[user] opens the panel on [src] and removes [cell].</span>", "<span class='notice'>You open the panel on [src] and remove [cell].</span>")
cell.add_fingerprint(user)
cell.loc = src.loc
cell = null

View File

@@ -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

View File

@@ -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 << "<span class='warning'>You short out [src]'s maintenance hatch lock.</span>"
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 << "<span class='notice'>Unable to repair with the maintenance panel closed.</span>"
else
user << "<span class='notice'>[src] does not need a repair.</span>"
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()

View File

@@ -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 << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
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]", "<span class='notice'>You open [src]'s maintenance hatch.")
src.visible_message("[user] opens the maintenance hatch of [src]", "<span class='notice'>You open [src]'s maintenance hatch.</span>")
on = 0
icon_state="mulebot-hatch"
else
src.visible_message("[user] closes the maintenance hatch of [src]", "<span class='notice'>You close [src]'s maintenance hatch.")
src.visible_message("[user] closes the maintenance hatch of [src]", "<span class='notice'>You close [src]'s maintenance hatch.</span>")
icon_state = "mulebot0"
updateDialog()
@@ -133,6 +128,12 @@
..()
return
/obj/machinery/bot/mulebot/emag_act(var/remaining_charges, var/user)
locked = !locked
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
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)

View File

@@ -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

View File

@@ -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 << "<span class='notice'>\The [src] processes \the [W].</span>"
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

View File

@@ -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()
..()

View File

@@ -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))

View File

@@ -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("<span class='warning'>\The [user] swipes \a [I] through \the [src], causing the screen to flash!</span>",\
"<span class='warning'>You swipe your [I] through \the [src], the screen flashing as you gain full control.</span>",\
"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("<span class='warning'>\The [user] does something \the [src], causing the screen to flash!</span>",\
"<span class='warning'>You cause the screen to flash as you gain full control.</span>",\
"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)

View File

@@ -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 << "<span class='notice'>You authorised the circuit network!</span>"
updateDialog()
else
user << "<span class='warning'>You must select a camera network circuit!</span>"
else if(istype(I,/obj/item/weapon/screwdriver))
secured = !secured
user.visible_message("<span class='notice'>The [src] can [secured ? "no longer" : "now"] be modified.</span>")
@@ -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 << "<span class='notice'>You authorised the circuit network!</span>"
updateDialog()
else
usr << "<span class='warning'>You must select a camera network circuit!</span>"
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 << "<span class='notice'>You authorised the circuit network!</span>"
updateDialog()
return 1
else
user << "<span class='warning'>You must select a camera network circuit!</span>"

View File

@@ -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)

View File

@@ -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()
..()

View File

@@ -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)

View File

@@ -37,10 +37,18 @@
return
if(!istype(user))
return
if(istype(O,/obj/item/weapon/card/emag/))
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
user << "<span class='warning'>It is too hot to mess with!</span>"
return
..()
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)
if(!emag && operable())
if(!isnull(src.linkedServer))
icon_state = hack_icon // An error screen I made in the computers.dmi
emag = 1
@@ -53,15 +61,9 @@
MK.info += "<br><br><font color='red'>£%@%(*$%&(£&?*(%&£/{}</font>"
spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
message = rebootmsg
return 1
else
user << "<span class='notice'>A no server error appears on the screen.</span>"
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
user << "<span class='warning'>It is too hot to mess with!</span>"
return
..()
return
/obj/machinery/computer/message_monitor/update_icon()
..()

View File

@@ -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)

View File

@@ -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 << "<span class='notice'>You disable the lock.</span>"
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 << "<span class='notice'>You disable the lock.</span>"
return 1

View File

@@ -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))
/obj/machinery/computer/specops_shuttle/emag_act(var/remaining_charges, var/mob/user)
user << "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>"
else
return attack_hand(user)
/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 << "<span class='notice'>Central Command will not allow the Special Operations shuttle to return yet.</span>"
if(world.timeofday <= specops_shuttle_timereset)
if (((world.timeofday - specops_shuttle_timereset)/10) > 60)
usr << "<span class='notice'>[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!"
usr << "<span class='notice'>[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!"
usr << "<span class='notice'>[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!</span>"
usr << "<span class='notice'>[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!</span>"
return
usr << "<span class='notice'>The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds.</span>"

View File

@@ -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()

View File

@@ -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 << "<span class='notice'>Special supplies unlocked.</span>"
hacked = 1
return
else
..()
return
return 1
/obj/machinery/computer/supplycomp/Topic(href, href_list)
if(!supply_controller)

View File

@@ -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))
/obj/machinery/computer/syndicate_elite_shuttle/emag_act(var/remaining_charges, var/mob/user)
user << "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>"
else
return attack_hand(user)
/obj/machinery/computer/syndicate_elite_shuttle/attack_hand(var/mob/user as mob)
if(!allowed(user))

View File

@@ -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()
..()

View File

@@ -124,7 +124,7 @@
return
if(!Adjacent(usr))
usr << "You can't reach it.</span>"
usr << "<span class='warning'>You can't reach it.</span>"
return
close_laptop(usr)

View File

@@ -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("<span class='notice'>\The [initial(name)] hums and hisses as it moves [occupant.real_name] into storage.</span>", 3)
// Delete the mob.

View File

@@ -127,11 +127,6 @@ for reference:
dismantle()
return
/obj/structure/barricade/meteorhit()
visible_message("<span class='danger'>\The [src] is smashed apart!</span>")
dismantle()
return
/obj/structure/barricade/blob_act()
src.health -= 25
if (src.health <= 0)
@@ -191,25 +186,6 @@ for reference:
visible_message("<span class='warning'>BZZzZZzZZzZT</span>")
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("<span class='warning'>BZZzZZzZZzZT</span>")
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("<span class='warning'>BZZzZZzZZzZT</span>")
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("<span class='warning'>BZZzZZzZZzZT</span>")
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("<span class='warning'>BZZzZZzZZzZT</span>")
return 1

View File

@@ -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(..())

View File

@@ -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

View File

@@ -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)

View File

@@ -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 += "<span class='warning'>"
else
o += "<span style='color:blue'>"
o += "<span class='[(dir_alerts[index] & (FIREDOOR_ALERT_HOT|FIREDOOR_ALERT_COLD)) ? "warning" : "color:blue"]'>"
o += "[celsius]&deg;C</span> "
o += "<span style='color:blue'>"
o += "[pressure]kPa</span></li>"

View File

@@ -2,21 +2,20 @@
autoclose = 0
var/locked = 0
Bumped(atom/AM)
/obj/machinery/door/unpowered/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
/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'

View File

@@ -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("<span class='warning'>The glass door was sliced open by [user]!</span>")
flick("[src.base_state]spark", src)
sleep(6)
open()
return 1
//If it's emagged, crowbar can pry electronics out.

View File

@@ -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("<span class='game say'><span class='name'>[src]</span> states coldly, \"[message]\"",2)
O.show_message("<span class='game say'><span class='name'>[src]</span> states coldly, \"[message]\"</span>",2)
/obj/machinery/doppler_array/power_change()

View File

@@ -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)

View File

@@ -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"

View File

@@ -174,16 +174,15 @@ datum/track/New(var/title_name, var/audio)
power_change()
update_icon()
return
if(istype(W, /obj/item/weapon/card/emag))
return ..()
/obj/machinery/media/jukebox/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
emagged = 1
StopPlaying()
visible_message("<span class='danger'>\the [src] makes a fizzling sound.</span>")
log_and_message_admins("emagged \the [src]")
visible_message("<span class='danger'>\The [src] makes a fizzling sound.</span>")
update_icon()
return
return ..()
return 1
/obj/machinery/media/jukebox/proc/StopPlaying()
var/area/main_area = get_area(src)

View File

@@ -84,16 +84,12 @@
..()
usr << "The safety guard is [emagged ? "<span class='danger'>disabled</span>" : "enabled"]."
/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 << "<span class='danger'>Access denied.</span>"
return
/obj/machinery/gibber/emag_act(var/remaining_charges, var/mob/user)
emagged = !emagged
user << "<span class='danger'>You [emagged ? "disable" : "enable"] the gibber safety guard.</span>"
return
return 1
/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user)
var/obj/item/weapon/grab/G = W
if(!istype(G))

View File

@@ -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 << "<span class='notice'>\The [src] smartly refuses [O].</span>"
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)

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More