mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-28 19:12:01 +00:00
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:
15
.travis.yml
15
.travis.yml
@@ -2,12 +2,16 @@
|
||||
language: c
|
||||
|
||||
env:
|
||||
BYOND_MAJOR="507"
|
||||
BYOND_MINOR="1282"
|
||||
BYOND_MAJOR="508"
|
||||
BYOND_MINOR="1287"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install libc6:i386 libgcc1:i386 libstdc++6:i386 -qq
|
||||
- sudo apt-get install python -qq
|
||||
- sudo apt-get install python-pip -qq
|
||||
- sudo pip install PyYaml -q
|
||||
- sudo pip install beautifulsoup4 -q
|
||||
|
||||
install:
|
||||
- curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip
|
||||
@@ -19,4 +23,9 @@ install:
|
||||
script:
|
||||
- shopt -s globstar
|
||||
- (! grep 'step_[xy]' maps/**/*.dmm)
|
||||
- DreamMaker polaris.dme
|
||||
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
|
||||
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; [ $num -le 1355 ])
|
||||
- ( md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int")
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
- python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs
|
||||
- DreamMaker baystation12.dme
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
2
code/__defines/_compile_options.dm
Normal file
2
code/__defines/_compile_options.dm
Normal 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.
|
||||
@@ -80,6 +80,8 @@ var/list/be_special_flags = list(
|
||||
#define MODE_MALFUNCTION "malf"
|
||||
#define MODE_TRAITOR "traitor"
|
||||
|
||||
#define DEFAULT_TELECRYSTAL_AMOUNT 12
|
||||
|
||||
/////////////////
|
||||
////WIZARD //////
|
||||
/////////////////
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
17
code/_helpers/matrices.dm
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
72
code/game/antagonist/_antagonist_setup.dm
Normal file
72
code/game/antagonist/_antagonist_setup.dm
Normal 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()
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
31
code/game/antagonist/antagonist_add.dm
Normal file
31
code/game/antagonist/antagonist_add.dm
Normal 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
|
||||
@@ -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
|
||||
118
code/game/antagonist/antagonist_create.dm
Normal file
118
code/game/antagonist/antagonist_create.dm
Normal 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)
|
||||
17
code/game/antagonist/antagonist_equip.dm
Normal file
17
code/game/antagonist/antagonist_equip.dm
Normal 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
|
||||
@@ -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()
|
||||
@@ -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))
|
||||
@@ -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]")
|
||||
|
||||
61
code/game/antagonist/antagonist_panel.dm
Normal file
61
code/game/antagonist/antagonist_panel.dm
Normal 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 ""
|
||||
29
code/game/antagonist/antagonist_place.dm
Normal file
29
code/game/antagonist/antagonist_place.dm
Normal 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)
|
||||
86
code/game/antagonist/antagonist_print.dm
Normal file
86
code/game/antagonist/antagonist_print.dm
Normal 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
|
||||
@@ -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
|
||||
71
code/game/antagonist/antagonist_update.dm
Normal file
71
code/game/antagonist/antagonist_update.dm
Normal 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)
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
43
code/game/gamemodes/game_mode_latespawn.dm
Normal file
43
code/game/gamemodes/game_mode_latespawn.dm
Normal 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))
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(..())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]°C</span> "
|
||||
o += "<span style='color:blue'>"
|
||||
o += "[pressure]kPa</span></li>"
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user