This commit is contained in:
chopchop1614
2016-08-07 00:16:03 +01:00
77 changed files with 645 additions and 460 deletions
+3
View File
@@ -270,6 +270,9 @@
// Macro to get the current elapsed round time, rather than total world runtime
#define ROUND_TIME (round_start_time ? (world.time - round_start_time) : 0)
// Macro that returns true if it's too early in a round to freely ghost out
#define TOO_EARLY_TO_GHOST (config && (ROUND_TIME < (config.round_abandon_penalty_period)))
// Used by radios to indicate that they have sent a message via something other than subspace
#define RADIO_CONNECTION_FAIL 0
#define RADIO_CONNECTION_NON_SUBSPACE 1
+2 -2
View File
@@ -435,14 +435,14 @@
/proc/SecondsToTicks(var/seconds)
return seconds * 10
proc/pollCandidates(var/Question, var/be_special_type, var/antag_age_check = 0, var/poll_time = 300)
proc/pollCandidates(var/Question, var/be_special_type, var/antag_age_check = 0, var/poll_time = 300, var/ignore_respawnability = 0)
var/roletext = be_special_type ? get_roletext(be_special_type) : null
var/list/mob/dead/observer/candidates = list()
var/time_passed = world.time
if(!Question)
Question = "Would you like to be a special role?"
for(var/mob/dead/observer/G in player_list)
for(var/mob/dead/observer/G in (ignore_respawnability ? player_list : respawnable_list))
if(!G.key || !G.client)
continue
if(be_special_type)
+30 -1
View File
@@ -58,12 +58,41 @@
return 0
//Checks for specific types in a list
/proc/is_type_in_list(var/atom/A, var/list/L)
/proc/is_type_in_list(atom/A, list/L)
if(!L || !L.len || !A)
return 0
for(var/type in L)
if(istype(A, type))
return 1
return 0
//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches')
/proc/is_type_in_typecache(atom/A, list/L)
if(!L || !L.len || !A)
return 0
return L[A.type]
//Like typesof() or subtypesof(), but returns a typecache instead of a list
/proc/typecacheof(path, ignore_root_path)
if(ispath(path))
var/list/types = ignore_root_path ? subtypesof(path) : typesof(path)
var/list/L = list()
for(var/T in types)
L[T] = TRUE
return L
else if(islist(path))
var/list/pathlist = path
var/list/L = list()
if(ignore_root_path)
for(var/P in pathlist)
for(var/T in subtypesof(P))
L[T] = TRUE
else
for(var/P in pathlist)
for(var/T in typesof(P))
L[T] = TRUE
return L
//Removes any null entries from the list
/proc/listclearnulls(list/list)
if(istype(list))
+1
View File
@@ -22,6 +22,7 @@ var/global/list/spirits = list() //List of all the spirits, including Masks
var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
var/global/list/respawnable_list = list() //List of all mobs, dead or in mindless creatures that still be respawned.
var/global/list/non_respawnable_keys = list() //List of ckeys that are excluded from respawning for remainder of round.
var/global/list/simple_animal_list = list() //List of all simple animals, including clientless
var/global/list/snpc_list = list() //List of all snpc's, including clientless
+2 -3
View File
@@ -165,7 +165,7 @@ The box in your backpack has an oxygen tank and gas mask in it."
name = "Too Cold"
desc = "You're freezing cold! Get somewhere warmer and take off any insulating clothing like a space suit."
icon_state = "cold"
/obj/screen/alert/cold/drask
name = "Cold"
desc = "You're breathing supercooled gas! It's stimulating your metabolism to regenerate damaged tissue."
@@ -400,8 +400,7 @@ so as to remain in compliance with the most up-to-date laws."
return usr.client.Click(master, location, control, params)
/obj/screen/alert/Destroy()
..()
severity = 0
master = null
screen_loc = ""
return QDEL_HINT_QUEUE
return ..()
+1 -2
View File
@@ -63,9 +63,8 @@
var/severity = 0
/obj/screen/fullscreen/Destroy()
..()
severity = 0
return QDEL_HINT_HARDDEL_NOW
return ..()
/obj/screen/fullscreen/brute
icon_state = "brutedamageoverlay"
+1 -1
View File
@@ -321,7 +321,7 @@
mymob.healths = new /obj/screen/healths()
infodisplay += mymob.healths
mymob.healthdoll = new /obj/screen/healthdoll()
mymob.healthdoll = new()
infodisplay += mymob.healthdoll
mymob.pullin = new /obj/screen/pull()
+1 -1
View File
@@ -102,7 +102,7 @@
mymob.healths = new /obj/screen/healths()
infodisplay += mymob.healths
mymob.healthdoll = new /obj/screen/healthdoll()
mymob.healthdoll = new()
infodisplay += mymob.healthdoll
mymob.pullin = new /obj/screen/pull()
+1
View File
@@ -468,3 +468,4 @@
name = "health doll"
icon_state = "healthdoll_DEAD"
screen_loc = ui_healthdoll
var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays
+4
View File
@@ -61,6 +61,7 @@
var/ToRban = 0
var/automute_on = 0 //enables automuting/spam prevention
var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
var/round_abandon_penalty_period = 30 MINUTES // Time from round start during which ghosting out is penalized
var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors
@@ -560,6 +561,9 @@
if("max_loadout_points")
config.max_loadout_points = text2num(value)
if("round_abandon_penalty_period")
config.round_abandon_penalty_period = MinutesToTicks(text2num(value))
else
diary << "Unknown setting in configuration: '[name]'"
+2 -2
View File
@@ -12,7 +12,6 @@
range = 7
cooldown_min = 30 //30 deciseconds reduction per rank
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human)
action_icon_state = "barn"
@@ -26,7 +25,8 @@
if(!target)
return
if((target.type in compatible_mobs) || ishuman(target))
if(!ishuman(target))
to_chat(user, "<span class='notice'>It'd be stupid to curse [target] with a horse's head!</span>")
return
+2 -2
View File
@@ -894,8 +894,8 @@ var/list/uplink_items = list()
cost = 1
/datum/uplink_item/device_tools/surgerybag
name = "Syndicate Surgery Dufflebag"
desc = "The Syndicate surgery dufflebag is a toolkit containing all surgery tools, a straitjacket, and a muzzle."
name = "Syndicate Surgery Duffelbag"
desc = "The Syndicate surgery duffelbag is a toolkit containing all surgery tools, a straitjacket, and a muzzle."
reference = "SSDB"
item = /obj/item/weapon/storage/backpack/duffel/syndie/surgery
cost = 4
+1 -1
View File
@@ -72,7 +72,7 @@ var/global/max_secret_rooms = 6
treasureitems = list(/obj/item/device/soulstone=1, /obj/item/clothing/suit/space/cult=1, /obj/item/weapon/bedsheet/cult=2,
/obj/item/clothing/suit/hooded/cultrobes=2, /mob/living/simple_animal/hostile/creature=3)
fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2,
/obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/woodentable=2,/obj/item/weapon/ectoplasm=3,
/obj/item/organ/internal/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/woodentable=2,/obj/item/weapon/reagent_containers/food/snacks/ectoplasm=3,
/obj/item/clothing/head/helmet/space/cult=1, /obj/item/clothing/shoes/cult=1)
if("wizden")
+1 -1
View File
@@ -273,7 +273,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
owner.attack_log += text("\[[time_stamp()]\] <font color='red'>Bit [H] ([H.ckey]) in the neck and draining their blood</font>")
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been bit in the neck by [owner] ([owner.ckey])</font>")
log_attack("[owner] ([owner.ckey]) bit [H] ([H.ckey]) in the neck")
owner.visible_message("<span class='danger'>[owner] grabs [H]'s harshly and sinks in thier fangs!</span>", "<span class='danger'>You sink your fangs into [H] and begin to drain their blood.</span>", "<span class='notice'>You hear a soft puncture and a wet sucking noise.</span>")
owner.visible_message("<span class='danger'>[owner] grabs [H]'s neck harshly and sinks in their fangs!</span>", "<span class='danger'>You sink your fangs into [H] and begin to drain their blood.</span>", "<span class='notice'>You hear a soft puncture and a wet sucking noise.</span>")
if(!iscarbon(owner))
H.LAssailant = null
else
+5
View File
@@ -39,6 +39,11 @@
src.colorlist += D
/obj/machinery/pdapainter/Destroy()
if(storedpda)
qdel(storedpda)
storedpda = null
return ..()
/obj/machinery/pdapainter/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/device/pda))
+7 -7
View File
@@ -43,7 +43,7 @@
loopings += ident_tag
loopings[ident_tag] = 0
break
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
for(var/ident_tag in id_tags)
if((M.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags))
@@ -69,7 +69,7 @@
loopings[ident_tag] = 0
break
if(!(ident_tag in synced))
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if((M.id_tag == ident_tag) && !(ident_tag in synced) && !(ident_tag in door_only_tags))
door_only_tags += ident_tag
@@ -90,7 +90,7 @@
visible_message("Cannot locate any mass driver of that ID. Cancelling firing sequence!")
return
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if(M.id_tag == ident_tag)
spawn()
@@ -104,7 +104,7 @@
M.drive()
sleep(50)
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if(M.id_tag == ident_tag)
spawn()
@@ -242,7 +242,7 @@
maxtimes[ident_tag] = min(max(round(maxtimes[ident_tag]), 0), 120)
if(href_list["door"])
var/ident_tag = href_list["driver"]
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if(M.id_tag == ident_tag)
spawn()
@@ -315,7 +315,7 @@
P.failchance = 0//So it has no fail chance when teleporting.
spawn_marauder.Remove(P.target)
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if(M.id_tag == ident_tag)
spawn()
@@ -328,7 +328,7 @@
M.drive()
sleep(50)
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.z != src.z) continue
if(M.id_tag == ident_tag)
spawn()
+17 -4
View File
@@ -174,7 +174,9 @@
var/mob/living/occupant = null // Person waiting to be despawned.
var/orient_right = null // Flips the sprite.
var/time_till_despawn = 9000 // 15 minutes-ish safe period before being despawned.
// 15 minutes-ish safe period before being despawned.
var/time_till_despawn = 9000 // This is reduced by 90% if a player manually enters cryo
var/willing_time_divisor = 10
var/time_entered = 0 // Used to keep track of the safe period.
var/obj/item/device/radio/intercom/announce //
@@ -382,7 +384,12 @@
announce.autosay("[occupant.real_name] [on_store_message]", "[on_store_name]")
visible_message("<span class='notice'>\The [src] hums and hisses as it moves [occupant.real_name] into storage.</span>")
// Delete the mob.
// Ghost and delete the mob.
if(!occupant.get_ghost(1))
if(TOO_EARLY_TO_GHOST)
occupant.ghostize(0) // Players despawned too early may not re-enter the game
else
occupant.ghostize(1)
qdel(occupant)
occupant = null
name = initial(name)
@@ -404,6 +411,7 @@
var/willing = null //We don't want to allow people to be forced into despawning.
var/mob/living/M = G:affecting
time_till_despawn = initial(time_till_despawn)
if(!istype(M) || M.stat == DEAD)
to_chat(user, "<span class='notice'>Dead people can not be put into cryo.</span>")
@@ -412,7 +420,7 @@
if(M.client)
if(alert(M,"Would you like to enter long-term storage?",,"Yes","No") == "Yes")
if(!M || !G || !G:affecting) return
willing = 1
willing = willing_time_divisor
else
willing = 1
@@ -433,6 +441,8 @@
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
time_till_despawn = initial(time_till_despawn) / willing
else //because why the fuck would you keep going if the mob isn't in the pod
to_chat(user, "<span class='notice'>You stop putting [M] into the cryopod.</span>")
return
@@ -502,11 +512,12 @@
var/willing = null //We don't want to allow people to be forced into despawning.
time_till_despawn = initial(time_till_despawn)
if(L.client)
if(alert(L,"Would you like to enter cryosleep?",,"Yes","No") == "Yes")
if(!L) return
willing = 1
willing = willing_time_divisor
else
willing = 1
@@ -523,6 +534,7 @@
to_chat(user, "<span class='boldnotice'>\The [src] is in use.</span>")
return
L.loc = src
time_till_despawn = initial(time_till_despawn) / willing
if(L.client)
L.client.perspective = EYE_PERSPECTIVE
@@ -622,6 +634,7 @@
usr.client.eye = src
usr.loc = src
src.occupant = usr
time_till_despawn = initial(time_till_despawn) / willing_time_divisor
if(orient_right)
icon_state = "[occupied_icon_state]-r"
+1 -1
View File
@@ -109,7 +109,7 @@
D.safe = 1
else
for(var/obj/machinery/door/poddoor/M in world)
for(var/obj/machinery/door/poddoor/M in airlocks)
if(M.id_tag == src.id)
if(M.density)
spawn( 0 )
+1 -1
View File
@@ -980,7 +980,7 @@ About the new airlock wires panel:
wires = new(src)
if(src.closeOtherId != null)
spawn (5)
for(var/obj/machinery/door/airlock/A in world)
for(var/obj/machinery/door/airlock/A in airlocks)
if(A.closeOtherId == src.closeOtherId && A != src)
src.closeOther = A
break
+7 -1
View File
@@ -19,6 +19,12 @@
src.cell = new(src)
..()
/obj/machinery/floodlight/Destroy()
if(cell)
qdel(cell)
cell = null
return ..()
/obj/machinery/floodlight/proc/updateicon()
icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
@@ -31,7 +37,7 @@
set_light(0)
src.visible_message("<span class='warning'>[src] shuts down due to lack of power!</span>")
return
/obj/machinery/floodlight/attack_ai(mob/user as mob)
return
+2
View File
@@ -544,6 +544,8 @@ Class Procs:
return 0
if(!prob(prb))
return 0
if((TK in user.mutations) && !Adjacent(user))
return 0
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
+6
View File
@@ -19,6 +19,12 @@
update_icon()
return
/obj/machinery/space_heater/Destroy()
if(cell)
qdel(cell)
cell = null
return ..()
/obj/machinery/space_heater/update_icon()
overlays.Cut()
icon_state = "sheater[on]"
@@ -61,36 +61,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(long_range_link == 0 && machine.long_range_link == 0)
continue
// If we're sending a copy, be sure to create the copy for EACH machine and paste the data
var/datum/signal/copy = new
var/datum/signal/copy
if(copysig)
copy = new
copy.transmission_method = 2
copy.frequency = signal.frequency
// Copy the main data contents! Workaround for some nasty bug where the actual array memory is copied and not its contents.
copy.data = list(
"mob" = signal.data["mob"],
"mobtype" = signal.data["mobtype"],
"realname" = signal.data["realname"],
"name" = signal.data["name"],
"job" = signal.data["job"],
"key" = signal.data["key"],
"vmessage" = signal.data["vmessage"],
"vname" = signal.data["vname"],
"vmask" = signal.data["vmask"],
"compression" = signal.data["compression"],
"message" = signal.data["message"],
"connection" = signal.data["connection"],
"radio" = signal.data["radio"],
"slow" = signal.data["slow"],
"traffic" = signal.data["traffic"],
"type" = signal.data["type"],
"server" = signal.data["server"],
"reject" = signal.data["reject"],
"level" = signal.data["level"],
"verb" = signal.data["verb"],
"language" = signal.data["language"]
)
copy.data = signal.data.Copy()
// Keep the "original" signal constant
if(!signal.data["original"])
@@ -98,15 +74,11 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
else
copy.data["original"] = signal.data["original"]
else
qdel(copy)
send_count++
if(machine.is_freq_listening(signal))
machine.traffic++
if(copysig && copy)
if(copysig)
machine.receive_information(copy, src)
else
machine.receive_information(signal, src)
+2 -2
View File
@@ -673,7 +673,7 @@ steam.start() -- spawns the effect
for(var/mob/living/carbon/human/R in get_turf(src))
if(R.internal != null && usr.wear_mask && (R.wear_mask.flags & AIRTIGHT) && R.wear_suit != null && !istype(R.wear_suit, /obj/item/clothing/suit/storage/labcoat) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket && !istype(R.wear_suit, /obj/item/clothing/suit/armor)))
else
R.burn_skin(0.75)
R.adjustFireLoss(0.75)
if(R.coughedtime != 1)
R.coughedtime = 1
R.emote("gasp")
@@ -687,7 +687,7 @@ steam.start() -- spawns the effect
if(istype(R, /mob/living/carbon/human))
if(R.internal != null && usr.wear_mask && (R.wear_mask.flags & AIRTIGHT) && R.wear_suit != null && !istype(R.wear_suit, /obj/item/clothing/suit/storage/labcoat) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket && !istype(R.wear_suit, /obj/item/clothing/suit/armor)))
return
R.burn_skin(0.75)
R.adjustFireLoss(0.75)
if(R.coughedtime != 1)
R.coughedtime = 1
R.emote("gasp")
+6
View File
@@ -18,6 +18,12 @@
ID = new /obj/item/weapon/card/id
ID.access = get_region_accesses(region_access)
/obj/item/weapon/door_remote/Destroy()
if(ID)
qdel(ID)
ID = null
return ..()
/obj/item/weapon/door_remote/attack_self(mob/user)
switch(mode)
if(WAND_OPEN)
@@ -11,7 +11,6 @@
w_class = 2 //Increased to 2, because diodes are w_class 2. Conservation of matter.
origin_tech = "combat=1"
origin_tech = "magnets=2"
var/turf/pointer_loc
var/energy = 5
var/max_energy = 5
var/effectchance = 33
@@ -35,6 +34,12 @@
if(!pointer_icon_state)
pointer_icon_state = pick("red_laser","green_laser","blue_laser","purple_laser")
/obj/item/device/laser_pointer/Destroy()
if(diode)
qdel(diode)
diode = null
return ..()
/obj/item/device/laser_pointer/upgraded/New()
..()
diode = new /obj/item/weapon/stock_parts/micro_laser/ultra
+7 -3
View File
@@ -24,9 +24,13 @@
overlays += "pai-off"
/obj/item/device/paicard/Destroy()
//Will stop people throwing friend pAIs into the singularity so they can respawn
if(!isnull(pai))
pai.death(0)
if(pai)
pai.ghostize()
qdel(pai)
pai = null
if(radio)
qdel(radio)
radio = null
return ..()
/obj/item/device/paicard/attack_self(mob/user)
@@ -20,6 +20,12 @@
mytape = new /obj/item/device/tape/random(src)
update_icon()
/obj/item/device/taperecorder/Destroy()
if(mytape)
qdel(mytape)
mytape = null
return ..()
/obj/item/device/taperecorder/examine(mob/user)
if(..(user, 1))
to_chat(user, "The wire panel is [open_panel ? "opened" : "closed"].")
@@ -283,7 +289,8 @@
timestamp.Cut()
/obj/item/device/tape/proc/ruin()
overlays += "ribbonoverlay"
if(!ruined)
overlays += "ribbonoverlay"
ruined = 1
@@ -11,6 +11,18 @@
var/toggle = 1
origin_tech = "materials=1;engineering=1"
/obj/item/device/transfer_valve/Destroy()
if(tank_one)
qdel(tank_one)
tank_one = null
if(tank_two)
qdel(tank_two)
tank_two = null
if(attached_device)
qdel(attached_device)
attached_device = null
return ..()
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
/obj/item/device/transfer_valve/IsAssemblyHolder()
+6
View File
@@ -11,6 +11,12 @@
var/state
var/datum/gas_mixture/air_contents = null
/obj/item/latexballon/Destroy()
if(air_contents)
qdel(air_contents)
air_contents = null
return ..()
/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank, mob/user)
if(icon_state == "latexballon_bursted")
return
@@ -16,6 +16,14 @@
var/list/loadedItems = list() //The items loaded into the cannon that will be fired out
var/pressureSetting = 1 //How powerful the cannon is - higher pressure = more gas but more powerful throws
/obj/item/weapon/pneumatic_cannon/Destroy()
if(tank)
qdel(tank)
tank = null
for(var/obj/item/I in loadedItems)
qdel(I)
loadedItems.Cut()
return ..()
/obj/item/weapon/pneumatic_cannon/examine(mob/user)
..()
@@ -276,8 +276,8 @@
slowdown = 1
/obj/item/weapon/storage/backpack/duffel/syndie
name = "suspicious looking dufflebag"
desc = "A large dufflebag for holding extra tactical supplies."
name = "suspicious looking duffelbag"
desc = "A large duffelbag for holding extra tactical supplies."
icon_state = "duffel-syndi"
item_state = "duffel-syndimed"
origin_tech = "syndicate=1"
@@ -297,7 +297,7 @@
item_state = "duffel-syndiammo"
/obj/item/weapon/storage/backpack/duffel/syndie/ammo/loaded
desc = "A large dufflebag, packed to the brim with Bulldog shotgun ammo."
desc = "A large duffelbag, packed to the brim with Bulldog shotgun ammo."
/obj/item/weapon/storage/backpack/duffel/syndie/ammo/loaded/New()
..()
@@ -312,10 +312,10 @@
new /obj/item/ammo_box/magazine/m12g/dragon(src)
/obj/item/weapon/storage/backpack/duffel/syndie/surgery
name = "surgery dufflebag"
desc = "A suspicious looking dufflebag for holding surgery tools."
name = "surgery duffelbag"
desc = "A suspicious looking duffelbag for holding surgery tools."
icon_state = "duffel-syndimed"
item_state = "duffle-syndimed"
item_state = "duffel-syndimed"
/obj/item/weapon/storage/backpack/duffel/syndie/surgery/New()
..()
@@ -333,10 +333,10 @@
new /obj/item/device/mmi/syndie(src)
/obj/item/weapon/storage/backpack/duffel/syndie/surgery_fake //for maint spawns
name = "surgery dufflebag"
desc = "A suspicious looking dufflebag for holding surgery tools."
name = "surgery duffelbag"
desc = "A suspicious looking duffelbag for holding surgery tools."
icon_state = "duffel-syndimed"
item_state = "duffle-syndimed"
item_state = "duffel-syndimed"
/obj/item/weapon/storage/backpack/duffel/syndie/surgery_fake/New()
..()
@@ -23,6 +23,12 @@
update_icon()
return
/obj/item/weapon/melee/baton/Destroy()
if(bcell)
qdel(bcell)
bcell = null
return ..()
/obj/item/weapon/melee/baton/CheckParts(list/parts_list)
..()
bcell = locate(/obj/item/weapon/stock_parts/cell) in contents
@@ -35,6 +35,7 @@
/obj/item/weapon/tank/Destroy()
if(air_contents)
qdel(air_contents)
air_contents = null
processing_objects.Remove(src)
+5 -5
View File
@@ -140,7 +140,7 @@
if(get_dist(src,user) > 1)
return 0
if(H != null)
user.visible_message("<span class='notice'>[src.name] is too cumbersome to carry in one hand!</span>")
to_chat(user, "<span class='notice'>[src.name] is too cumbersome to carry in one hand!</span>")
return
var/obj/item/weapon/twohanded/offhand/O = new(user)
user.put_in_inactive_hand(O)
@@ -693,7 +693,7 @@
Z.ex_act(2)
charged = 3
playsound(user, 'sound/weapons/marauder.ogg', 50, 1)
// Energized Fire axe
/obj/item/weapon/twohanded/energizedfireaxe
name = "energized fire axe"
@@ -711,7 +711,7 @@
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
var/charged = 1
/obj/item/weapon/twohanded/energizedfireaxe/update_icon()
if(wielded)
icon_state = "fireaxe2"
@@ -719,7 +719,7 @@
icon_state = "fireaxe0"
/obj/item/weapon/twohanded/energizedfireaxe/afterattack(atom/A, mob/user, proximity)
if(!proximity)
if(!proximity)
return
if(wielded)
if(istype(A, /mob/living))
@@ -732,7 +732,7 @@
var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread
sparks.set_up(1, 1, src)
sparks.start()
if(A && wielded && (istype(A, /obj/structure/window) || istype(A, /obj/structure/grille)))
if(istype(A, /obj/structure/window))
var/obj/structure/window/W = A
@@ -77,13 +77,10 @@
s.start()
visible_message("<span class='danger'>The electric chair went off!</span>", "<span class='danger'>You hear a deep sharp shock!</span>")
if(buckled_mob)
buckled_mob.burn_skin(90)
buckled_mob.electrocute_act(110, src, 1)
to_chat(buckled_mob, "<span class='danger'>You feel a deep shock course through your body!</span>")
sleep(1)
buckled_mob.burn_skin(90)
sleep(5)
buckled_mob.burn_skin(max(rand(5,20),rand(5,20),rand(5,20)))
spawn(1)
buckled_mob.electrocute_act(110, src, 1)
A.power_light = light
A.updateicon()
return
+2
View File
@@ -361,6 +361,8 @@
user.attack_log +="\[[time_stamp()]\] <font color='red'>Cremated [M.name] ([M.ckey])</font>"
log_attack("[user.name] ([user.ckey]) cremated [M.name] ([M.ckey])")
M.death(1)
if(!M || !isnull(M.gcDestroyed))
continue // Re-check for mobs that delete themselves on death
M.ghostize()
qdel(M)
+6 -2
View File
@@ -114,13 +114,17 @@ var/ert_request_answered = 0
active_team = response_team_type
send_emergency_team = 1
var/list/ert_candidates = pollCandidates("Join the Emergency Response Team?",, responseteam_age, 600)
var/list/ert_candidates = pollCandidates("Join the Emergency Response Team?",, responseteam_age, 600, 1)
if(!ert_candidates.len)
active_team.cannot_send_team()
send_emergency_team = 0
return
var/teamsize = 0
for(var/mob/dead/observer/M in ert_candidates)
// Respawnable players get first dibs
for(var/mob/dead/observer/M in (ert_candidates & respawnable_list))
teamsize += M.JoinResponseTeam()
// If there's still open slots, non-respawnable players can fill them
for(var/mob/dead/observer/M in (ert_candidates - respawnable_list))
teamsize += M.JoinResponseTeam()
send_emergency_team = 0
if (!teamsize)
+1 -1
View File
@@ -613,7 +613,7 @@
var/obj/effect/buildmode_line/L2 = new(holder, P, M, "[M.name] to [P.name]") // Yes, reversed one so that you can see it from both sides.
L2.color = L.color
link_lines += L2
for(var/obj/machinery/door/poddoor/P in world)
for(var/obj/machinery/door/poddoor/P in airlocks)
if(P.id_tag == M.id)
var/obj/effect/buildmode_line/L = new(holder, M, P, "[M.name] to [P.name]")
L.color = M.normaldoorcontrol ? "#993333" : "#339933"
+2 -8
View File
@@ -38,13 +38,7 @@
<A href='?src=\ref[src];secretsfun=power'>Make all areas powered</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=unpower'>Make all areas unpowered</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=quickpower'>Power all SMES</A><BR>
<BR>
<B>Shuttle options</b><br>
<A href='?src=\ref[src];secretsfun=launchshuttle'>Launch a shuttle</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=forcelaunchshuttle'>Force launch a shuttle</A><BR>
<A href='?src=\ref[src];secretsfun=jumpshuttle'>Jump a shuttle</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=moveshuttle'>Move a shuttle</A><BR>
<BR></center>
</center>
"}
else if(check_rights(R_SERVER,0)) //only add this if admin secrets are unavailiable; otherwise, it's added inline
@@ -73,7 +67,7 @@
<center>
<h2><B>IC Events</B></h2>
<b>Teams</b><br>
<A href='?src=\ref[src];secretsfun=striketeam'>Send in a strike team</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=striketeam'>Send in the Deathsquad</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=striketeam_syndicate'>Send in a syndicate strike team</A>&nbsp;&nbsp;
<A href='?src=\ref[src];secretsfun=honksquad'>Send in a HONKsquad</A><BR>
<b>Change Security Level</b><BR>
+4 -3
View File
@@ -1252,6 +1252,7 @@
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] back to the Lobby.")
var/mob/new_player/NP = new()
non_respawnable_keys -= M.ckey
NP.ckey = M.ckey
qdel(M)
@@ -2564,7 +2565,7 @@
if("eagles")//SCRAW
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","EgL")
for(var/obj/machinery/door/airlock/W in world)
for(var/obj/machinery/door/airlock/W in airlocks)
// TODO: Tie into space manager
if((W.z in config.station_levels) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
@@ -2758,12 +2759,12 @@
dat += "No-one has done anything this round!"
usr << browse(dat, "window=admin_log")
if("maint_access_brig")
for(var/obj/machinery/door/airlock/maintenance/M in world)
for(var/obj/machinery/door/airlock/maintenance/M in airlocks)
if(access_maint_tunnels in M.req_access)
M.req_access = list(access_brig)
message_admins("[key_name_admin(usr)] made all maint doors brig access-only.")
if("maint_access_engiebrig")
for(var/obj/machinery/door/airlock/maintenance/M in world)
for(var/obj/machinery/door/airlock/maintenance/M in airlocks)
if(access_maint_tunnels in M.req_access)
M.req_access = list()
M.req_one_access = list(access_brig,access_engine)
+15 -9
View File
@@ -1371,19 +1371,25 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(alert("Are you sure? This will start up the engine. Should only be used during debug!",,"Yes","No") != "Yes")
return
for(var/obj/machinery/power/emitter/E in world)
for(var/obj/machinery/power/emitter/E in machines)
if(E.anchored)
E.active = 1
for(var/obj/machinery/field/generator/F in world)
if(F.anchored)
F.Varedit_start = 1
for(var/obj/machinery/field/generator/F in machines)
if(F.active == 0)
F.active = 1
F.state = 2
F.power = 250
F.anchored = 1
F.warming_up = 3
F.start_fields()
F.update_icon()
spawn(30)
for(var/obj/machinery/the_singularitygen/G in world)
for(var/obj/machinery/the_singularitygen/G in machines)
if(G.anchored)
var/obj/singularity/S = new /obj/singularity(get_turf(G), 50)
spawn(0)
qdel(G)
// qdel(G)
S.energy = 1750
S.current_size = 7
S.icon = 'icons/effects/224x224.dmi'
@@ -1397,7 +1403,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
//S.dissipate_track = 0
//S.dissipate_strength = 10
for(var/obj/machinery/power/rad_collector/Rad in world)
for(var/obj/machinery/power/rad_collector/Rad in machines)
if(Rad.anchored)
if(!Rad.P)
var/obj/item/weapon/tank/plasma/Plasma = new/obj/item/weapon/tank/plasma(Rad)
@@ -1409,7 +1415,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!Rad.active)
Rad.toggle_power()
for(var/obj/machinery/power/smes/SMES in world)
for(var/obj/machinery/power/smes/SMES in machines)
if(SMES.anchored)
SMES.input_attempt = 1
+6 -5
View File
@@ -21,7 +21,7 @@ var/global/list/frozen_mob_list = list()
///mob freeze procs
/mob/living/var/frozen = 0 //used for preventing attacks on admin-frozen mobs
/mob/living/var/frozen = null //used for preventing attacks on admin-frozen mobs
/mob/living/var/admin_prev_sleeping = 0 //used for keeping track of previous sleeping value with admin freeze
/mob/living/proc/admin_Freeze(var/client/admin)
@@ -34,7 +34,7 @@ var/global/list/frozen_mob_list = list()
src.overlays += AO
anchored = 1
frozen = 1
frozen = AO
admin_prev_sleeping = sleeping
sleeping += 20000
if(!(src in frozen_mob_list))
@@ -46,15 +46,16 @@ var/global/list/frozen_mob_list = list()
message_admins("\blue [key_name_admin(admin)] unfroze [key_name_admin(src)]")
log_admin("[key_name(admin)] unfroze [key_name(src)]")
update_icons()
anchored = 0
frozen = 0
overlays -= frozen
frozen = null
sleeping = admin_prev_sleeping
admin_prev_sleeping = null
if(src in frozen_mob_list)
frozen_mob_list -= src
update_icons()
/mob/living/carbon/slime/admin_Freeze(admin)
..(admin)
+1 -1
View File
@@ -410,7 +410,7 @@
name = "black hoodie"
desc = "It's a hoodie. It has a hood. Most hoodies do."
icon_state = "black_hoodie"
item_state = "labcoat"
item_state = "blueshieldcoat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
hoodtype = /obj/item/clothing/head/hood
species_fit = list("Vox")
+1 -1
View File
@@ -1,5 +1,5 @@
/datum/event/meteor_wave/goreop/announce()
var/meteor_declaration = "MeteorOps have declared thier intent to utterly destroy [station_name()] with thier own bodies, and dares the crew to try and stop them."
var/meteor_declaration = "MeteorOps have declared their intent to utterly destroy [station_name()] with their own bodies, and dares the crew to try and stop them."
command_announcement.Announce(meteor_declaration, "Declaration of 'War'", 'sound/effects/siren.ogg')
/datum/event/meteor_wave/goreop/setup()
+2 -3
View File
@@ -17,7 +17,7 @@
if((T.z in config.station_levels))
pick_turfs += T
for(var/i = 1, i <= number_of_wormholes, i++)
for(var/i in 1 to number_of_wormholes)
var/turf/T = pick(pick_turfs)
wormholes += new /obj/effect/portal/wormhole(T, null, null, -1)
@@ -31,9 +31,8 @@
if(T) O.loc = T
/datum/event/wormholes/end()
portals.Remove(wormholes)
for(var/obj/effect/portal/wormhole/O in wormholes)
O.loc = null
qdel(O)
wormholes.Cut()
+2 -2
View File
@@ -55,8 +55,8 @@
/datum/martial_art/mimejutsu/proc/mimePalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(!D.stat && !D.stunned && !D.weakened)
D.visible_message("<span class='danger'>[A] has barely touched [D] with thier palm!</span>", \
"<span class='userdanger'>[A] hovers thier palm over your face!</span>")
D.visible_message("<span class='danger'>[A] has barely touched [D] with their palm!</span>", \
"<span class='userdanger'>[A] hovers their palm over your face!</span>")
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
D.throw_at(throw_target, 200, 4,A)
+4
View File
@@ -3,5 +3,9 @@
if(ghostimage)
ghostimage.icon_state = src.icon_state
updateghostimages()
if(non_respawnable_keys[ckey])
can_reenter_corpse = 0
respawnable_list -= src
update_interface()
+24 -5
View File
@@ -129,11 +129,15 @@ Works together with spawning an observer, noted above.
/mob/proc/ghostize(var/flags = GHOST_CAN_REENTER)
if(key)
if(non_respawnable_keys[ckey])
flags &= ~GHOST_CAN_REENTER
var/mob/dead/observer/ghost = new(src, flags) //Transfer safety to observer spawning proc.
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
respawnable_list -= src
if(ghost.can_reenter_corpse)
respawnable_list += ghost
else
non_respawnable_keys[ckey] = 1
ghost.key = key
if(!(ghost.client && ghost.client.holder) && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
@@ -148,12 +152,28 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Relinquish your life and enter the land of the dead."
var/mob/M = src
var/warningmsg = null
var/obj/machinery/cryopod/P = istype(loc, /obj/machinery/cryopod) && loc
if(stat == DEAD)
if(P)
if(TOO_EARLY_TO_GHOST)
warningmsg = "It's too early in the shift to enter cryo"
// If it's not too early, we'll skip straight to ghosting out without penalty
else if(suiciding && TOO_EARLY_TO_GHOST)
warningmsg = "You have committed suicide too early in the round"
else if(stat != DEAD)
warningmsg = "You are alive"
else if(non_respawnable_keys[ckey])
warningmsg = "You have lost your right to respawn"
if(!warningmsg)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost") return //didn't want to ghost after-all
var/response
var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)"
response = alert(src, alertmsg,"Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return //didn't want to ghost after-all
resting = 1
var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
@@ -162,8 +182,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
Morgue = M.loc
if(Morgue)
Morgue.update()
if(istype(M.loc, /obj/machinery/cryopod))
var/obj/machinery/cryopod/P = M.loc
if(P)
if(!P.control_computer)
P.find_control_computer(urgent=1)
if(P.control_computer)
@@ -13,6 +13,7 @@
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/silenced = 0 //if set to 1, they can't talk.
var/next_ping_at = 0
/obj/item/device/mmi/posibrain/attack_self(mob/user as mob)
@@ -53,6 +54,8 @@
return 0
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
return 0
if(!O.can_reenter_corpse)
return 0
if(O.client)
return 1
return 0
@@ -190,7 +193,11 @@
/obj/item/device/mmi/posibrain/attack_ghost(var/mob/dead/observer/O)
if(searching)
volunteer(O)
else
return
if(brainmob && brainmob.key)
return // No point pinging a posibrain with a player already inside
if(check_observer(O) && (world.time >= next_ping_at))
next_ping_at = world.time + (20 SECONDS)
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
M.show_message("\blue The positronic brain pings softly.")
@@ -2,7 +2,7 @@
var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
if(eyes)
eyes.update_colour()
regenerate_icons()
update_body()
/mob/living/carbon/human/var/list/organs = list()
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
@@ -614,6 +614,8 @@
H.clear_alert("high")
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(!H.client)
return
if(H.healths)
if(H.stat == DEAD)
H.healths.icon_state = "health7"
@@ -633,11 +635,15 @@
else H.healths.icon_state = "health6"
if(H.healthdoll)
H.healthdoll.overlays.Cut()
if(H.stat == DEAD)
H.healthdoll.icon_state = "healthdoll_DEAD"
if(H.healthdoll.overlays.len)
H.healthdoll.overlays.Cut()
else
H.healthdoll.icon_state = "healthdoll_OVERLAY"
var/list/new_overlays = list()
var/list/cached_overlays = H.healthdoll.cached_healthdoll_overlays
// Use the dead health doll as the base, since we have proper "healthy" overlays now
H.healthdoll.icon_state = "healthdoll_DEAD"
for(var/obj/item/organ/external/O in H.organs)
var/damage = O.burn_dam + O.brute_dam
var/comparison = (O.max_damage/5)
@@ -652,8 +658,10 @@
icon_num = 4
if(damage > (comparison*4))
icon_num = 5
if(icon_num)
H.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[O.limb_name][icon_num]")
new_overlays += "[O.limb_name][icon_num]"
H.healthdoll.overlays += (new_overlays - cached_overlays)
H.healthdoll.overlays -= (cached_overlays - new_overlays)
H.healthdoll.cached_healthdoll_overlays = new_overlays
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
@@ -107,17 +107,7 @@ Please contact me on #coderbus IRC. ~Carn x
var/list/overlays_standing[TOTAL_LAYERS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
var/icon/skeleton
/mob/living/carbon/human/proc/apply_overlay(cache_index)
var/image/I = overlays_standing[cache_index]
if(I)
overlays += I
/mob/living/carbon/human/proc/remove_overlay(cache_index)
if(overlays_standing[cache_index])
overlays -= overlays_standing[cache_index]
overlays_standing[cache_index] = null
var/list/cached_standing_overlays = list() // List of everything currently in a human's actual overlays
//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
@@ -125,6 +115,7 @@ Please contact me on #coderbus IRC. ~Carn x
/mob/living/carbon/human/update_icons()
var/stealth = 0
var/obj/item/clothing/suit/armor/abductor/vest/V // Begin the most snowflakey bullshit code I've ever written. I'm so sorry, but there was no other way.
for(V in list(wear_suit))
if(V.stealth_active)
stealth = 1
@@ -133,6 +124,7 @@ Please contact me on #coderbus IRC. ~Carn x
if(stealth)
icon = V.disguise.icon //if the suit is active, reference the suit's current loaded icon and overlays; this does not include hand overlays
overlays.Cut()
cached_standing_overlays.Cut() // Make sure the cache gets rebuilt once the disguise is gone
for(var/thing in V.disguise.overlays)
if(thing)
@@ -146,10 +138,28 @@ Please contact me on #coderbus IRC. ~Carn x
overlays += I
else
icon = stand_icon
overlays.Cut()
var/list/new_overlays = list()
var/list/old_overlays = cached_standing_overlays
for(var/thing in overlays_standing)
if(thing) overlays += thing
// Totally regenerate if something touched our overlays
if(overlays.len != old_overlays.len)
overlays.Cut()
old_overlays.Cut()
for(var/i in 1 to TOTAL_LAYERS)
var/image/I = overlays_standing[i]
if(I)
if(istype(I))
// Since we avoid full overlay rebuilds, we have to reorganize the layers manually
I.layer = (-2 - (TOTAL_LAYERS - i)) // Highest layer gets -2, each prior layer is 1 lower
new_overlays += I
if(frozen) // Admin freeze overlay
new_overlays += frozen
overlays += (new_overlays - old_overlays)
overlays -= (old_overlays - new_overlays)
cached_standing_overlays = new_overlays
update_transform()
@@ -538,12 +548,13 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_fire()
remove_overlay(FIRE_LAYER)
if(on_fire)
overlays_standing[FIRE_LAYER] = image("icon"=fire_dmi, "icon_state"=fire_sprite, "layer"=-FIRE_LAYER)
if(!overlays_standing[FIRE_LAYER])
overlays_standing[FIRE_LAYER] = image("icon"=fire_dmi, "icon_state"=fire_sprite)
update_icons()
else
overlays_standing[FIRE_LAYER] = null
apply_overlay(FIRE_LAYER)
update_icons()
/* --------------------------------------- */
//For legacy support.
@@ -574,11 +585,12 @@ var/global/list/damage_icon_parts = list()
update_inv_legcuffed(0)
update_inv_pockets(0)
update_inv_wear_pda(0)
UpdateDamageIcon()
update_icons()
update_fire()
UpdateDamageIcon(0)
force_update_limbs()
update_tail_layer(0)
overlays.Cut() // Force all overlays to regenerate
update_fire()
update_icons()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
-16
View File
@@ -92,22 +92,6 @@
/mob/living/proc/calculate_affecting_pressure(var/pressure)
return 0
//sort of a legacy burn method for /electrocute, /shock, and the e_chair
/mob/living/proc/burn_skin(burn_amount)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part
var/divided_damage = (burn_amount)/(H.organs.len)
var/extradam = 0 //added to when organ is at max dam
for(var/obj/item/organ/external/affecting in H.organs)
if(!affecting) continue
if(affecting.take_damage(0, divided_damage+extradam)) //TODO: fix the extradam stuff. Or, ebtter yet...rewrite this entire proc ~Carn
H.UpdateDamageIcon()
H.updatehealth()
return 1
else if(istype(src, /mob/living/silicon/ai))
return 0
/mob/living/proc/adjustBodyTemp(actual, desired, incrementboost)
var/temperature = actual
var/difference = abs(actual-desired) //get difference
@@ -113,7 +113,7 @@
if(istype(src,/mob/dead/observer))
var/mob/dead/observer/G = src
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
to_chat(usr, "\blue <B>Upon using the antagHUD you forfeited the ability to join the round.</B>")
to_chat(usr, "<span class='warning'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
return
if(G.started_as_observer == 1)
joinedasobserver = 1
@@ -133,6 +133,9 @@
to_chat(usr, "<span class='warning'>You must wait 10 minutes to respawn as a drone!</span>")
return
if(alert("Are you sure you want to respawn as a drone?", "Are you sure?", "Yes", "No") != "Yes")
return
for(var/obj/machinery/drone_fabricator/DF in world)
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
+1 -1
View File
@@ -22,7 +22,7 @@
*/
var/obj/screen/zone_sel/zone_sel = null
var/obj/screen/leap_icon = null
var/obj/screen/healthdoll = null
var/obj/screen/healthdoll/healthdoll = null
var/use_me = 1 //Allows all mobs to use the me verb by default, will have to manually specify they cannot
var/damageoverlaytemp = 0
@@ -15,10 +15,8 @@
var/obj/machinery/field/generator/FG2 = null
/obj/machinery/field/containment/Destroy()
if(FG1 && !FG1.clean_up)
FG1.cleanup()
if(FG2 && !FG2.clean_up)
FG2.cleanup()
FG1.fields -= src
FG2.fields -= src
return ..()
/obj/machinery/field/containment/attack_hand(mob/user)
@@ -67,35 +65,26 @@
/obj/machinery/field
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
/obj/machinery/field/CanPass(mob/mover, turf/target, height=0)
/obj/machinery/field/CanPass(atom/movable/mover, turf/target, height=0)
if(hasShocked)
return 0
if(isliving(mover)) // Don't let mobs through
shock_field(mover)
return 0
return ..()
/obj/machinery/field/CanPass(obj/mover, turf/target, height=0)
if((istype(mover, /obj/machinery) && !istype(mover, /obj/singularity)) || \
istype(mover, /obj/structure) || \
istype(mover, /obj/mecha))
if(istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha))
bump_field(mover)
return 0
return ..()
/obj/machinery/field/proc/shock_field(mob/living/user)
if(hasShocked)
return 0
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
if(iscarbon(user))
var/stun = min(shock_damage, 15)
user.Stun(stun)
user.Weaken(10)
user.burn_skin(shock_damage)
user.visible_message("<span class='danger'>[user.name] was shocked by the [src.name]!</span>", \
"<span class='userdanger'>You feel a powerful shock course through your body, sending you flying!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>")
user.electrocute_act(shock_damage, src, 1)
else if(issilicon(user))
if(prob(20))
@@ -108,13 +97,14 @@
user.updatehealth()
bump_field(user)
spawn(5)
hasShocked = 0
return
/obj/machinery/field/proc/bump_field(atom/movable/AM as mob|obj)
if(hasShocked)
return 0
hasShocked = 1
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(5, 1, AM.loc)
s.start()
var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src)))
AM.throw_at(target, 200, 4)
spawn(5)
hasShocked = 0
+130 -151
View File
@@ -13,6 +13,15 @@ field_generator power level display
*/
#define field_generator_max_power 250
#define FG_UNSECURED 0
#define FG_SECURED 1
#define FG_WELDED 2
#define FG_OFFLINE 0
#define FG_CHARGING 1
#define FG_ONLINE 2
/obj/machinery/field/generator
name = "Field Generator"
desc = "A large thermal battery that projects a high amount of energy when powered."
@@ -22,134 +31,109 @@ field_generator power level display
density = 1
use_power = 0
var/const/num_power_levels = 6 // Total number of power level icon has
var/Varedit_start = 0
var/Varpower = 0
var/active = 0
var/power_level = 0
var/active = FG_OFFLINE
var/power = 20 // Current amount of power
var/state = 0
var/state = FG_UNSECURED
var/warming_up = 0
var/list/obj/machinery/field/containment/fields
var/list/obj/machinery/field/generator/connected_gens
var/clean_up = 0
/obj/machinery/field/generator/update_icon()
overlays.Cut()
if(warming_up)
overlays += "+a[warming_up]"
if(fields.len)
overlays += "+on"
// Power level indicator
// Scale % power to % num_power_levels and truncate value
var/level = round(num_power_levels * power / field_generator_max_power)
// Clamp between 0 and num_power_levels for out of range power values
level = Clamp(level, 0, num_power_levels)
if(level)
overlays += "+p[level]"
return
if(power_level)
overlays += "+p[power_level]"
/obj/machinery/field/generator/New()
..()
fields = list()
connected_gens = list()
return
/obj/machinery/field/generator/process()
if(Varedit_start == 1)
if(active == 0)
active = 1
state = 2
power = field_generator_max_power
anchored = 1
warming_up = 3
start_fields()
update_icon()
Varedit_start = 0
if(src.active == 2)
if(active == FG_ONLINE)
calc_power()
update_icon()
return
/obj/machinery/field/generator/attack_hand(mob/user)
if(state == 2)
if(state == FG_WELDED)
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
if(src.active >= 1)
to_chat(user, "<span class='warning'>You are unable to turn off the [src.name] once it is online!</span>")
if(active >= FG_CHARGING)
to_chat(user, "<span class='warning'>You are unable to turn off the [name] once it is online!</span>")
return 1
else
user.visible_message("[user.name] turns on the [src.name].", \
"<span class='notice'>You turn on the [src.name].</span>", \
user.visible_message("[user.name] turns on the [name].", \
"<span class='notice'>You turn on the [name].</span>", \
"<span class='italics'>You hear heavy droning.</span>")
turn_on()
investigate_log("<font color='green'>activated</font> by [user.key].","singulo")
src.add_fingerprint(user)
add_fingerprint(user)
else
to_chat(user, "<span class='warning'>The [src] needs to be firmly secured to the floor first!</span>")
return
to_chat(user, "<span class='warning'>[src] needs to be firmly secured to the floor first!</span>")
/obj/machinery/field/generator/attackby(obj/item/W, mob/user, params)
if(active)
to_chat(user, "<span class='warning'>The [src] needs to be off!</span>")
to_chat(user, "<span class='warning'>[src] needs to be off!</span>")
return
else if(istype(W, /obj/item/weapon/wrench))
switch(state)
if(0)
if(FG_UNSECURED)
if(isinspace()) return
state = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
state = FG_SECURED
playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [name] to the floor.", \
"<span class='notice'>You secure the external reinforcing bolts to the floor.</span>", \
"<span class='italics'>You hear ratchet.</span>")
src.anchored = 1
if(1)
state = 0
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \
anchored = 1
if(FG_SECURED)
state = FG_UNSECURED
playsound(loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] unsecures [name] reinforcing bolts from the floor.", \
"<span class='notice'>You undo the external reinforcing bolts.</span>", \
"<span class='italics'>You hear ratchet.</span>")
src.anchored = 0
if(2)
to_chat(user, "<span class='warning'>The [src.name] needs to be unwelded from the floor!</span>")
return
anchored = 0
if(FG_WELDED)
to_chat(user, "<span class='warning'>The [name] needs to be unwelded from the floor!</span>")
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
switch(state)
if(0)
to_chat(user, "<span class='warning'>The [src.name] needs to be wrenched to the floor!</span>")
return
if(1)
if(FG_UNSECURED)
to_chat(user, "<span class='warning'>The [name] needs to be wrenched to the floor!</span>")
if(FG_SECURED)
if(WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to weld the [name] to the floor.", \
"<span class='notice'>You start to weld \the [src] to the floor...</span>", \
"<span class='italics'>You hear welding.</span>")
if(do_after(user,20, target = src))
if(!src || !WT.isOn()) return
state = 2
if(!src || !WT.isOn())
return
state = FG_WELDED
to_chat(user, "<span class='notice'>You weld the field generator to the floor.</span>")
else
return
if(2)
if(FG_WELDED)
if(WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to cut the [name] free from the floor.", \
"<span class='notice'>You start to cut \the [src] free from the floor...</span>", \
"<span class='italics'>You hear welding.</span>")
if(do_after(user,20, target = src))
if(!src || !WT.isOn()) return
state = 1
if(!src || !WT.isOn())
return
state = FG_SECURED
to_chat(user, "<span class='notice'>You cut \the [src] free from the floor.</span>")
else
return
else
..()
return ..()
/obj/machinery/field/generator/emp_act()
@@ -164,30 +148,35 @@ field_generator power level display
/obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj)
if(Proj.flag != "bullet")
power += Proj.damage
update_icon()
power = min(power + Proj.damage, field_generator_max_power)
check_power_level()
return 0
/obj/machinery/field/generator/Destroy()
src.cleanup()
cleanup()
return ..()
/obj/machinery/field/generator/proc/check_power_level()
var/new_level = round(num_power_levels * power / field_generator_max_power)
if(new_level != power_level)
power_level = new_level
update_icon()
/obj/machinery/field/generator/proc/turn_off()
active = 0
active = FG_OFFLINE
spawn(1)
src.cleanup()
while(warming_up>0 && !active)
cleanup()
while(warming_up > 0 && !active)
sleep(50)
warming_up--
update_icon()
/obj/machinery/field/generator/proc/turn_on()
active = 1
active = FG_CHARGING
spawn(1)
while(warming_up<3 && active)
while(warming_up < 3 && active)
sleep(50)
warming_up++
update_icon()
@@ -196,44 +185,35 @@ field_generator power level display
/obj/machinery/field/generator/proc/calc_power()
if(Varpower)
return 1
var/power_draw = 2 + fields.len
update_icon()
if(src.power > field_generator_max_power)
src.power = field_generator_max_power
var/power_draw = 2
for(var/obj/machinery/field/containment/F in fields)
if(isnull(F))
continue
power_draw++
if(draw_power(round(power_draw/2,1)))
if(draw_power(round(power_draw/2, 1)))
check_power_level()
return 1
else
visible_message("<span class='danger'>The [src.name] shuts down!</span>", "<span class='italics'>You hear something shutting down.</span>")
visible_message("<span class='danger'>The [name] shuts down!</span>", "<span class='italics'>You hear something shutting down.</span>")
turn_off()
investigate_log("ran out of power and <font color='red'>deactivated</font>","singulo")
src.power = 0
power = 0
check_power_level()
return 0
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = 0, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
if(Varpower)
return 1
if((G && G == src) || (failsafe >= 8))//Loopin, set fail
if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
return 0
else
failsafe++
if(src.power >= draw)//We have enough power
src.power -= draw
if(power >= draw)//We have enough power
power -= draw
return 1
else//Need more power
draw -= src.power
src.power = 0
for(var/obj/machinery/field/generator/FG in connected_gens)
if(isnull(FG))
continue
draw -= power
power = 0
for(var/CG in connected_gens)
var/obj/machinery/field/generator/FG = CG
if(FG == last)//We just asked you
continue
if(G)//Another gen is askin for power and we dont have it
@@ -249,7 +229,7 @@ field_generator power level display
/obj/machinery/field/generator/proc/start_fields()
if(!src.state == 2 || !anchored)
if(state != FG_WELDED || !anchored)
turn_off()
return
spawn(1)
@@ -260,82 +240,73 @@ field_generator power level display
setup_field(4)
spawn(4)
setup_field(8)
src.active = 2
spawn(5)
active = FG_ONLINE
/obj/machinery/field/generator/proc/setup_field(NSEW)
var/turf/T = src.loc
var/obj/machinery/field/generator/G
var/turf/T = loc
if(!istype(T))
return 0
var/obj/machinery/field/generator/G = null
var/steps = 0
if(!NSEW)//Make sure its ran right
return
for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
return 0
for(var/dist in 0 to 7) // checks out to 8 tiles away for another generator
T = get_step(T, NSEW)
if(T.density)//We cant shoot a field though this
return 0
for(var/atom/A in T.contents)
if(ismob(A))
continue
if(!istype(A,/obj/machinery/field/generator))
if((istype(A,/obj/machinery/door)||istype(A,/obj/machinery/the_singularitygen))&&(A.density))
return 0
steps += 1
G = locate(/obj/machinery/field/generator) in T
if(!isnull(G))
if(G)
steps -= 1
if(!G.active)
return 0
break
if(isnull(G))
return
T = src.loc
for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
for(var/TC in T.contents)
var/atom/A = TC
if(ismob(A))
continue
if(A.density)
return 0
steps++
if(!G)
return 0
T = loc
for(var/dist in 0 to steps) // creates each field tile
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
T = get_step(T, NSEW)
if(!locate(/obj/machinery/field/containment) in T)
var/obj/machinery/field/containment/CF = new/obj/machinery/field/containment()
CF.set_master(src,G)
fields += CF
G.fields += CF
CF.loc = T
CF.dir = field_dir
for(var/mob/living/L in CF.loc)
fields += CF
G.fields += CF
for(var/mob/living/L in T)
CF.Crossed(L)
var/listcheck = 0
for(var/obj/machinery/field/generator/FG in connected_gens)
if(isnull(FG))
continue
if(FG == G)
listcheck = 1
break
if(!listcheck)
connected_gens.Add(G)
listcheck = 0
for(var/obj/machinery/field/generator/FG2 in G.connected_gens)
if(isnull(FG2))
continue
if(FG2 == src)
listcheck = 1
break
if(!listcheck)
G.connected_gens.Add(src)
connected_gens |= G
G.connected_gens |= src
update_icon()
/obj/machinery/field/generator/proc/cleanup()
clean_up = 1
for(var/obj/machinery/field/containment/F in fields)
if(isnull(F))
continue
for(var/F in fields)
qdel(F)
fields = list()
for(var/obj/machinery/field/generator/FG in connected_gens)
if(isnull(FG))
continue
FG.connected_gens.Remove(src)
for(var/CG in connected_gens)
var/obj/machinery/field/generator/FG = CG
FG.connected_gens -= src
if(!FG.clean_up)//Makes the other gens clean up as well
FG.cleanup()
connected_gens.Remove(FG)
connected_gens = list()
connected_gens -= FG
clean_up = 0
update_icon()
@@ -359,3 +330,11 @@ field_generator power level display
/obj/machinery/field/generator/bump_field(atom/movable/AM as mob|obj)
if(fields.len)
..()
#undef FG_UNSECURED
#undef FG_SECURED
#undef FG_WELDED
#undef FG_OFFLINE
#undef FG_CHARGING
#undef FG_ONLINE
+20 -19
View File
@@ -149,17 +149,18 @@
dissipate_delay = 10
dissipate_track = 0
dissipate_strength = 1
if(STAGE_TWO)//1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them
current_size = STAGE_TWO
icon = 'icons/effects/96x96.dmi'
icon_state = "singularity_s3"
pixel_x = -32
pixel_y = -32
grav_pull = 6
consume_range = 1
dissipate_delay = 5
dissipate_track = 0
dissipate_strength = 5
if(STAGE_TWO)
if((check_turfs_in(1,1))&&(check_turfs_in(2,1))&&(check_turfs_in(4,1))&&(check_turfs_in(8,1)))
current_size = STAGE_TWO
icon = 'icons/effects/96x96.dmi'
icon_state = "singularity_s3"
pixel_x = -32
pixel_y = -32
grav_pull = 6
consume_range = 1
dissipate_delay = 5
dissipate_track = 0
dissipate_strength = 5
if(STAGE_THREE)
if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2)))
current_size = STAGE_THREE
@@ -238,22 +239,22 @@
/obj/singularity/proc/eat()
set background = BACKGROUND_ENABLED
for(var/tile in spiral_range_turfs(grav_pull, src, 1))
for(var/tile in spiral_range_turfs(grav_pull, src))
var/turf/T = tile
if(!T)
if(!T || !isturf(loc))
continue
if(get_dist(T, src) > consume_range)
T.singularity_pull(src, current_size)
else
consume(T)
for(var/thing in T)
var/atom/movable/X = thing
if(get_dist(X, src) > consume_range)
X.singularity_pull(src, current_size)
else
consume(X)
if(isturf(loc) && thing != src)
var/atom/movable/X = thing
if(get_dist(X, src) > consume_range)
X.singularity_pull(src, current_size)
else
consume(X)
CHECK_TICK
return
/obj/singularity/proc/consume(var/atom/A)
var/gain = A.singularity_act(current_size)
+3 -3
View File
@@ -1,7 +1,7 @@
#define TESLA_DEFAULT_POWER 1738260
#define TESLA_MINI_POWER 869130
var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics,
var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
/obj/machinery/power/emitter,
/obj/machinery/field/generator,
/mob/living/simple_animal,
@@ -15,7 +15,7 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics,
/obj/machinery/field/containment,
/obj/structure/disposalpipe,
/obj/structure/sign,
/obj/machinery/gateway)
/obj/machinery/gateway))
/obj/singularity/energy_ball
name = "energy ball"
@@ -175,7 +175,7 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics,
closest_atom = A
closest_dist = dist
else if(closest_grounding_rod || is_type_in_list(A, blacklisted_tesla_types))
else if(closest_grounding_rod || is_type_in_typecache(A, blacklisted_tesla_types))
continue
else if(istype(A, /mob/living))
@@ -186,7 +186,7 @@
/obj/item/ammo_box/magazine/m45
name = "handgun magazine (.45)"
icon_state = "45-8"
icon_state = "45"
ammo_type = /obj/item/ammo_casing/c45
caliber = ".45"
max_ammo = 8
@@ -266,7 +266,7 @@
/datum/reagent/holywater/on_mob_life(mob/living/M)
M.jitteriness = max(M.jitteriness-5,0)
if(current_cycle >= 30) // 12 units, 60 seconds @ metabolism 0.4 units & tick rate 2.0 sec
M.stuttering += 4
M.stuttering = min(M.stuttering+4, 20)
M.Dizzy(5)
if(iscultist(M) && prob(5))
M.say(pick("Av'te Nar'sie","Pa'lid Mors","INO INO ORA ANA","SAT ANA!","Daim'niodeis Arc'iai Le'eones","Egkau'haom'nai en Chaous","Ho Diak'nos tou Ap'iron","R'ge Na'sie","Diabo us Vo'iscum","Si gn'um Co'nu"))
@@ -403,6 +403,8 @@
return 0
if(O.mind && O.mind.current && O.mind.current.stat != DEAD)
return 0
if(!O.can_reenter_corpse)
return 0
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
return 0
return 1
@@ -89,13 +89,13 @@
move_gamma_ship()
if(security_level < SEC_LEVEL_RED)
for(var/obj/machinery/door/airlock/highsecurity/red/R in world)
for(var/obj/machinery/door/airlock/highsecurity/red/R in airlocks)
// TODO: Tie into space manager
if((R.z in config.station_levels))
R.locked = 0
R.update_icon()
for(var/obj/machinery/door/airlock/hatch/gamma/H in world)
for(var/obj/machinery/door/airlock/hatch/gamma/H in airlocks)
// TODO: Tie into space manager
if((H.z in config.station_levels))
H.locked = 0