Merge Conflic Fix

Conflicts:
	icons/obj/gun.dmi
This commit is contained in:
SamCroswell
2015-02-27 15:52:26 -05:00
134 changed files with 1921 additions and 1184 deletions
+5 -5
View File
@@ -54,11 +54,11 @@
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1 && !node2)
del(src)
return
update_icon()
return
@@ -105,10 +105,10 @@
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1 && !node2)
del(src)
return
qdel(src)
return
update_icon()
return
+28 -27
View File
@@ -55,9 +55,10 @@
return parent.return_network(reference)
/obj/machinery/atmospherics/pipe/Del()
/obj/machinery/atmospherics/pipe/Destroy()
del(parent)
if(air_temporary)
if(air_temporary && loc)
loc.assume_air(air_temporary)
..()
@@ -70,7 +71,7 @@
if(istype(W,/obj/item/device/pipe_painter))
return 0
if (istype(W, /obj/item/device/pipe_freezer))
if(!src.frozen) // If the pipe is not already frozen
user << "\red You begin to freeze the [src]"
@@ -88,7 +89,7 @@
"You hear dripping water.")
add_fingerprint(user)
return 1
return 1
if (!istype(W, /obj/item/weapon/wrench))
return ..()
@@ -96,7 +97,7 @@
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
@@ -129,7 +130,7 @@
/*
/obj/machinery/atmospherics/pipe/add_underlay(var/obj/machinery/atmospherics/node, var/direction)
if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices
if(istype(src, /obj/machinery/atmospherics/pipe/tank)) //todo: move tanks to unary devices
return ..()
if(node)
@@ -182,7 +183,7 @@
/obj/machinery/atmospherics/pipe/simple/New()
..()
// Pipe colors and icon states are handled by an image cache - so color and icon should
// be null. For mapping purposes color is defined in the object definitions.
icon = null
@@ -242,7 +243,7 @@
else if(dir==12)
dir = 4
/obj/machinery/atmospherics/pipe/simple/Del()
/obj/machinery/atmospherics/pipe/simple/Destroy()
if(node1)
node1.disconnect(src)
if(node2)
@@ -276,7 +277,7 @@
if (meter.target == src)
new /obj/item/pipe_meter(T)
del(meter)
del(src)
qdel(src)
else if(node1 && node2)
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, pipe_icon + "intact" + icon_connect_type)
else
@@ -313,9 +314,9 @@
src.connected_to = c
node2 = target
break
if(!node1 && !node2)
del(src)
qdel(src)
return
var/turf/T = get_turf(src)
@@ -359,7 +360,7 @@
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/visible/yellow
color = PIPE_COLOR_YELLOW
@@ -394,7 +395,7 @@
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/visible/universal
name="Universal pipe adapter"
desc = "An adapter for regular, supply and scrubbers pipes"
@@ -567,7 +568,7 @@
else
. = PROCESS_KILL
/obj/machinery/atmospherics/pipe/manifold/Del()
/obj/machinery/atmospherics/pipe/manifold/Destroy()
if(node1)
node1.disconnect(src)
if(node2)
@@ -620,19 +621,19 @@
if (meter.target == src)
new /obj/item/pipe_meter(T)
del(meter)
del(src)
qdel(src)
else
overlays.Cut()
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
underlays.Cut()
var/turf/T = get_turf(src)
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
var/node1_direction = get_dir(src, node1)
var/node2_direction = get_dir(src, node2)
var/node3_direction = get_dir(src, node3)
directions -= dir
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
@@ -692,7 +693,7 @@
break
if (node3)
break
if(!node1 && !node2 && !node3)
del(src)
return
@@ -804,7 +805,7 @@
else
. = PROCESS_KILL
/obj/machinery/atmospherics/pipe/manifold4w/Del()
/obj/machinery/atmospherics/pipe/manifold4w/Destroy()
if(node1)
node1.disconnect(src)
if(node2)
@@ -866,13 +867,13 @@
if (meter.target == src)
new /obj/item/pipe_meter(T)
del(meter)
del(src)
qdel(src)
else
overlays.Cut()
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
underlays.Cut()
/*
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
@@ -884,7 +885,7 @@
for(var/D in directions)
add_underlay(,D)
*/
var/turf/T = get_turf(src)
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
var/node1_direction = get_dir(src, node1)
@@ -948,7 +949,7 @@
src.connected_to = c
node4 = target
break
if(!node1 && !node2 && !node3&& !node4)
del(src)
return
@@ -1059,7 +1060,7 @@
..()
else
. = PROCESS_KILL
/obj/machinery/atmospherics/pipe/cap/Del()
/obj/machinery/atmospherics/pipe/cap/Destroy()
if(node)
node.disconnect(src)
@@ -1176,7 +1177,7 @@
else
. = PROCESS_KILL
/obj/machinery/atmospherics/pipe/tank/Del()
/obj/machinery/atmospherics/pipe/tank/Destroy()
if(node1)
node1.disconnect(src)
@@ -1263,7 +1264,7 @@
air_temporary.oxygen = (25*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)
air_temporary.nitrogen = (25*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)
..()
..()
icon_state = "air"
/obj/machinery/atmospherics/pipe/tank/oxygen
@@ -1376,7 +1377,7 @@
else
parent.mingle_with_turf(loc, volume)
/obj/machinery/atmospherics/pipe/vent/Del()
/obj/machinery/atmospherics/pipe/vent/Destroy()
if(node1)
node1.disconnect(src)
+5
View File
@@ -207,6 +207,8 @@ mob/airflow_hit(atom/A)
for(var/mob/M in hearers(src))
M.show_message("\red <B>\The [src] slams into \a [A]!</B>",1,"\red You hear a loud slam!",2)
playsound(src.loc, "smash.ogg", 25, 1, -1)
if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN))
return 0
weakened = max(weakened, (istype(A,/obj/item) ? A:w_class : rand(1,5))) //Heheheh
. = ..()
@@ -238,6 +240,9 @@ mob/living/carbon/human/airflow_hit(atom/A)
blocked = run_armor_check("groin","melee")
apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow")
if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN))
return 0
if(airflow_speed > 10)
paralysis += round(airflow_speed * vsc.airflow_stun)
stunned = max(stunned,paralysis + 3)
+87 -61
View File
@@ -1,5 +1,5 @@
/*
* Experimental procs by ESwordTheCat.
* Experimental procs by ESwordTheCat!
*/
/*
@@ -15,7 +15,7 @@
* -1, parameter B is not a char
* -2, parameter A is not a string
*/
/proc/EgijkAeN(const/A, const/B)
/proc/strpos(const/A, const/B)
if (istext(A) == 0 || length(A) < 1)
return -2
@@ -31,29 +31,24 @@
. = i
i = findtext(A, B, i + 1)
/obj/machinery/proc/getArea()
var/area/A = loc.loc
if (A != myArea)
myArea = A
. = myArea
/**
* Object pooling.
*
* If this file is named experimental,
* well treat this implementation as experimental experimental (redundancy intended).
*
* WARNING, only supports /mob and /obj.
* WARNING, only supports /atom/movable (/mob and /obj)
*/
// Uncomment to show debug messages.
//#define DEBUG_OBJECT_POOL
#define MAINTAINING_OBJECT_POOL_COUNT 20
#define MAINTAINING_OBJECT_POOL_COUNT 500
var/list/masterPool = list()
var/global/list/masterPool = new
// Read-only or compile-time vars and special exceptions.
var/list/exclude = list("inhand_states", "loc", "locs", "parent_type", "vars", "verbs", "type", "x", "y", "z")
/*
* @args
@@ -62,27 +57,35 @@ var/list/masterPool = list()
*
* Example call: getFromPool(/obj/item/weapon/shard, loc)
*/
/proc/getFromPool(const/A, const/B)
if (isnull(masterPool[A]))
/proc/getFromPool()
var/A = args[1]
var/list/B = list()
B += (args - A)
if(length(masterPool["[A]"]) <= 0)
#ifdef DEBUG_OBJECT_POOL
world << "DEBUG_OBJECT_POOL: new proc has been called ([A])."
world << text("DEBUG_OBJECT_POOL: new proc has been called ([]).", A)
#endif
//so the GC knows we're pooling this type.
if(isnull(masterPool["[A]"]))
masterPool["[A]"] = list(new A)
if(B && B.len)
return new A(arglist(B))
else
return new A()
return new A(B)
var/atom/movable/Object = masterPool[A][1]
masterPool[A] -= Object
var/objectLength = length(masterPool[A])
var/atom/movable/O = masterPool["[A]"][1]
masterPool["[A]"] -= O
#ifdef DEBUG_OBJECT_POOL
world << "DEBUG_OBJECT_POOL: getFromPool([A]) [objectLength] left."
world << text("DEBUG_OBJECT_POOL: getFromPool([]) [] left.", A, length(masterPool[A]))
#endif
if (!objectLength)
masterPool[A] = null
Object.loc = B
return Object
if(!O || !istype(O))
O = new A(arglist(B))
else
if(length(B))
O.loc = B[1]
O.New(arglist(B))
return O
/*
* @args
@@ -93,31 +96,26 @@ var/list/masterPool = list()
*
* Example call: returnToPool(src)
*/
/proc/returnToPool(const/A)
if (!istype(A, /atom/movable))
return -1
/proc/returnToPool(const/atom/movable/AM)
if(istype(AM.loc,/mob/living))
var/mob/living/L = AM.loc
L.unEquip(AM)
if(length(masterPool["[AM.type]"]) > MAINTAINING_OBJECT_POOL_COUNT)
#ifdef DEBUG_OBJECT_POOL
world << text("DEBUG_OBJECT_POOL: returnToPool([]) exceeds [] discarding...", AM.type, MAINTAINING_OBJECT_POOL_COUNT)
#endif
var/atom/movable/Object = A
Object.resetVariables()
qdel(AM, 1)
return
switch(length(masterPool[Object.type]))
if (MAINTAINING_OBJECT_POOL_COUNT to 1.#INF)
#ifdef DEBUG_OBJECT_POOL
world << "DEBUG_OBJECT_POOL: returnToPool([Object.type]) exceeds [num2text(MAINTAINING_OBJECT_POOL_COUNT)] discarding..."
#endif
if(isnull(masterPool["[AM.type]"]))
masterPool["[AM.type]"] = list()
return
if (0) // In a numeric context (like a mathematical operation), null evaluates to 0.
#ifdef DEBUG_OBJECT_POOL
world << "DEBUG_OBJECT_POOL: [Object.type] pool is empty, recreating pool."
#endif
masterPool[Object.type] = list()
masterPool[Object.type] += Object
AM.resetVariables()
masterPool["[AM.type]"] += AM
#ifdef DEBUG_OBJECT_POOL
world << "DEBUG_OBJECT_POOL: returnToPool([Object.type]) [length(masterPool[Object.type])] left."
world << text("DEBUG_OBJECT_POOL: returnToPool([]) [] left.", AM.type, length(masterPool["[AM.type]"]))
#endif
#undef MAINTAINING_OBJECT_POOL_COUNT
@@ -127,20 +125,48 @@ var/list/masterPool = list()
#endif
/*
* Override this if the object variables needed to reset.
* if you have a variable that needed to be preserve, override this and call ..
*
* Example: see, code\game\objects\items\stacks\sheets\glass.dm
* @/obj/item/weapon/shard
* @resetVariables()
* example
*
* /obj/item/resetVariables()
* ..("var1", "var2", "var3")
*
* however, if the object has a child type an it has overridden resetVariables()
* this should be
*
* /obj/item/resetVariables()
* ..("var1", "var2", "var3", args)
*
* /obj/item/weapon/resetVariables()
* ..("var4")
*/
/atom/movable
proc/resetVariables()
var/list/exclude = list("loc", "locs", "parent_type", "vars", "verbs", "type") // Read-only or compile-time vars and whatevs.
exclude += args // Explicit var exclusion
var/list/varsCopy = vars - exclude
var/key
/atom/movable/proc/resetVariables()
loc = null
for (key in varsCopy)
vars[key] = initial(vars[key])
var/list/exclude = global.exclude + args // explicit var exclusion
vars["loc"] = null // Making sure the loc is null not a compile-time var value.
for(var/key in vars)
if(key in exclude)
continue
vars[key] = initial(vars[key])
/proc/isInTypes(atom/Object, types)
var/prototype = Object.type
Object = null
for (var/type in params2list(types))
if (ispath(prototype, text2path(type)))
return 1
return 0
/obj/machinery/proc/getArea()
var/area/A = loc.loc
if (A != myArea)
myArea = A
. = myArea
+4 -16
View File
@@ -107,7 +107,7 @@
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
return
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
@@ -126,7 +126,7 @@
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
return
else // non-adjacent click
if(W)
@@ -136,9 +136,9 @@
return
/mob/proc/changeNext_move(num)
/mob/proc/changeNext_move(num)
next_move = world.time + num
// Default behavior: ignore double clicks, consider them normal clicks instead
/mob/proc/DblClickOn(var/atom/A, var/params)
return
@@ -344,21 +344,9 @@
if(available >= 5000000)
L.damage = 205
if(L.damage >= 200)
apply_damage(15, BURN, (hand ? "l_hand" : "r_hand"))
//usr:Stun(15)
//usr:Weaken(15)
//if(usr:status_flags & CANSTUN) // stun is usually associated with stutter
// usr:stuttering += 20
time = 200
src << "<span class='warning'>[G] overload from the massive current shocking you in the process!"
else if(L.damage >= 100)
apply_damage(5, BURN, (hand ? "l_hand" : "r_hand"))
//usr:Stun(10)
//usr:Weaken(10)
//if(usr:status_flags & CANSTUN) // stun is usually associated with stutter
// usr:stuttering += 10
time = 150
src << "<span class='warning'>[G] overload from the massive current shocking you in the process!"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
+2 -2
View File
@@ -404,7 +404,7 @@
if("Toggle Sensor Augmentation")
if(isrobot(usr))
var/mob/living/silicon/robot/R = usr
R.control_hud()
R.sensor_mode()
if("module1")
if(istype(usr, /mob/living/silicon/robot))
@@ -551,7 +551,7 @@
if("Set Sensor Augmentation")
if(isAI(usr))
var/mob/living/silicon/ai/AI = usr
AI.control_hud()
AI.sensor_mode()
// Alien
if("night vision")
-2
View File
@@ -53,8 +53,6 @@
/////////////////////////
var/power = force
if(HULK in user.mutations)
power *= 2
if(!istype(M, /mob/living/carbon/human))
if(istype(M, /mob/living/carbon/slime))
+2 -2
View File
@@ -108,7 +108,7 @@ var/const/tk_maxrange = 15
return
var/d = get_dist(user, target)
if(focus)
if(focus)
d = max(d,get_dist(user,focus)) // whichever is further
if(d > tk_maxrange)
user << "<span class='warning'>Your mind won't reach that far.</span>"
@@ -163,7 +163,7 @@ var/const/tk_maxrange = 15
O.icon_state = "nothing"
flick("empdisable",O)
spawn(5)
O.delete()
qdel(O)
return
@@ -160,14 +160,6 @@ atom/movable/New()
trueLuminosity = luminosity * luminosity
light = new(src)
//Objects with opacity will trigger nearby lights to update at next lighting process.
atom/movable/Destroy()
if(opacity)
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights()
..()
//Sets our luminosity.
//If we have no light it will create one.
+7 -7
View File
@@ -134,12 +134,12 @@
var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix
var/default_laws = 0 //Controls what laws the AI spawns with.
var/list/station_levels = list(1) // Defines which Z-levels the station exists on.
var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle
var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect
var/list/player_levels = list(1, 3, 4, 5, 6, 7) // Defines all Z-levels a character can typically reach
var/const/minutes_to_ticks = 60 * 10
// Event settings
var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours
@@ -168,7 +168,7 @@
src.probabilities[M.config_tag] = M.probability
if (M.votable)
src.votable_modes += M.config_tag
del(M)
qdel(M)
src.votable_modes += "secret"
/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
@@ -209,9 +209,9 @@
if ("use_age_restriction_for_jobs")
config.use_age_restriction_for_jobs = 1
if ("use_age_restriction_for_antags")
config.use_age_restriction_for_antags = 1
config.use_age_restriction_for_antags = 1
if ("jobs_have_minimal_access")
config.jobs_have_minimal_access = 1
@@ -462,7 +462,7 @@
if("max_maint_drones")
config.max_maint_drones = text2num(value)
if("station_levels")
config.station_levels = text2numlist(value, ";")
@@ -474,7 +474,7 @@
if("player_levels")
config.player_levels = text2numlist(value, ";")
if("expected_round_length")
config.expected_round_length = MinutesToTicks(text2num(value))
+55 -45
View File
@@ -1,68 +1,78 @@
var/datum/controller/failsafe/Failsafe
var/global/datum/controller/failsafe/failsafe
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
var/processing = 0
var/processing_interval = 100 //poke the MC every 10 seconds
/datum/controller/failsafe // This thing pretty much just keeps poking the controllers.
processing_interval = 100 // Poke the controllers every 10 seconds.
var/MC_iteration = 0
var/MC_defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
/*
* Controller alert level.
* For every poke that fails this is raised by 1.
* When it reaches 5 the MC is replaced with a new one
* (effectively killing any controller process() and starting a new one).
*/
var/lighting_iteration = 0
var/lighting_defcon = 0 //alert level for lighting controller.
// master
var/masterControllerIteration = 0
var/masterControllerAlertLevel = 0
// lighting
var/lightingControllerIteration = 0
var/lightingControllerAlertLevel = 0
/datum/controller/failsafe/New()
//There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
if(Failsafe != src)
if(istype(Failsafe))
del(Failsafe)
Failsafe = src
Failsafe.process()
. = ..()
// There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one).
if (failsafe != src)
if (istype(failsafe))
recover()
qdel(failsafe)
failsafe = src
failsafe.process()
/datum/controller/failsafe/proc/process()
processing = 1
spawn(0)
//set background = 1
while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller
set background = BACKGROUND_ENABLED
while(1) // More efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop.
iteration++
if(processing)
if(master_controller.processing) //only poke if these overrides aren't in effect
if(MC_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval
switch(MC_defcon)
if(master_controller.processing) // Only poke if these overrides aren't in effect
if(masterControllerIteration == master_controller.iteration) // Master controller hasn't finished processing in the defined interval.
switch(masterControllerAlertLevel)
if(0 to 3)
MC_defcon++
masterControllerAlertLevel++
if(4)
admins << "<font color='red' size='2'><b>Warning. The Master Controller has not fired in the last [MC_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
MC_defcon = 5
admins << "<font color='red' size='2'><b>Warning. The master Controller has not fired in the last [masterControllerAlertLevel * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
masterControllerAlertLevel = 5
if(5)
admins << "<font color='red' size='2'><b>Warning. The Master Controller has still not fired within the last [MC_defcon*processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process)
master_controller.process() //Start it rolling again
MC_defcon = 0
admins << "<font color='red' size='2'><b>Warning. The master Controller has still not fired within the last [masterControllerAlertLevel * processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/game_controller() // Replace the old master controller (hence killing the old one's process).
master_controller.process() // Start it rolling again.
masterControllerAlertLevel = 0
else
MC_defcon = 0
MC_iteration = controller_iteration
masterControllerAlertLevel = 0
masterControllerIteration = master_controller.iteration
if(lighting_controller.processing)
if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval
switch(lighting_defcon)
if(lightingControllerIteration == lighting_controller.iteration) // Lighting controller hasn't finished processing in the defined interval.
switch(lightingControllerAlertLevel)
if(0 to 3)
lighting_defcon++
lightingControllerAlertLevel++
if(4)
admins << "<font color='red' size='2'><b>Warning. The Lighting Controller has not fired in the last [lighting_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
lighting_defcon = 5
admins << "<font color='red' size='2'><b>Warning. The lighting_controller controller has not fired in the last [lightingControllerAlertLevel * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
lightingControllerAlertLevel = 5
if(5)
admins << "<font color='red' size='2'><b>Warning. The Lighting Controller has still not fired within the last [lighting_defcon*processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/lighting() //replace the old lighting_controller (hence killing the old one's process)
lighting_controller.process() //Start it rolling again
lighting_defcon = 0
admins << "<font color='red' size='2'><b>Warning. The lighting_controller controller has still not fired within the last [lightingControllerAlertLevel * processing_interval] ticks. Killing and restarting...</b></font>"
new /datum/controller/lighting() // Replace the old lighting_controller (hence killing the old one's process).
lighting_controller.process() // Start it rolling again.
lightingControllerAlertLevel = 0
else
lighting_defcon = 0
lighting_iteration = lighting_controller.iteration
else
MC_defcon = 0
lighting_defcon = 0
lightingControllerAlertLevel = 0
lightingControllerIteration = lighting_controller.iteration
sleep(processing_interval)
sleep(processing_interval)
+172 -110
View File
@@ -1,124 +1,186 @@
#define GC_COLLECTIONS_PER_TICK 300 // Was 100.
#define GC_COLLECTION_TIMEOUT (30 SECONDS)
#define GC_FORCE_DEL_PER_TICK 60
//#define GC_DEBUG
#define GC_COLLECTIONS_PER_TICK 250 // Was 100
#define GC_COLLECTION_TIMEOUT 100 // 10s
var/global/datum/controller/garbage_collector/garbage
var/global/list/uncollectable_vars=list(
"alpha",
"bestF",
"bounds",
"bound_height",
"bound_width",
"ckey",
"color",
"contents",
"gender",
"group",
"key",
//"loc",
"locs",
"luminosity",
"parent",
"parent_type",
"step_size",
"glide_size",
"gc_destroyed",
"step_x",
"step_y",
"step_z",
"tag",
"thermal_conductivity",
"type",
"vars",
"verbs",
"x",
"y",
"z",
)
/datum/controller/garbage_collector
var/list/queue=list()
var/list/destroyed=list()
var/waiting=0
var/del_everything=1
var/turf/trashbin=null
var/list/gc_hard_del_types = new
var/datum/garbage_collector/garbageCollector
New()
trashbin=locate(0,0,CENTCOMM_Z)
/client/proc/gc_dump_hdl()
set name = "(GC) Hard Del List"
set desc = "List types that are hard del()'d by the GC."
set category = "Debug"
proc/AddTrash(var/atom/movable/A)
if(!A)
return
if(del_everything)
del(A)
return
A.loc=trashbin
queue.Add(A)
waiting++
for(var/A in gc_hard_del_types)
usr << "[A] = [gc_hard_del_types[A]]"
proc/Pop()
var/atom/movable/A = queue[1]
if(!A)
if(isnull(A))
var/loopcheck = 0
while(queue.Remove(null))
loopcheck++
if(loopcheck > 50)
break
return
if(del_everything)
del(A)
return
if(!istype(A,/atom/movable))
testing("GC given a [A.type].")
del(A)
return
for(var/vname in A.vars)
if(!issaved(A.vars[vname]))
continue
if(vname in uncollectable_vars)
continue
//testing("Unsetting [vname] in [A.type]!")
A.vars[vname]=null
A.loc=null
destroyed.Add("\ref[A]")
queue.Remove(A)
/datum/garbage_collector
var/list/queue = new
var/del_everything = 0
proc/process()
for(var/i=0;i<min(waiting,GC_COLLECTIONS_PER_TICK);i++)
if(waiting)
Pop()
waiting--
for(var/i=0;i<min(destroyed.len,GC_COLLECTIONS_PER_TICK);i++)
if(destroyed.len)
var/refID=destroyed[1]
var/atom/A = locate(refID)
if(A && A.gc_destroyed && A.gc_destroyed >= world.time - GC_COLLECTION_TIMEOUT)
// Something's still referring to the qdel'd object. Kill it.
del(A)
destroyed.Remove(refID)
// To let them know how hardworking am I :^).
var/dels_count = 0
var/hard_dels = 0
var/soft_dels = 0
/**
* NEVER USE THIS FOR ANYTHING OTHER THAN /atom/movable
* OTHER TYPES CANNOT BE QDEL'D BECAUSE THEIR LOC IS LOCKED OR THEY DON'T HAVE ONE.
*/
/proc/qdel(var/atom/movable/A)
if(!A) return
if(!istype(A))
warning("qdel() passed object of type [A.type]. qdel() can only handle /atom/movable types.")
del(A)
/datum/garbage_collector/proc/addTrash(const/atom/movable/AM)
if(!istype(AM))
return
if(!garbage)
del(A)
if(del_everything)
del(AM)
hard_dels++
dels_count++
return
// Let our friend know they're about to get fucked up.
A.Destroy()
garbage.AddTrash(A)
queue["\ref[AM]"] = world.timeofday
/datum/garbage_collector/proc/process()
var/remainingCollectionPerTick = GC_COLLECTIONS_PER_TICK
var/remainingForceDelPerTick = GC_FORCE_DEL_PER_TICK
var/collectionTimeScope = world.timeofday - GC_COLLECTION_TIMEOUT
if(narsie_cometh) return //don't even fucking bother, its over.
while(queue.len && --remainingCollectionPerTick >= 0)
var/refID = queue[1]
var/destroyedAtTime = queue[refID]
if(destroyedAtTime > collectionTimeScope)
break
var/atom/movable/AM = locate(refID)
if(AM) // Something's still referring to the qdel'd object. del it.
if(isnull(AM.gcDestroyed))
queue -= refID
continue
if(remainingForceDelPerTick <= 0)
break
#ifdef GC_DEBUG
WARNING("gc process force delete [AM.type]")
#endif
AM.hard_deleted = 1
if(!AM.type in gc_hard_del_types)
gc_hard_del_types += AM.type
del AM
hard_dels++
remainingForceDelPerTick--
#ifdef GC_DEBUG
#undef GC_DEBUG
#endif
#undef GC_FORCE_DEL_PER_TICK
#undef GC_COLLECTION_TIMEOUT
#undef GC_COLLECTIONS_PER_TICK
/datum/garbage_collector/proc/dequeue(id)
if (queue)
queue -= id
dels_count++
/*
* NEVER USE THIS FOR ANYTHING OTHER THAN /atom/movable
* OTHER TYPES CANNOT BE QDEL'D BECAUSE THEIR LOC IS LOCKED OR THEY DON'T HAVE ONE.
*/
/proc/qdel(const/atom/movable/AM, ignore_pooling = 0)
if(isnull(AM))
return
if(isnull(garbageCollector))
del(AM)
return
if(!istype(AM))
WARNING("qdel() passed object of type [AM.type]. qdel() can only handle /atom/movable types.")
if(!AM.type in gc_hard_del_types)
gc_hard_del_types += AM.type
del(AM)
garbageCollector.hard_dels++
garbageCollector.dels_count++
return
//We are object pooling this.
if(("[AM.type]" in masterPool) && !ignore_pooling)
returnToPool(AM)
return
if(isnull(AM.gcDestroyed))
// Let our friend know they're about to get fucked up.
AM.Destroy()
garbageCollector.addTrash(AM)
/datum/controller
var/processing = 0
var/iteration = 0
var/processing_interval = 0
/datum/controller/proc/recover() // If we are replacing an existing controller (due to a crash) we attempt to preserve as much as we can.
/*
* Like Del(), but for qdel.
* Called BEFORE qdel moves shit.
*/
/datum/proc/Destroy()
del(src)
/client/proc/qdel_toggle()
set name = "Toggle qdel Behavior"
set desc = "Toggle qdel usage between normal and force del()."
set category = "Debug"
garbage.del_everything = !garbage.del_everything
world << "<b>GC: qdel turned [garbage.del_everything?"off":"on"].</b>"
log_admin("[key_name(usr)] turned qdel [garbage.del_everything?"off":"on"].")
message_admins("\blue [key_name(usr)] turned qdel [garbage.del_everything?"off":"on"].", 1)
garbageCollector.del_everything = !garbageCollector.del_everything
world << "<b>GC: qdel turned [garbageCollector.del_everything ? "off" : "on"].</b>"
log_admin("[key_name(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].")
message_admins("\blue [key_name(usr)] turned qdel [garbageCollector.del_everything ? "off" : "on"].", 1)
/*/client/var/running_find_references
/atom/verb/find_references()
set category = "Debug"
set name = "Find References"
set background = 1
set src in world
if(!usr || !usr.client)
return
if(usr.client.running_find_references)
testing("CANCELLED search for references to a [usr.client.running_find_references].")
usr.client.running_find_references = null
return
if(alert("Running this will create a lot of lag until it finishes. You can cancel it by running it again. Would you like to begin the search?", "Find References", "Yes", "No") == "No")
return
qdel(src)
// Remove this object from the list of things to be auto-deleted.
if(garbageCollector)
garbageCollector.queue -= "\ref[src]"
usr.client.running_find_references = type
testing("Beginning search for references to a [type].")
var/list/things = list()
for(var/client/thing)
things += thing
for(var/datum/thing)
things += thing
for(var/atom/thing)
things += thing
for(var/event/thing)
things += thing
testing("Collected list of things in search for references to a [type]. ([things.len] Thing\s)")
for(var/datum/thing in things)
if(!usr.client.running_find_references) return
for(var/varname in thing.vars)
var/variable = thing.vars[varname]
if(variable == src)
testing("Found [src.type] \ref[src] in [thing.type]'s [varname] var.")
else if(islist(variable))
if(src in variable)
testing("Found [src.type] \ref[src] in [thing.type]'s [varname] list var.")
testing("Completed search for references to a [type].")
usr.client.running_find_references = null
*/
+2 -4
View File
@@ -1,10 +1,8 @@
var/datum/controller/lighting/lighting_controller = new ()
datum/controller/lighting
var/processing = 0
var/processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it!
processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it!
var/process_cost = 0
var/iteration = 0
var/lighting_states = 7
@@ -21,7 +19,7 @@ datum/controller/lighting/New()
if(lighting_controller != src)
if(istype(lighting_controller,/datum/controller/lighting))
Recover() //if we are replacing an existing lighting_controller (due to a crash) we attempt to preserve as much as we can
del(lighting_controller)
qdel(lighting_controller)
lighting_controller = src
+8 -11
View File
@@ -11,7 +11,6 @@ var/global/air_processing_killed = 0
var/global/pipe_processing_killed = 0
datum/controller/game_controller
var/processing = 0
var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
var/minimum_ticks = 20 //The minimum length of time between MC ticks
@@ -28,7 +27,7 @@ datum/controller/game_controller
var/events_cost = 0
var/puddles_cost
var/ticker_cost = 0
var/gc_cost = 0
var/garbageCollectorCost = 0
var/total_cost = 0
var/last_thing_processed
@@ -36,13 +35,14 @@ datum/controller/game_controller
var/list/shuttle_list // For debugging and VV
var/datum/ore_distribution/asteroid_ore_map // For debugging and VV.
var/global/datum/garbage_collector/garbageCollector
datum/controller/game_controller/New()
//There can be only one master_controller. Out with the old and in with the new.
if(master_controller != src)
if(istype(master_controller))
Recover()
del(master_controller)
qdel(master_controller)
master_controller = src
if(!job_master)
@@ -71,9 +71,6 @@ datum/controller/game_controller/proc/setup()
ticker = new /datum/controller/gameticker()
*/
if(!garbage)
garbage = new /datum/controller/garbage_collector()
color_windows_init()
setup_objects()
@@ -134,7 +131,7 @@ datum/controller/game_controller/proc/process()
spawn(0)
//set background = 1
while(1) //far more efficient than recursively calling ourself
if(!Failsafe) new /datum/controller/failsafe()
if(!failsafe) new /datum/controller/failsafe()
if(processing)
@@ -246,12 +243,12 @@ datum/controller/game_controller/proc/process()
// GC
timer = world.timeofday
last_thing_processed = garbage.type
garbage.process()
gc_cost = (world.timeofday - timer) / 10
last_thing_processed = garbageCollector.type
garbageCollector.process()
garbageCollectorCost = (world.timeofday - timer) / 10
//TIMING
total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + aibots_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + puddles_cost + ticker_cost + gc_cost
total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + aibots_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + puddles_cost + ticker_cost + garbageCollectorCost
var/end_time = world.timeofday
if(end_time < start_time) //why not just use world.time instead?
+12 -9
View File
@@ -49,7 +49,7 @@
return
/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event"))
/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Scheduler"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -59,18 +59,15 @@
if("Master")
debug_variables(master_controller)
feedback_add_details("admin_verb","DMC")
if("Failsafe")
debug_variables(Failsafe)
feedback_add_details("admin_verb","DFailsafe")
if ("failsafe")
debug_variables(failsafe)
feedback_add_details("admin_verb", "dfailsafe")
if("Ticker")
debug_variables(ticker)
feedback_add_details("admin_verb","DTicker")
if("Lighting")
debug_variables(lighting_controller)
feedback_add_details("admin_verb","DLighting")
if("Garbage")
debug_variables(garbage)
feedback_add_details("admin_verb","DGarbage")
if("Air")
debug_variables(air_master)
feedback_add_details("admin_verb","DAir")
@@ -103,7 +100,13 @@
feedback_add_details("admin_verb","DCameras")
if("Event")
debug_variables(event_manager)
feedback_add_details("admin_verb","DEvent")
feedback_add_details("admin_verb","DEvent")
if("Garbage")
debug_variables(garbageCollector)
feedback_add_details("admin_verb","DGarbage")
if("Scheduler")
debug_variables(processScheduler)
feedback_add_details("admin_verb","DprocessScheduler")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
+1 -1
View File
@@ -17,7 +17,7 @@ datum/controller/vote
New()
if(vote != src)
if(istype(vote))
del(vote)
qdel(vote)
vote = src
proc/process() //called by master_controller
+2 -2
View File
@@ -103,7 +103,7 @@
id = "boxes"
blacklist = null
whitelist = list(/obj/item/weapon/storage, /obj/item/weapon/moneybag, /obj/item/weapon/evidencebag,
/obj/item/weapon/tray, /obj/item/pizzabox, /obj/item/weapon/clipboard,
/obj/item/weapon/storage/bag/tray, /obj/item/pizzabox, /obj/item/weapon/clipboard,
/obj/item/smallDelivery, /obj/structure/bigDelivery)
/datum/cargoprofile/cargo
@@ -270,7 +270,7 @@
/obj/item/weapon/hand_labeler,/obj/item/weapon/hemostat,/obj/item/weapon/mop,/obj/item/weapon/locator,/obj/item/weapon/minihoe,
/obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/pickaxe,/obj/item/weapon/pinpointer,
/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/retractor,/obj/item/weapon/rsf,/obj/item/weapon/rsp,/obj/item/weapon/scalpel,
/obj/item/weapon/screwdriver,/obj/item/weapon/shovel,/obj/item/weapon/soap,/obj/item/weapon/stamp,/obj/item/weapon/tray,/obj/item/weapon/weldingtool,
/obj/item/weapon/screwdriver,/obj/item/weapon/shovel,/obj/item/weapon/soap,/obj/item/weapon/stamp,/obj/item/weapon/storage/bag/tray,/obj/item/weapon/weldingtool,
/obj/item/weapon/wirecutters,/obj/item/weapon/wrench,/obj/item/weapon/extinguisher)
/datum/cargoprofile/finished
+2 -2
View File
@@ -627,7 +627,7 @@ client
for(var/obj/Obj in world)
if(Obj.type == O_type)
i++
del(Obj)
qdel(Obj)
if(!i)
usr << "No objects of this type exist"
return
@@ -638,7 +638,7 @@ client
for(var/obj/Obj in world)
if(istype(Obj,O_type))
i++
del(Obj)
qdel(Obj)
if(!i)
usr << "No objects of this type exist"
return
@@ -231,7 +231,7 @@
user.visible_message(fixText(state["vis_msg"],user),fixText(state["self_msg"],user))
if("delete" in state)
del(used_atom)
qdel(used_atom)
else if("spawn" in state)
var/spawntype=state["spawn"]
var/atom/A = new spawntype(holder.loc)
+1 -1
View File
@@ -49,7 +49,7 @@
//must succeed in most cases
proc/setTeleatom(atom/movable/ateleatom)
if(istype(ateleatom, /obj/effect) && !istype(ateleatom, /obj/effect/dummy/chameleon))
del(ateleatom)
qdel(ateleatom)
return 0
if(istype(ateleatom))
teleatom = ateleatom
+26 -26
View File
@@ -735,7 +735,7 @@ datum/mind
var/obj/item/device/flash/flash = locate() in L
if (!flash)
usr << "\red Deleting flash failed!"
del(flash)
qdel(flash)
if("repairflash")
var/list/L = current.get_contents()
@@ -748,7 +748,7 @@ datum/mind
if("reequip")
var/list/L = current.get_contents()
var/obj/item/device/flash/flash = locate() in L
del(flash)
qdel(flash)
take_uplink()
var/fail = 0
fail |= !ticker.mode.equip_traitor(current, 1)
@@ -927,17 +927,17 @@ datum/mind
if("lair")
current.loc = get_turf(locate("landmark*Syndicate-Spawn"))
if("dressup")
del(H.belt)
del(H.back)
del(H.l_ear)
del(H.r_ear)
del(H.gloves)
del(H.head)
del(H.shoes)
del(H.wear_id)
del(H.wear_pda)
del(H.wear_suit)
del(H.w_uniform)
qdel(H.belt)
qdel(H.back)
qdel(H.l_ear)
qdel(H.r_ear)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_pda)
qdel(H.wear_suit)
qdel(H.w_uniform)
if (!ticker.mode.equip_syndicate(current))
usr << "\red Equipping a syndicate failed!"
@@ -1150,7 +1150,7 @@ datum/mind
proc/take_uplink()
var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
if(H)
del(H)
qdel(H)
proc/make_AI_Malf()
@@ -1191,17 +1191,17 @@ datum/mind
current.loc = get_turf(locate("landmark*Syndicate-Spawn"))
var/mob/living/carbon/human/H = current
del(H.belt)
del(H.back)
del(H.l_ear)
del(H.r_ear)
del(H.gloves)
del(H.head)
del(H.shoes)
del(H.wear_id)
del(H.wear_pda)
del(H.wear_suit)
del(H.w_uniform)
qdel(H.belt)
qdel(H.back)
qdel(H.l_ear)
qdel(H.r_ear)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_pda)
qdel(H.wear_suit)
qdel(H.w_uniform)
ticker.mode.equip_syndicate(current)
@@ -1290,7 +1290,7 @@ datum/mind
var/list/L = current.get_contents()
var/obj/item/device/flash/flash = locate() in L
del(flash)
qdel(flash)
take_uplink()
var/fail = 0
// fail |= !ticker.mode.equip_traitor(current, 1)
+2 -2
View File
@@ -79,7 +79,7 @@
var/obj/result_obj = new result(container)
for (var/obj/O in (container.contents-result_obj))
O.reagents.trans_to(result_obj, O.reagents.total_volume)
del(O)
qdel(O)
container.reagents.clear_reagents()
return result_obj
@@ -91,7 +91,7 @@
O.reagents.del_reagent("nutriment")
O.reagents.update_total()
O.reagents.trans_to(result_obj, O.reagents.total_volume)
del(O)
qdel(O)
container.reagents.clear_reagents()
return result_obj
+2 -2
View File
@@ -20,8 +20,8 @@
for(var/mob/living/target in targets)
for(var/x in mutations)
target.mutations.Add(x)
if(x == HULK && ishuman(target))
target:hulk_time=world.time + duration
/* if(x == HULK && ishuman(target))
target:hulk_time=world.time + duration */
target.disabilities |= disabilities
target.update_mutations() //update target's mutation overlays
spawn(duration)
+1 -1
View File
@@ -26,7 +26,7 @@
if(!target)
return
if(target.type in compatible_mobs || ishuman(target))
if((target.type in compatible_mobs) || ishuman(target))
user << "<span class='notice'>It'd be stupid to curse [target] with a horse's head!</span>"
return
+5 -5
View File
@@ -234,7 +234,7 @@
if(H)
user << "<span class='notice'>You use [src] to destroy [H].</span>"
signs -= H
del(H)
qdel(H)
else
if(signs.len < max_signs)
H = new(get_turf(target))
@@ -250,7 +250,7 @@
if(signs.len)
var/list/L = signs.Copy()
for(var/sign in L)
del(sign)
qdel(sign)
signs -= sign
user << "<span class='notice'>You clear all active holograms.</span>"
@@ -313,7 +313,7 @@
if(ishuman(C))
dead_legs(C)
if(src)
del(src)
qdel(src)
proc/dead_legs(mob/living/carbon/human/H as mob)
var/datum/organ/external/l = H.get_organ("l_leg")
@@ -562,8 +562,8 @@
if(istype(A, /obj/effect/plantsegment))
for(var/obj/effect/plantsegment/B in orange(A,1))
if(prob(80))
del B
del A
qdel(B)
qdel(A)
/*
/obj/item/weapon/cigarpacket
+13 -8
View File
@@ -1,3 +1,6 @@
var/global/list/del_profiling = list()
var/global/list/gdel_profiling = list()
var/global/list/ghdel_profiling = list()
/atom
layer = 2
var/level = 2
@@ -24,16 +27,18 @@
// Garbage collection
var/gc_destroyed=null
/atom/Del()
// Pass to Destroy().
if(!gc_destroyed)
Destroy()
..()
/atom/proc/Destroy()
gc_destroyed=world.time
/atom/Destroy()
SetOpacity(0)
if(reagents)
reagents.Destroy()
reagents = null
// Idea by ChuckTheSheep to make the object even more unreferencable.
invisibility = 101
/atom/proc/CheckParts()
return
@@ -242,7 +247,7 @@ its easier to just keep the beam vertical.
return
/atom/proc/emag_act()
return
return
/atom/proc/hitby(atom/movable/AM as mob|obj)
if (density)
+55 -5
View File
@@ -15,13 +15,67 @@
var/mob/pulledby = null
var/area/areaMaster
var/hard_deleted = 0
/atom/movable/New()
. = ..()
areaMaster = get_area_master(src)
/atom/movable/Destroy()
if(opacity)
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights()
gcDestroyed = "Bye, world!"
tag = null
loc = null
/*
if(istype(beams) && beams.len)
for(var/obj/effect/beam/B in beams)
if(B && B.target == src)
B.target = null
if(B.master && B.master.target == src)
B.master.target = null
beams.len = 0
*/
..()
/proc/delete_profile(var/type, code = 0)
if(!ticker || !ticker.current_state < 3) return
switch(code)
if(0)
if (!("[type]" in del_profiling))
del_profiling["[type]"] = 0
del_profiling["[type]"] += 1
if(1)
if (!("[type]" in ghdel_profiling))
ghdel_profiling["[type]"] = 0
ghdel_profiling["[type]"] += 1
if(2)
if (!("[type]" in gdel_profiling))
gdel_profiling["[type]"] = 0
gdel_profiling["[type]"] += 1
if(garbageCollector)
garbageCollector.soft_dels++
/atom/movable/Del()
if (gcDestroyed)
garbageCollector.dequeue("\ref[src]")
if (hard_deleted)
delete_profile("[type]", 1)
else
delete_profile("[type]", 2)
else // direct del calls or nulled explicitly.
delete_profile("[type]", 0)
Destroy()
..()
// Used in shuttle movement and AI eye stuff.
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
/atom/movable/proc/setLoc(var/T, var/teleported=0)
@@ -107,10 +161,6 @@
src.thrower = thrower
src.throw_source = get_turf(src) //store the origin turf
if(usr)
if(HULK in usr.mutations)
src.throwing = 2 // really strong throw!
var/dist_x = abs(target.x - src.x)
var/dist_y = abs(target.y - src.y)
+4 -4
View File
@@ -65,7 +65,7 @@
component_parts += new /obj/item/stack/cable_coil(src, 1)
component_parts += new /obj/item/stack/cable_coil(src, 1)
RefreshParts()
/obj/machinery/dna_scannernew/upgraded/New()
..()
component_parts = list()
@@ -233,7 +233,7 @@
return
put_in(G.affecting)
src.add_fingerprint(user)
del(G)
qdel(G)
return
/obj/machinery/dna_scannernew/proc/put_in(var/mob/M)
@@ -309,7 +309,7 @@
if(prob(75))
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
del(src)
qdel(src)
/obj/machinery/computer/scan_consolenew
name = "DNA Modifier Access Console"
@@ -367,7 +367,7 @@
/obj/machinery/computer/scan_consolenew/blob_act()
if(prob(75))
del(src)
qdel(src)
/obj/machinery/computer/scan_consolenew/power_change()
if(stat & BROKEN)
+3 -1
View File
@@ -47,6 +47,7 @@
desc = "Enables the subject to bend low levels of light around themselves, creating a cloaking effect."
activation_messages = list("You begin to fade into the shadows.")
deactivation_messages = list("You become fully visible.")
activation_prob=10
New()
block=SHADOWBLOCK
@@ -66,6 +67,7 @@
desc = "The subject becomes able to subtly alter light patterns to become invisible, as long as they remain still."
activation_messages = list("You feel one with your surroundings.")
deactivation_messages = list("You feel oddly exposed.")
activation_prob=10
New()
block=CHAMELEONBLOCK
@@ -316,7 +318,7 @@
else
usr.visible_message("\red [usr] eats \the [the_item].")
playsound(usr.loc, 'sound/items/eatfood.ogg', 50, 0)
del(the_item)
qdel(the_item)
doHeal(usr)
return
+3 -3
View File
@@ -33,7 +33,7 @@
animation.master = src
flick("h2monkey", animation)
sleep(48)
del(animation)
qdel(animation)
var/mob/living/carbon/monkey/O = null
@@ -56,7 +56,7 @@
for(var/obj/T in (M.contents-implants))
del(T)
qdel(T)
O.loc = M.loc
@@ -78,7 +78,7 @@
I.loc = O
I.implanted = O
// O.update_icon = 1 //queue a full icon update at next life() call
del(M)
qdel(M)
return
/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags)
+49 -1
View File
@@ -7,6 +7,7 @@
activation_messages=list("You feel no need to breathe.")
mutation=NO_BREATH
instability=2
activation_prob=10
New()
block=NOBREATHBLOCK
@@ -112,10 +113,57 @@
..(M,connected,flags)
M.pass_flags |= 1
// OLD HULK BEHAVIOR
/datum/dna/gene/basic/hulk
name="Hulk"
activation_messages=list("Your muscles hurt.")
mutation=HULK
activation_prob=5
New()
block=HULKBLOCK
can_activate(var/mob/M,var/flags)
// Can't be big AND small.
if(DWARF in M.mutations)
return 0
return ..(M,flags)
activate(var/mob/M, var/connected, var/flags)
..()
var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
M.status_flags &= ~status
deactivate(var/mob/M, var/connected, var/flags)
..()
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
OnDrawUnderlays(var/mob/M,var/g,var/fat)
if(HULK in M.mutations)
if(fat)
return "hulk_[fat]_s"
else
return "hulk_[g]_s"
return 0
OnMobLife(var/mob/living/carbon/human/M)
if(!istype(M)) return
if ((HULK in M.mutations) && M.health <= 25)
M.mutations.Remove(HULK)
M.dna.SetSEState(HULKBLOCK,0)
M.update_mutations() //update our mutation overlays
M.update_body()
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved.
M << "<span class='danger'>You suddenly feel very weak.</span>"
M.Weaken(3)
M.emote("collapse")
/datum/dna/gene/basic/xray
name="X-Ray Vision"
activation_messages=list("The walls suddenly disappear.")
mutation=XRAY
activation_prob=10
instability=2
New()
@@ -125,7 +173,7 @@
name="Telekenesis"
activation_messages=list("You feel smarter.")
mutation=TK
activation_prob=15
activation_prob=10
instability=5
New()
+7 -7
View File
@@ -2,7 +2,7 @@
This is /vg/'s nerf for hulk. Feel free to steal it.
Obviously, requires DNA2.
*/
// When hulk was first applied (world.time).
/mob/living/carbon/human/var/hulk_time=0
@@ -84,7 +84,7 @@ Obviously, requires DNA2.
//M.say(pick("",";")+pick("HULK MAD","YOU MADE HULK ANGRY")) // Just a note to security.
message_admins("[key_name(usr)] has hulked out! ([formatJumpTo(usr)])")
return
*/
///////////////////Vanilla Morph////////////////////////////////////
@@ -222,19 +222,19 @@ Obviously, requires DNA2.
/obj/effect/proc_holder/spell/wizard/targeted/remotetalk/choose_targets(mob/user = usr)
var/list/targets = new /list()
var/list/validtargets = new /list()
for(var/mob/M in living_mob_list)
for(var/mob/M in living_mob_list)
if(M && M.mind)
var/special_role = M.mind.special_role
if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien")
continue
validtargets += M
if(!validtargets.len || validtargets.len == 1)
usr << "<span class='warning'>There are no valid targets!</span>"
start_recharge()
return
targets += input("Choose the target to talk to.", "Targeting") as mob in validtargets
perform(targets)
@@ -280,7 +280,7 @@ Obviously, requires DNA2.
icon_power_button = "genetic_view"
/obj/effect/proc_holder/spell/wizard/targeted/remoteview/choose_targets(mob/user = usr)
var/list/targets = living_mob_list
var/list/targets = living_mob_list
var/list/remoteviewers = new /list()
for(var/mob/M in targets)
if(REMOTE_VIEW in M.mutations)
+1 -1
View File
@@ -79,7 +79,7 @@
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]</span> <a href='byond://?src=\ref[M];follow2=\ref[M];follow=\ref[src]'>(Follow)</a> <span class='message'>[verb] \"[message]\"</span></span></i></font>"
rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]</span> (<a href='byond://?src=\ref[M];follow2=\ref[M];follow=\ref[src]'>follow</a>) <span class='message'>[verb] \"[message]\"</span></span></i></font>"
M.show_message(rendered, 2)
/mob/camera/blob/emote(var/act,var/m_type=1,var/message = null)
+6
View File
@@ -227,6 +227,12 @@ var/global/datum/controller/gameticker/ticker
statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
votetimer()
for(var/mob/M in mob_list)
if(istype(M,/mob/new_player))
var/mob/new_player/N = M
N.new_player_panel_proc()
return 1
/datum/controller/gameticker
+5
View File
@@ -33,6 +33,11 @@
typepath = /obj/item/weapon/gun/energy/laser/captain
protected_jobs = list("Captain")
/datum/theft_objective/hoslaser
name = "the head of security's recreated antique laser gun"
typepath = /obj/item/weapon/gun/energy/hos
protected_jobs = list("Head Of Security")
/datum/theft_objective/hand_tele
name = "a hand teleporter"
typepath = /obj/item/weapon/hand_tele
+1 -70
View File
@@ -18,8 +18,6 @@
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/xenoai = 0 //Should the Xenos have their own AI?
var/xenoborg = 0 //Should the Xenos have their own borg?
var/gammaratio = 4 //At what alien to human ratio will the Gamma security level be called and the nuke be made available?
/datum/game_mode/xenos/announce()
@@ -70,48 +68,12 @@
del(A)
continue
var/xenoai_selected = 0
var/xenoborg_selected = 0
var/xenoqueen_selected = 0
var/spawnpos = 1
for(var/datum/mind/xeno_mind in xenos)
if(spawnpos > xenos_spawn.len)
spawnpos = 1
//XenoAI selection
if(xenoai && !xenoai_selected)
var/mob/living/silicon/ai/O = new(xenos_spawn[spawnpos],,,1)//No MMI but safety is in effect.
O.invisibility = 0
O.aiRestorePowerRoutine = 0
if(xeno_mind.current)
xeno_mind.transfer_to(O)
O.mind.original = O
else
O.key = xeno_mind.current.key
//del(xeno_mind)
var/obj/loc_landmark
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name == "XenoAI")
loc_landmark = sloc
O.loc = loc_landmark.loc
O.icon_state = "ai-alien"
O.verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon)
O.laws = new /datum/ai_laws/alienmov
O.name = "Alien AI"
O.real_name = name
xeno_mind.name = O.name
O.alienAI = 1
O.network = list("SS13","Xeno")
O.holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo3"))
O.alien_talk_understand = 1
xenoai_selected = 1
spawnpos++
continue
//XenoQueen Selection
if(!xenoqueen_selected)
var/mob/living/carbon/alien/humanoid/queen/O = new(xenos_spawn[spawnpos])
@@ -124,37 +86,6 @@
xenoqueen_selected = 1
spawnpos++
continue
//XenoBorg Selection
if(xenoborg && !xenoborg_selected)
var/mob/living/silicon/robot/O = new(xenos_spawn[spawnpos],0,0,1)
O.mmi = new /obj/item/device/mmi(O)
O.mmi.alien = 1
O.mmi.transfer_identity(xeno_mind.current)//Does not transfer key/client.
O.cell = new(O)
O.cell.maxcharge = 25000
O.cell.charge = 25000
O.gender = xeno_mind.current.gender
O.invisibility = 0
O.key = xeno_mind.current.key
//del(xeno_mind)
O.job = "Alien Cyborg"
O.name = "Alien Cyborg"
O.real_name = name
xeno_mind.name = O.name
O.module = new /obj/item/weapon/robot_module/alien/hunter(src)
O.hands.icon_state = "standard"
O.icon = 'icons/mob/alien.dmi'
O.icon_state = "xenoborg-state-a"
O.modtype = "Xeno-Hu"
O.connected_ai = select_active_alien_ai()
O.laws = new /datum/ai_laws/alienmov()
O.scrambledcodes = 1
O.hiddenborg = 1
O.alien_talk_understand = 1
feedback_inc("xeborg_hunter",1)
xenoborg_selected = 1
spawnpos++
continue
//Additional larvas if playercount > 20
else
var/mob/living/carbon/alien/larva/O = new(xenos_spawn[spawnpos])
@@ -230,7 +161,7 @@
var/list/livingxenos = list()
for(var/datum/mind/xeno in xenos)
if((xeno) && (xeno.current) && (xeno.current.stat != 2) && (xeno.current.client))
if(istype(xeno.current,/mob/living/carbon/alien) || (xenoborg && isrobot(xeno.current)) || (xenoai && isAI(xeno.current)))
if(istype(xeno.current,/mob/living/carbon/alien))
livingxenos += xeno
return livingxenos.len
+46 -24
View File
@@ -16,7 +16,7 @@
var/operating = 0.0
var/list/queue = list()
var/queue_max_len = 10
var/queue_max_len = 12
var/turf/BuildTurf
anchored = 1.0
var/list/L = list()
@@ -34,7 +34,7 @@
var/prod_coeff
var/datum/wires/autolathe/wires = null
var/datum/design/being_built
var/list/being_built = list()
var/datum/research/files
var/list/datum/design/matching_designs
var/selected_category
@@ -190,16 +190,17 @@
/////////////////
//href protection
being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design
if(!being_built)
var/datum/design/design_last_ordered
design_last_ordered = files.FindDesignByID(href_list["make"]) //check if it's a valid design
if(!design_last_ordered)
return
if(!(being_built.build_type & AUTOLATHE))
if(!(design_last_ordered.build_type & AUTOLATHE))
return
//multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier
var/multiplier = text2num(href_list["multiplier"])
var/max_multiplier = min(50, being_built.materials["$metal"] ?round(m_amount/being_built.materials["$metal"]):INFINITY,being_built.materials["$glass"]?round(g_amount/being_built.materials["$glass"]):INFINITY)
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
var/max_multiplier = min(50, design_last_ordered.materials["$metal"] ?round(m_amount/design_last_ordered.materials["$metal"]):INFINITY,design_last_ordered.materials["$glass"]?round(g_amount/design_last_ordered.materials["$glass"]):INFINITY)
var/is_stack = ispath(design_last_ordered.build_path, /obj/item/stack)
if(!is_stack && (multiplier > 1))
return
@@ -207,8 +208,8 @@
return
/////////////////
if(queue.len<queue_max_len)
add_to_queue(being_built,multiplier)
if((queue.len+1)<queue_max_len)
add_to_queue(design_last_ordered,multiplier)
else
usr << "\red The autolathe queue is full!"
if (!busy)
@@ -263,19 +264,22 @@
var/glass_cost = D.materials["$glass"]
var/power = max(2000, (metal_cost+glass_cost)*multiplier/5)
if (can_build(D,multiplier))
being_built = list(D,multiplier)
use_power(power)
icon_state = "autolathe"
flick("autolathe_n",src)
updateUsrDialog()
sleep(32/coeff)
if(is_stack)
m_amount -= metal_cost*multiplier
g_amount -= glass_cost*multiplier
var/obj/item/stack/S = new D.build_path(BuildTurf)
S.amount = multiplier
else
m_amount -= metal_cost/coeff
g_amount -= glass_cost/coeff
updateUsrDialog()
sleep(32/coeff)
if(is_stack)
var/obj/item/stack/S = new D.build_path(BuildTurf)
S.amount = multiplier
else
var/obj/item/new_item = new D.build_path(BuildTurf)
new_item.m_amt /= coeff
new_item.g_amt /= coeff
@@ -288,17 +292,17 @@
/obj/machinery/autolathe/proc/can_build(var/datum/design/D,var/multiplier=1,var/custom_metal,var/custom_glass)
var/coeff = get_coeff(D)
var/m_amount_tmp = m_amount
var/metal_amount = m_amount
if(custom_metal)
m_amount_tmp = custom_metal
var/g_amount_tmp = g_amount
metal_amount = custom_metal
var/glass_amount = g_amount
if(custom_glass)
g_amount_tmp = custom_glass
if(D.materials["$metal"] && (m_amount_tmp*multiplier < (D.materials["$metal"] / coeff)))
glass_amount = custom_glass
if(D.materials["$metal"] && (metal_amount < (multiplier*D.materials["$metal"] / coeff)))
return 0
if(D.materials["$glass"] && (g_amount_tmp*multiplier < (D.materials["$glass"] / coeff)))
if(D.materials["$glass"] && (glass_amount < (multiplier*D.materials["$glass"] / coeff)))
return 0
return 1
@@ -311,6 +315,13 @@
OutputList[2] = (D.materials["$glass"] / coeff)*multiplier
return OutputList
/obj/machinery/autolathe/proc/get_processing_line()
var/datum/design/D = being_built[1]
var/multiplier = being_built[2]
var/is_stack = (multiplier>1)
var/output = "PROCESSING: [initial(D.name)][is_stack?" (x[multiplier])":null]"
return output
/obj/machinery/autolathe/proc/get_queue()
var/temp_metal = m_amount
var/temp_glass = g_amount
@@ -318,19 +329,27 @@
output += "<div class='statusDisplay'>"
output += "<b>Queue contains:</b>"
if (!istype(queue) || !queue.len)
output += "<br>Nothing"
if(being_built.len)
output += "<ol><li>"
output += get_processing_line()
output += "</li></ol>"
else
output += "<br>Nothing"
else
output += "<ol>"
if(being_built.len)
output += "<li>"
output += get_processing_line()
output += "</li>"
var/i = 0
var/datum/design/D
for(var/list/L in queue)
i++
D = L[1]
var/multiplier = L[2]
var/obj/part = D.build_path
var/list/LL = get_design_cost_as_list(D,multiplier)
var/is_stack = (multiplier>1)
output += "<li[!can_build(D,multiplier,temp_metal,temp_glass)?" style='color: #f00;'":null]>[initial(part.name)][is_stack?" (x[multiplier])":null] - [i>1?"<a href='?src=\ref[src];queue_move=-1;index=[i]' class='arrow'>&uarr;</a>":null] [i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>&darr;</a>":null] <a href='?src=\ref[src];remove_from_queue=[i]'>Remove</a></li>"
output += "<li[!can_build(D,multiplier,temp_metal,temp_glass)?" style='color: #f00;'":null]>[initial(D.name)][is_stack?" (x[multiplier])":null] - [i>1?"<a href='?src=\ref[src];queue_move=-1;index=[i]' class='arrow'>&uarr;</a>":null] [i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>&darr;</a>":null] <a href='?src=\ref[src];remove_from_queue=[i]'>Remove</a></li>"
temp_metal = max(temp_metal-LL[1],1)
temp_glass = max(temp_glass-LL[2],1)
@@ -363,16 +382,19 @@
return
while(D)
if(stat&(NOPOWER|BROKEN))
being_built = new /list()
return 0
if(!can_build(D,multiplier))
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Not enough resources. Queue processing terminated.\"")
queue = list()
being_built = new /list()
return 0
remove_from_queue(1)
build_item(D,multiplier)
D = listgetindex(listgetindex(queue, 1),1)
multiplier = listgetindex(listgetindex(queue,1),2)
being_built = new /list()
//visible_message("\icon[src] <b>\The [src]</b> beeps, \"Queue processing finished successfully.\"")
/obj/machinery/autolathe/proc/main_win(mob/user)
+2 -2
View File
@@ -1024,7 +1024,7 @@
/obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowlerhat = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1,
/obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,/obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1,
/obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1,
/obj/item/clothing/under/pirate = 1,/obj/item/clothing/suit/pirate_brown = 1,/obj/item/clothing/suit/pirate_black =1,/obj/item/clothing/under/pirate_rags =1,/obj/item/clothing/head/pirate = 1,/obj/item/clothing/head/bandana = 1,
/obj/item/clothing/head/bandana = 1,/obj/item/clothing/under/soviet = 1,/obj/item/clothing/head/ushanka = 1,/obj/item/clothing/suit/imperium_monk = 1,
/obj/item/clothing/mask/gas/cyborg = 1,/obj/item/clothing/suit/holidaypriest = 1,/obj/item/clothing/head/wizard/marisa/fake = 1,
@@ -1053,7 +1053,7 @@
desc = "A kitchen and restaurant equipment vendor"
product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..."
icon_state = "dinnerware"
products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2,/obj/item/weapon/reagent_containers/food/condiment/pack/ketchup = 5,/obj/item/weapon/reagent_containers/food/condiment/pack/hotsauce = 5)
products = list(/obj/item/weapon/storage/bag/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2,/obj/item/weapon/reagent_containers/food/condiment/pack/ketchup = 5,/obj/item/weapon/reagent_containers/food/condiment/pack/hotsauce = 5)
contraband = list(/obj/item/weapon/kitchen/utensil/spoon = 2,/obj/item/weapon/kitchen/utensil/knife = 2,/obj/item/weapon/kitchen/rollingpin = 2, /obj/item/weapon/butch = 2)
/obj/machinery/vending/sovietsoda
+42 -4
View File
@@ -35,26 +35,64 @@
ticker.mode.traitors += user.mind
user.mind.special_role = "The Hero The Station Deserves"
var/wish = input("You want to...","Wish") as null|anything in list("Protect the innocent","Hunt the guilty")
var/mob/living/carbon/human/M = user
var/wish = input("You want to...","Wish") as anything in list("Protect the innocent","Hunt the guilty")
switch(wish)
if("Protect the innocent")
M.fully_replace_character_name(M.real_name, "Owlman")
var/datum/objective/protect/protect = new
protect.owner = user.mind
user.mind.objectives += protect
for(var/obj/item/W in M)
M.unEquip(W)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/under/owl(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask(M), slot_wear_mask)
var/obj/item/weapon/card/id/syndicate/W = new(M)
W.name = "[M.real_name]'s ID Card (Superhero)"
W.access = get_all_accesses()
W.assignment = "Superhero"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
M.regenerate_icons()
if("Hunt the guilty")
M.fully_replace_character_name(M.real_name, "The Griffin")
var/datum/objective/assassinate/assasinate = new
assasinate.owner = user.mind
user.mind.objectives += assasinate
for(var/obj/item/W in M)
M.unEquip(W)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/griffin(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/under/griffin(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/head/griffin(M), slot_head)
var/obj/item/weapon/card/id/syndicate/W = new(M)
W.name = "[M.real_name]'s ID Card (Supervillain)"
W.access = get_all_accesses()
W.assignment = "Supervillain"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
M.regenerate_icons()
var/obj_count = 1
for(var/datum/objective/OBJ in user.mind.objectives)
user << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
user << "As a superhero, you are allowed to pick an appropriate pseudonym for your new role. A costume is also strongly encouraged."
user.rename_self()
charges--
insisting = 0
@@ -11,6 +11,17 @@ would spawn and follow the beaker, even if it is carried or thrown.
icon = 'icons/effects/effects.dmi'
mouse_opacity = 0
unacidable = 1//So effect are not targeted by alien acid.
/datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16)
if(A.alpha == 0) //Handle already transparent case
return
if(frames == 0)
frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame".
var/step = A.alpha / frames
for(var/i = 0, i < frames, i++)
A.alpha -= step
sleep(world.tick_lag)
return
/obj/effect/effect/water
name = "water"
+50 -101
View File
@@ -1,4 +1,3 @@
/obj/item/weapon/extinguisher
name = "fire extinguisher"
desc = "A traditional red fire extinguisher."
@@ -18,32 +17,24 @@
var/last_use = 1.0
var/safety = 1
var/sprite_name = "fire_extinguisher"
reagents_to_log=list(
"plasma"= "plasma",
"pacid" = "polytrinic acid",
"sacid" = "sulphuric acid"
)
var/power = 5 //Maximum distance launched water will travel
var/precision = 0 //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row
var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled
/obj/item/weapon/extinguisher/mini
name = "fire extinguisher"
name = "pocket fire extinguisher"
desc = "A light and compact fibreglass-framed model fire extinguisher."
icon_state = "miniFE0"
item_state = "miniFE"
hitsound = null //it is much lighter, after all.
flags = null //doesn't CONDUCT
throwforce = 2
w_class = 2.0
force = 3.0
m_amt = 0
max_water = 30
sprite_name = "miniFE"
/obj/item/weapon/extinguisher/New()
var/datum/reagents/R = new/datum/reagents(max_water)
reagents = R
R.my_atom = src
R.add_reagent("water", max_water)
/obj/item/weapon/extinguisher/examine()
set src in usr
@@ -51,11 +42,13 @@
if(reagents && reagents.reagent_list.len)
for(var/datum/reagent/R in reagents.reagent_list)
usr << "\blue [R.volume] units of [R.name]"
for(var/thing in src)
usr << "\red \A [thing] is jammed into the nozzle!"
..()
return
/obj/item/weapon/extinguisher/New()
create_reagents(max_water)
reagents.add_reagent("water", max_water)
/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
safety = !safety
src.icon_state = "[sprite_name][!safety]"
@@ -63,81 +56,43 @@
user << "The safety is [safety ? "on" : "off"]."
return
/*
/obj/item/weapon/extinguisher/attackby(obj/item/W, mob/user, params)
if(user.stat || user.restrained() || user.lying) return
if (istype(W, /obj/item/weapon/wrench))
if(!is_open_container())
user.visible_message("[user] begins to unwrench the fill cap on \the [src].","\blue You begin to unwrench the fill cap on \the [src].")
if(do_after(user, 25))
user.visible_message("[user] removes the fill cap on \the [src].","\blue You remove the fill cap on \the [src].")
playsound(get_turf(src),'sound/items/Ratchet.ogg', 100, 1)
flags |= OPENCONTAINER
/obj/item/weapon/extinguisher/proc/AttemptRefill(atom/target, mob/user)
if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user))
var/safety_save = safety
safety = 1
if(reagents.total_volume == reagents.maximum_volume)
user << "<span class='notice'>\The [src] is already full!</span>"
safety = safety_save
return 1
var/obj/structure/reagent_dispensers/watertank/W = target
var/transferred = W.reagents.trans_to(src, max_water)
if(transferred > 0)
user << "<span class='notice'>\The [src] has been refilled by [transferred] units</span>"
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
for(var/datum/reagent/water/R in reagents.reagent_list)
R.cooling_temperature = cooling_power
else
user.visible_message("[user] begins to seal the fill cap on \the [src].","\blue You begin to seal the fill cap on \the [src].")
if(do_after(user, 25))
user.visible_message("[user] fastens the fill cap on \the [src].","\blue You fasten the fill cap on \the [src].")
playsound(get_turf(src),'sound/items/Ratchet.ogg', 100, 1)
flags &= ~OPENCONTAINER
return
if (istype(W, /obj/item) && !is_open_container())
if(W.w_class>1)
user << "\The [W] won't fit into the nozzle!"
return
if(locate(/obj) in src)
user << "There's already something crammed into the nozzle."
return
user.drop_item()
W.loc=src
user << "You cram \the [W] into the nozzle of \the [src]."
msg_admin_attack("[user]/[user.ckey] has crammed \a [W] into a [src].")
*/
user << "<span class='notice'>\The [W] is empty!</span>"
safety = safety_save
return 1
else
return 0
/obj/item/weapon/extinguisher/afterattack(atom/target, mob/user , flag)
if(get_dist(src,target) <= 1)
if((istype(target, /obj/structure/reagent_dispensers)))
var/obj/o = target
var/list/badshit=list()
for(var/bad_reagent in src.reagents_to_log)
if(o.reagents.has_reagent(bad_reagent))
badshit += reagents_to_log[bad_reagent]
if(badshit.len)
var/hl="\red <b>([english_list(badshit)])</b> \black"
message_admins("[user.name] ([user.ckey]) filled \a [src] with [o.reagents.get_reagent_ids()] [hl]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
log_game("[user.name] ([user.ckey]) filled \a [src] with [o.reagents.get_reagent_ids()] [hl]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
o.reagents.trans_to(src, 50)
user << "\blue \The [src] is now refilled"
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
if(is_open_container() && reagents.total_volume)
user << "\blue You empty \the [src] onto [target]."
if(reagents.has_reagent("fuel"))
message_admins("[user.name] ([user.ckey]) poured Welder Fuel onto [target]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
log_game("[user.name] ([user.ckey]) poured Welder Fuel onto [target]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
src.reagents.reaction(target, TOUCH)
spawn(5) src.reagents.clear_reagents()
return
if (!safety && !is_open_container())
//TODO; Add support for reagents in water.
if(target.loc == user)//No more spraying yourself when putting your extinguisher away
return
var/Refill = AttemptRefill(target, user)
if(Refill)
return
if (!safety)
if (src.reagents.total_volume < 1)
usr << "\red \The [src] is empty."
usr << "<span class='danger'>\The [src] is empty.</span>"
return
if (world.time < src.last_use + 20)
return
var/list/badshit=list()
for(var/bad_reagent in src.reagents_to_log)
if(reagents.has_reagent(bad_reagent))
badshit += reagents_to_log[bad_reagent]
if(badshit.len)
var/hl="\red <b>([english_list(badshit)])</b> \black"
message_admins("[user.name] ([user.ckey]) used \a [src] filled with [reagents.get_reagent_ids(1)] [hl]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
log_game("[user.name] ([user.ckey]) used \a [src] filled with [reagents.get_reagent_ids(1)] [hl]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
src.last_use = world.time
playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3)
@@ -174,26 +129,21 @@
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
if(locate(/obj) in src)
for(var/obj/thing in src)
thing.loc = get_turf(src)
thing.throw_at(target,thing.throw_range*2,throw_speed*2)
user.visible_message(
"<span class='danger'>[user] fires [src] and launches [thing] at [target]!</span>",
"<span class='danger'>You fire [src] and launch [thing] at [target]!</span>")
break
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
if(precision)
var/turf/T3 = get_step(T1, turn(direction, 90))
var/turf/T4 = get_step(T2,turn(direction, -90))
the_targets = list(T,T1,T2,T3,T4)
for(var/a=0, a<5, a++)
spawn(0)
var/obj/effect/effect/water/W = new /obj/effect/effect/water( get_turf(src) )
var/turf/my_target = pick(the_targets)
if(precision)
the_targets -= my_target
var/datum/reagents/R = new/datum/reagents(5)
if(!W) return
W.reagents = R
@@ -202,21 +152,20 @@
src.reagents.trans_to(W,1)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W) return
if(!W.reagents) return
if(!W || !W.reagents) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm, TOUCH) // Touch, since we sprayed it.
if(isliving(atm) && W.reagents.has_reagent("water")) // For extinguishing mobs on fire
var/mob/living/M = atm // Why isn't this handled by the reagent? - N3X
W.reagents.reaction(atm)
if(isliving(atm)) //For extinguishing mobs on fire
var/mob/living/M = atm
M.ExtinguishMob()
if(W.loc == my_target) break
sleep(2)
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
if(!has_gravity(user))
user.inertia_dir = get_dir(target, user)
step(user, user.inertia_dir)
else
return ..()
return
+1 -88
View File
@@ -7,7 +7,6 @@
* Kitchen knives
* Butcher's cleaver
* Rolling Pins
* Trays
*/
/obj/item/weapon/kitchen
@@ -215,90 +214,4 @@
w_class = 3.0
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
/*
* Trays - Agouri
*/
/obj/item/weapon/tray
name = "tray"
icon = 'icons/obj/food.dmi'
icon_state = "tray"
desc = "A metal tray to lay food on."
force = 8
hitsound = 'sound/items/trayhit1.ogg'
throwforce = 10.0
throw_speed = 3
throw_range = 5
w_class = 3.0
flags = CONDUCT
m_amt = 3000
var/list/carrying = list() // List of things on the tray. - Doohl
var/max_carry = 10 // w_class = 1 -- takes up 1
// w_class = 2 -- takes up 3
// w_class = 3 -- takes up 5
/*
===============~~~~~================================~~~~~====================
= =
= Code for trays carrying things. By Doohl for Doohl erryday Doohl Doohl~ =
= =
===============~~~~~================================~~~~~====================
*/
/obj/item/weapon/tray/proc/calc_carry()
// calculate the weight of the items on the tray
var/val = 0 // value to return
for(var/obj/item/I in carrying)
if(I.w_class == 1.0)
val ++
else if(I.w_class == 2.0)
val += 3
else
val += 5
return val
/obj/item/weapon/tray/pickup(mob/user)
if(!isturf(loc))
return
for(var/obj/item/I in loc)
if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) )
var/add = 0
if(I.w_class == 1.0)
add = 1
else if(I.w_class == 2.0)
add = 3
else
add = 5
if(calc_carry() + add >= max_carry)
break
I.loc = src
carrying.Add(I)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer)
/obj/item/weapon/tray/dropped(mob/user)
var/mob/living/M
for(M in src.loc) //to handle hand switching
return
var/foundtable = 0
for(var/obj/structure/table/T in loc)
foundtable = 1
break
overlays.Cut()
for(var/obj/item/I in carrying)
I.loc = loc
carrying.Remove(I)
if(!foundtable && isturf(loc))
// if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere!
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
/* Trays moved to /obj/item/weapon/storage/bag */
@@ -10,6 +10,7 @@
* Plant Bag
* Sheet Snatcher
* Book Bag
* Tray
*
* -Sayu
*/
@@ -37,6 +38,11 @@
storage_slots = 30
can_hold = list() // any
cant_hold = list("/obj/item/weapon/disk/nuclear","/obj/item/flag/nation")
/obj/item/weapon/storage/bag/trash/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] puts the [src.name] over their head and starts chomping at the insides! Disgusting!</span>")
playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1)
return (TOXLOSS)
/obj/item/weapon/storage/bag/trash/update_icon()
if(contents.len == 0)
@@ -47,10 +53,15 @@
icon_state = "trashbag2"
else icon_state = "trashbag3"
/obj/item/weapon/storage/bag/trash/cyborg
/obj/item/weapon/storage/bag/trash/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
J.put_in_cart(src, user)
J.mybag=src
J.update_icon()
/obj/item/weapon/storage/bag/trash/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J)
return
// -----------------------------
@@ -323,3 +334,96 @@
max_w_class = 3
w_class = 4 //Bigger than a book because physics
can_hold = list(/obj/item/weapon/book, /obj/item/weapon/spellbook) //No bibles, consistent with bookcase
/*
* Trays - Agouri
*/
/obj/item/weapon/storage/bag/tray
name = "tray"
icon = 'icons/obj/food.dmi'
icon_state = "tray"
desc = "A metal tray to lay food on."
force = 5
throwforce = 10.0
throw_speed = 3
throw_range = 5
w_class = 4.0
flags = CONDUCT
m_amt = 3000
/obj/item/weapon/storage/bag/tray/attack(mob/living/M as mob, mob/living/user as mob)
..()
// Drop all the things. All of them.
var/list/obj/item/oldContents = contents.Copy()
quick_empty()
// Make each item scatter a bit
for(var/obj/item/I in oldContents)
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
if(prob(50))
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
else
playsound(M, 'sound/items/trayhit2.ogg', 50, 1)
if(ishuman(M) || ismonkey(M))
if(prob(10))
M.Weaken(2)
/obj/item/weapon/storage/bag/tray/proc/rebuild_overlays()
overlays.Cut()
for(var/obj/item/I in contents)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1)
/obj/item/weapon/storage/bag/tray/remove_from_storage(obj/item/W as obj, atom/new_location)
..()
rebuild_overlays()
/obj/item/weapon/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1)
..()
/obj/item/weapon/storage/bag/tray/cyborg
/obj/item/weapon/storage/bag/tray/cyborg/afterattack(atom/target, mob/user as mob)
if ( isturf(target) || istype(target,/obj/structure/table) )
var foundtable = istype(target,/obj/structure/table/)
if ( !foundtable ) //it must be a turf!
for(var/obj/structure/table/T in target)
foundtable = 1
break
var turf/dropspot
if ( !foundtable ) // don't unload things onto walls or other silly places.
dropspot = user.loc
else if ( isturf(target) ) // they clicked on a turf with a table in it
dropspot = target
else // they clicked on a table
dropspot = target.loc
overlays = null
var droppedSomething = 0
for(var/obj/item/I in contents)
I.loc = dropspot
contents.Remove(I)
droppedSomething = 1
if(!foundtable && isturf(dropspot))
// if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere!
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
if ( droppedSomething )
if ( foundtable )
user.visible_message("\blue [user] unloads their service tray.")
else
user.visible_message("\blue [user] drops all the items on their tray.")
return ..()
@@ -336,19 +336,6 @@
if(!can_be_inserted(W))
return 0
if(istype(W, /obj/item/weapon/tray))
var/obj/item/weapon/tray/T = W
if(T.calc_carry() > 0)
if(prob(85))
user << "\red The tray won't fit in [src]."
return 1
else
W.loc = user.loc
if ((user.client && user.s_active != src))
user.client.screen -= W
W.dropped(user)
user << "\red God damnit!"
handle_item_insertion(W)
return 1
@@ -2,13 +2,14 @@
/obj/item/weapon/watertank
name = "backpack water tank"
desc = "A S.U.N.S.H.I.N.E. brand watertank backpack with nozzle to water plants."
icon = 'icons/obj/hydroponics.dmi'
icon = 'icons/obj/watertank.dmi'
icon_state = "waterbackpack"
item_state = "waterbackpack"
w_class = 4.0
slot_flags = SLOT_BACK
slowdown = 1
action_button_name = "Toggle Mister"
icon_action_button = "action_waterbackpack"
var/obj/item/weapon/noz
var/on = 0
@@ -18,39 +19,34 @@
..()
create_reagents(volume)
noz = make_noz()
return
/obj/item/weapon/watertank/examine()
set src in usr
..()
for(var/datum/reagent/R in reagents.reagent_list)
usr << "[round(R.volume)] units of [R.name] left."
return
/obj/item/weapon/watertank/ui_action_click()
if (usr.get_item_by_slot(slot_back) == src)
toggle_mister()
else
usr << "<span class='notice'>The watertank needs to be on your back to use!</span>"
return
toggle_mister()
/obj/item/weapon/watertank/verb/toggle_mister()
set name = "Toggle Mister"
set category = "Object"
if (usr.get_item_by_slot(slot_back) != src)
usr << "<span class='notice'>The watertank needs to be on your back to use.</span>"
return
if(usr.stat || !usr.canmove || usr.restrained())
return
on = !on
var/mob/living/carbon/human/user = usr
if(on)
if(noz == null)
noz = make_noz()
//Detach the nozzle into the user's hands
var/list/L = list("left hand" = slot_l_hand,"right hand" = slot_r_hand)
if(!user.equip_in_one_of_slots(noz, L))
if(!user.put_in_hands(noz))
on = 0
user << "<span class='notice'>You need a free hand to hold the mister!</span>"
user << "<span class='notice'>You need a free hand to hold the mister.</span>"
return
noz.loc = user
else
//Remove from their hands and put back "into" the tank
remove_noz(user)
remove_noz()
return
/obj/item/weapon/watertank/proc/make_noz()
@@ -58,21 +54,52 @@
/obj/item/weapon/watertank/equipped(mob/user, slot)
if (slot != slot_back)
remove_noz(user)
remove_noz()
/obj/item/weapon/watertank/proc/remove_noz(mob/user)
var/mob/living/carbon/human/M = user
if(noz in get_both_hands(M))
M.unEquip(noz)
/obj/item/weapon/watertank/proc/remove_noz()
if(ismob(noz.loc))
var/mob/M = noz.loc
M.unEquip(noz, 1)
return
/obj/item/weapon/watertank/Destroy()
if (on)
var/M = get(noz, /mob)
remove_noz(M)
remove_noz()
qdel(noz)
noz = null
..()
return
/obj/item/weapon/watertank/attack_hand(mob/user as mob)
if(src.loc == user)
ui_action_click()
return
..()
/obj/item/weapon/watertank/MouseDrop(obj/over_object)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
switch(over_object.name)
if("r_hand")
if(H.r_hand)
return
if(!H.unEquip(src))
return
H.put_in_r_hand(src)
if("l_hand")
if(H.l_hand)
return
if(!H.unEquip(src))
return
H.put_in_l_hand(src)
return
/obj/item/weapon/watertank/attackby(obj/item/W, mob/user, params)
if(W == noz)
remove_noz()
return
..()
// This mister item is intended as an extension of the watertank and always attached to it.
// Therefore, it's designed to be "locked" to the player's hands or extended back onto
// the watertank backpack. Allowing it to be placed elsewhere or created without a parent
@@ -80,13 +107,15 @@
/obj/item/weapon/reagent_containers/spray/mister
name = "water mister"
desc = "A mister nozzle attached to a water tank."
icon = 'icons/obj/hydroponics.dmi'
icon = 'icons/obj/watertank.dmi'
icon_state = "mister"
item_state = "mister"
icon_override = 'icons/mob/in-hand/tools.dmi'
w_class = 4.0
amount_per_transfer_from_this = 50
possible_transfer_amounts = list(25,50,100)
volume = 500
flags = NODROP | OPENCONTAINER | NOBLUDGEON
var/obj/item/weapon/watertank/tank
@@ -99,7 +128,7 @@
return
/obj/item/weapon/reagent_containers/spray/mister/dropped(mob/user as mob)
user << "<span class='notice'>The mister snaps back onto the watertank!</span>"
user << "<span class='notice'>The mister snaps back onto the watertank.</span>"
tank.on = 0
loc = tank
@@ -114,6 +143,16 @@
else
return 1
/obj/item/weapon/reagent_containers/spray/mister/Move()
..()
if(loc != tank.loc)
loc = tank.loc
/obj/item/weapon/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity)
if(target.loc == loc || target == tank) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it putting it away
return
..()
//Janitor tank
/obj/item/weapon/watertank/janitor
name = "backpack water tank"
@@ -123,13 +162,12 @@
/obj/item/weapon/watertank/janitor/New()
..()
reagents.add_reagent("cleaner", 250)
reagents.add_reagent("cleaner", 500)
/obj/item/weapon/reagent_containers/spray/mister/janitor
name = "janitor spray nozzle"
desc = "A janitorial spray nozzle attached to a watertank, designed to clean up large messes."
icon = 'icons/obj/hydroponics.dmi'
icon = 'icons/obj/watertank.dmi'
icon_state = "misterjani"
item_state = "misterjani"
amount_per_transfer_from_this = 5
@@ -142,25 +180,46 @@
amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10)
user << "<span class='notice'>You [amount_per_transfer_from_this == 10 ? "remove" : "fix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.</span>"
//Atmos tank
//ATMOS FIRE FIGHTING BACKPACK
#define EXTINGUISHER 0
#define NANOFROST 1
#define METAL_FOAM 2
/obj/item/weapon/watertank/atmos
name = "backpack water tank"
desc = "A backpack watertank with fire extinguisher nozzle, intended to fight fires. Shouldn't toxins have one of these?"
name = "backpack firefighter tank"
desc = "A refridgerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, nanofrost launcher, and metal foam dispenser for breaches. Nanofrost converts plasma in the air to nitrogen, but only if it is combusting at the time."
icon_state = "waterbackpackatmos"
item_state = "waterbackpackatmos"
volume = 100
volume = 200
/obj/item/weapon/watertank/atmos/make_noz()
return new /obj/item/weapon/extinguisher/mini/nozzle(src)
/obj/item/weapon/watertank/atmos/dropped(mob/user as mob)
icon_state = "waterbackpackatmos"
if(istype(noz, /obj/item/weapon/extinguisher/mini/nozzle))
var/obj/item/weapon/extinguisher/mini/nozzle/N = noz
N.nozzle_mode = 0
/obj/item/weapon/extinguisher/mini/nozzle
name = "fire extinguisher nozzle"
desc = "A fire extinguisher nozzle attached to a water tank."
icon = 'icons/obj/hydroponics.dmi'
icon_state = "misteratmos"
item_state = "misteratmos"
name = "extinguisher nozzle"
desc = "A heavy duty nozzle attached to a firefighter's backpack tank."
icon = 'icons/obj/watertank.dmi'
icon_state = "atmos_nozzle"
item_state = "nozzleatmos"
icon_override = 'icons/mob/in-hand/tools.dmi'
safety = 0
max_water = 200
power = 8
precision = 1
cooling_power = 5
w_class = 5
flags = NODROP //Necessary to ensure that the nozzle and tank never seperate
var/obj/item/weapon/watertank/tank
var/nozzle_mode = 0
var/metal_synthesis_cooldown = 0
var/nanofrost_cooldown = 0
/obj/item/weapon/extinguisher/mini/nozzle/New(parent_tank)
if(check_tank_exists(parent_tank, src))
@@ -170,10 +229,174 @@
loc = tank
return
/obj/item/weapon/extinguisher/mini/nozzle/Move()
..()
if(tank && loc != tank.loc)
loc = tank
return
/obj/item/weapon/extinguisher/mini/nozzle/attack_self(mob/user as mob)
switch(nozzle_mode)
if(EXTINGUISHER)
nozzle_mode = NANOFROST
tank.icon_state = "waterbackpackatmos_1"
user << "Swapped to nanofrost launcher"
return
if(NANOFROST)
nozzle_mode = METAL_FOAM
tank.icon_state = "waterbackpackatmos_2"
user << "Swapped to metal foam synthesizer"
return
if(METAL_FOAM)
nozzle_mode = EXTINGUISHER
tank.icon_state = "waterbackpackatmos_0"
user << "Swapped to water extinguisher"
return
return
/obj/item/weapon/extinguisher/mini/nozzle/dropped(mob/user as mob)
user << "<span class='notice'>The nozzle snaps back onto the watertank!</span>"
user << "<span class='notice'>The nozzle snaps back onto the tank!</span>"
tank.on = 0
loc = tank
/obj/item/weapon/extinguisher/mini/nozzle/attack_self()
/obj/item/weapon/extinguisher/mini/nozzle/afterattack(atom/target, mob/user)
if(nozzle_mode == EXTINGUISHER)
..()
return
var/Adj = user.Adjacent(target)
if(Adj)
AttemptRefill(target, user)
if(nozzle_mode == NANOFROST)
if(Adj)
return //Safety check so you don't blast yourself trying to refill your tank
var/datum/reagents/R = reagents
if(R.total_volume < 100)
user << "You need at least 100 units of water to use the nanofrost launcher!"
return
if(nanofrost_cooldown)
user << "Nanofrost launcher is still recharging"
return
nanofrost_cooldown = 1
R.remove_any(100)
var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src))
log_game("[user.ckey] ([user.name]) used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).")
playsound(src,'sound/items/syringeproj.ogg',40,1)
for(var/a=0, a<5, a++)
step_towards(A, target)
sleep(2)
A.Smoke()
spawn(100)
if(src)
nanofrost_cooldown = 0
return
if(nozzle_mode == METAL_FOAM)
if(!Adj|| !istype(target, /turf))
return
if(metal_synthesis_cooldown < 5)
var/obj/effect/effect/foam/F = new /obj/effect/effect/foam(get_turf(target), 1)
F.amount = 0
metal_synthesis_cooldown++
spawn(100)
if(src)
metal_synthesis_cooldown--
else
user << "Metal foam mix is still being synthesized."
return
/obj/effect/nanofrost_container
name = "nanofrost container"
desc = "A frozen shell of ice containing nanofrost that freezes the surrounding area after activation."
icon = 'icons/effects/effects.dmi'
icon_state = "frozen_smoke_capsule"
mouse_opacity = 0
pass_flags = PASSTABLE
/obj/effect/nanofrost_container/proc/Smoke()
new /obj/effect/effect/freezing_smoke(src.loc, 6, 1)
var/obj/effect/decal/cleanable/flour/F = new /obj/effect/decal/cleanable/flour(src.loc)
F.color = "#B2FFFF"
F.name = "nanofrost residue"
F.desc = "Residue left behind from a nanofrost detonation. Perhaps there was a fire here?"
playsound(src,'sound/effects/bamf.ogg',100,1)
qdel(src)
/obj/effect/effect/freezing_smoke
name = "nanofrost smoke"
icon_state = "smoke"
opacity = 0
anchored = 0.0
mouse_opacity = 0
icon = 'icons/effects/96x96.dmi'
pixel_x = -32
pixel_y = -32
color = "#B2FFFF"
var/amount = 0
/obj/effect/effect/freezing_smoke/New(loc, var/amt, var/blast)
..()
spawn(100+rand(10,30))
delete()
amount = amt
if(amount)
var/datum/effect/effect/system/freezing_smoke_spread/F = new /datum/effect/effect/system/freezing_smoke_spread
F.set_up(amount, 0, src.loc)
F.start()
if(blast)
for(var/turf/T in trange(2, src.loc))
Chilled(T)
return
/obj/effect/effect/freezing_smoke/proc/Chilled(atom/A)
if(istype(A, /turf/simulated))
var/turf/simulated/T = A
if(T.air)
var/datum/gas_mixture/G = T.air
if(get_dist(T, src) < 2) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
G.temperature = 2
update_nearby_tiles()
var/hotspot = (locate(/obj/fire) in T)
if(hotspot && !istype(T, /turf/space))
var/CT = 10
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() )
lowertemp.temperature = max( min(lowertemp.temperature-(CT*1000),lowertemp.temperature / CT) ,0)
lowertemp.react()
T.assume_air(lowertemp)
qdel(hotspot)
if(G.toxins)
G.nitrogen += (G.toxins)
G.toxins = 0
for(var/obj/machinery/atmospherics/unary/vent_pump/V in T)
V.welded = 1
V.update_icon()
V.visible_message("<span class='danger'>[V] was frozen shut!</span>")
for(var/mob/living/L in T)
L.ExtinguishMob()
return
/datum/effect/effect/system/freezing_smoke_spread
/datum/effect/effect/system/freezing_smoke_spread/set_up(n = 6, c = 0, loca)
number = n
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
/datum/effect/effect/system/freezing_smoke_spread/start()
var/i = 0
for(i=0, i<number, i++)
spawn(0)
var/obj/effect/effect/freezing_smoke/smoke = new /obj/effect/effect/freezing_smoke(location, 0, 0)
smoke.amount = 0
var/direction = pick(alldirs)
for(i=0, i<rand(1,3), i++)
sleep(5)
step(smoke,direction)
spawn(150+rand(10,30))
if(smoke)
fadeOut(smoke)
smoke.delete()
#undef EXTINGUISHER
#undef NANOFROST
#undef METAL_FOAM
+2 -1
View File
@@ -25,7 +25,8 @@
/obj/structure/Destroy()
if(hascall(src, "unbuckle"))
src:unbuckle()
..()
/obj/structure/mech_melee_attack(obj/mecha/M)
if(M.damtype == "brute")
M.occupant_message("<span class='danger'>You hit [src].</span>")
@@ -85,6 +85,7 @@
new /obj/item/weapon/holosign_creator(src)
new /obj/item/clothing/gloves/black(src)
new /obj/item/clothing/head/soft/purple(src)
new /obj/item/weapon/watertank/janitor(src)
new /obj/item/weapon/storage/belt/janitor(src)
/*
@@ -144,6 +144,7 @@
new /obj/item/clothing/suit/storage/hazardvest(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
new /obj/item/weapon/watertank/atmos(src)
new /obj/item/clothing/suit/fire/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
@@ -115,9 +115,9 @@
new /obj/item/clothing/mask/gas/sechailer/hos(src)
new /obj/item/weapon/shield/riot(src)
new /obj/item/weapon/melee/baton/loaded(src)
new /obj/item/weapon/gun/energy/advtaser(src)
new /obj/item/weapon/storage/belt/security(src)
new /obj/item/taperoll/police(src)
new /obj/item/weapon/gun/energy/hos(src)
return
@@ -10,6 +10,17 @@
climbable = 1
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
var/rigged = 0
var/obj/item/weapon/paper/manifest/manifest
/obj/structure/closet/crate/New()
..()
update_icon()
/obj/structure/closet/crate/update_icon()
..()
overlays.Cut()
if(manifest)
overlays += "manifest"
/obj/structure/closet/crate/can_open()
return 1
@@ -183,6 +194,29 @@
else
return
/obj/structure/closet/crate/attack_hand(mob/user as mob)
if(manifest)
user << "<span class='notice'>You tear the manifest off of the crate.</span>"
playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1)
manifest.loc = loc
if(ishuman(user))
user.put_in_hands(manifest)
manifest = null
update_icon()
return
else
if(rigged && locate(/obj/item/device/radio/electropack) in src)
if(isliving(user))
var/mob/living/L = user
if(L.electrocute_act(17, src))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
return
src.add_fingerprint(user)
src.toggle(user)
return
/obj/structure/closet/crate/secure
desc = "A secure crate."
name = "Secure crate"
@@ -196,13 +230,16 @@
var/broken = 0
var/locked = 1
/obj/structure/closet/crate/secure/New()
/obj/structure/closet/crate/secure/update_icon()
..()
overlays.Cut()
if(manifest)
overlays += "manifest"
if(locked)
overlays.Cut()
overlays += redlight
else if(broken)
overlays += emag
else
overlays.Cut()
overlays += greenlight
/obj/structure/closet/crate/secure/can_open()
@@ -220,8 +257,7 @@
for(var/mob/O in viewers(user, 3))
if((O.client && !( O.blinded )))
O << "<span class='notice'>The crate has been [locked ? null : "un"]locked by [user].</span>"
overlays.Cut()
overlays += locked ? redlight : greenlight
update_icon()
else
user << "<span class='notice'>Access Denied</span>"
@@ -240,23 +276,31 @@
usr << "<span class='warning'>This mob type can't use this verb.</span>"
/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
src.add_fingerprint(user)
if(manifest)
user << "<span class='notice'>You tear the manifest off of the crate.</span>"
playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1)
manifest.loc = loc
if(ishuman(user))
user.put_in_hands(manifest)
manifest = null
update_icon()
return
if(locked)
src.togglelock(user)
else
src.toggle(user)
/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(is_type_in_list(W, list(/obj/item/stack/packageWrap, /obj/item/stack/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters)))
return ..()
if(locked && (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)))
overlays.Cut()
overlays += emag
overlays += sparks
spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
playsound(src.loc, "sparks", 60, 1)
src.locked = 0
src.broken = 1
update_icon()
user << "<span class='notice'>You unlock \the [src].</span>"
return
if(!opened)
@@ -270,15 +314,12 @@
if(!broken && !opened && prob(50/severity))
if(!locked)
src.locked = 1
overlays.Cut()
overlays += redlight
else
overlays.Cut()
overlays += emag
overlays += sparks
spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
src.locked = 0
update_icon()
if(!opened && prob(20/severity))
if(!locked)
open()
@@ -4,13 +4,38 @@
icon = 'icons/obj/storage.dmi'
icon_state = "densecrate"
density = 1
var/obj/item/weapon/paper/manifest/manifest
/obj/structure/largecrate/New()
..()
update_icon()
/obj/structure/largecrate/update_icon()
..()
overlays.Cut()
if(manifest)
overlays += "manifest"
/obj/structure/largecrate/attack_hand(mob/user as mob)
user << "<span class='notice'>You need a crowbar to pry this open!</span>"
return
if(manifest)
user << "<span class='notice'>You tear the manifest off of the crate.</span>"
playsound(src.loc, 'sound/items/poster_ripped.ogg', 75, 1)
manifest.loc = loc
if(ishuman(user))
user.put_in_hands(manifest)
manifest = null
update_icon()
return
else
user << "<span class='notice'>You need a crowbar to pry this open!</span>"
return
/obj/structure/largecrate/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/crowbar))
if(manifest)
manifest.loc = loc
manifest = null
update_icon()
new /obj/item/stack/sheet/wood(src)
var/turf/T = get_turf(src)
for(var/obj/O in contents)
+1 -1
View File
@@ -19,7 +19,7 @@
instrumentDir = dir
instrumentObj = obj
/datum/song/proc/Destroy()
/datum/song/Destroy()
instrumentObj = null
return
+16 -7
View File
@@ -131,9 +131,8 @@ var/list/mechtoys = list(
var/comment = null
/datum/controller/supply
var/processing = 1
var/processing_interval = 300
var/iteration = 0
processing = 1
processing_interval = 300
//supply points
var/points = 50
var/points_per_process = 1
@@ -224,8 +223,8 @@ var/list/mechtoys = list(
plat_count += P.amount
// If you send something in a crate, centcom's keeping it! - fixes secure crates being sent to centom to open them
del(A)
del(MA)
qdel(A)
qdel(MA)
if(plasma_count)
points += plasma_count * points_per_plasma
@@ -291,8 +290,16 @@ var/list/mechtoys = list(
//manifest finalisation
slip.info += "</ul><br>"
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>"
if (SP.contraband) slip.loc = null //we are out of blanks for Form #44-D Ordering Illicit Drugs.
if(!SP.contraband)
if(istype(A, /obj/structure/closet/crate))
var/obj/structure/closet/crate/CR = A
CR.manifest = slip
CR.update_icon()
if(istype(A, /obj/structure/largecrate))
var/obj/structure/largecrate/LC = A
LC.manifest = slip
LC.update_icon()
else slip.loc = null //we are out of blanks for Form #44-D Ordering Illicit Drugs.
shoppinglist.Cut()
return
@@ -359,6 +366,7 @@ var/list/mechtoys = list(
temp += "<b>Request from: [get_supply_group_name(cat)]</b><BR><BR>"
for(var/supply_type in supply_controller.supply_packs )
var/datum/supply_packs/N = supply_controller.supply_packs[supply_type]
if(N.name == "HEADER") continue //skip HEADER entry to disable exploiting it for supply points
if(N.hidden || N.contraband || N.group != cat) continue //Have to send the type instead of a reference to
temp += "<A href='?src=\ref[src];doorder=[supply_type]'>[N.name]</A> Cost: [N.cost]<BR>" //the obj because it would get caught by the garbage
@@ -555,6 +563,7 @@ var/list/mechtoys = list(
temp += "<b>Request from: [get_supply_group_name(cat)]</b><BR><BR>"
for(var/supply_type in supply_controller.supply_packs )
var/datum/supply_packs/N = supply_controller.supply_packs[supply_type]
if(N.name == "HEADER") continue //skip HEADER entry to disable exploiting it for supply points
if((N.hidden && !hacked) || (N.contraband && !can_order_contraband) || N.group != cat) continue //Have to send the type instead of a reference to
temp += "<A href='?src=\ref[src];doorder=[supply_type]'>[N.name]</A> Cost: [N.cost]<BR>" //the obj because it would get caught by the garbage
+2 -1
View File
@@ -144,7 +144,8 @@ var/list/admin_verbs_debug = list(
/client/proc/callproc,
/client/proc/callproc_datum,
/client/proc/toggledebuglogs,
/client/proc/qdel_toggle // /vg/
/client/proc/qdel_toggle, // /vg/
/client/proc/gc_dump_hdl
)
var/list/admin_verbs_possess = list(
/proc/possess,
+2 -1
View File
@@ -33,6 +33,7 @@
if(check_rights(R_ADMIN, 0))
spanclass = "mod_channel_admin"
for(var/client/C in admins)
C << "<span class='[spanclass]'>MOD: <span class='name'>[key_name(usr, 1)]</span> (<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
if(R_MOD & C.holder.rights)
C << "<span class='[spanclass]'>MOD: <span class='name'>[key_name(usr, 1)]</span> (<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+9 -1
View File
@@ -335,4 +335,12 @@
icon_state = "shamebrero"
item_state = "shamebrero"
desc = "Once it's on, it never comes off."
flags = NODROP
flags = NODROP
/obj/item/clothing/head/griffin
name = "griffon head"
desc = "Why not 'eagle head'? Who knows."
icon_state = "griffinhat"
item_state = "griffinhat"
flags = BLOCKHAIR|NODROP
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
+1
View File
@@ -135,6 +135,7 @@
desc = "Twoooo!"
icon_state = "owl"
species_fit = list("Vox")
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | NODROP
// ********************************************************************
+8 -1
View File
@@ -150,4 +150,11 @@
/obj/item/clothing/shoes/centcom
name = "dress shoes"
desc = "They appear impeccably polished."
icon_state = "laceups"
icon_state = "laceups"
/obj/item/clothing/shoes/griffin
name = "griffon boots"
desc = "A pair of costume boots fashioned after bird talons."
icon_state = "griffinboots"
item_state = "griffinboots"
flags = NODROP
@@ -444,3 +444,30 @@
desc = "An overcoat for the clown soldier, to keep him warm during those cold winter nights on the front."
icon_state = "soldiersuit"
item_state = "soldiersuit"
/obj/item/clothing/suit/toggle/owlwings
name = "owl cloak"
desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad."
icon_state = "owl_wings"
item_state = "owl_wings"
body_parts_covered = ARMS
armor = list(melee = 5, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite)
action_button_name = "Toggle Owl Wings"
icon_action_button = "action_wings"
flags = NODROP
/obj/item/clothing/suit/toggle/owlwings/griffinwings
name = "griffon cloak"
desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad."
icon_state = "griffin_wings"
item_state = "griffin_wings"
/obj/item/clothing/suit/toggle/attack_self()
if(icon_state == initial(icon_state))
icon_state = icon_state + "_t"
item_state = icon_state + "_t"
else
icon_state = initial(icon_state)
item_state = initial(item_state)
usr.update_inv_wear_suit()
+17 -7
View File
@@ -140,12 +140,6 @@
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
siemens_coefficient = 0
/obj/item/clothing/under/owl
name = "owl uniform"
desc = "A jumpsuit with owl wings. Photorealistic owl feathers! Twooooo!"
icon_state = "owl"
_color = "owl"
/obj/item/clothing/under/johnny
name = "johnny~~ jumpsuit"
desc = "Johnny~~"
@@ -643,4 +637,20 @@
desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?"
icon_state = "checkered_suit"
item_state = "checkered_suit"
_color = "checkered_suit"
_color = "checkered_suit"
/obj/item/clothing/under/owl
name = "owl uniform"
desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction."
icon_state = "owl"
_color = "owl"
flags = NODROP
/obj/item/clothing/under/griffin
name = "griffon uniform"
desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem."
icon_state = "griffin"
_color = "griffin"
flags = NODROP
+6
View File
@@ -46,6 +46,12 @@
desc = "Dark Green beret with an old insignia on it."
icon_state = "sparkyninja_beret"
/obj/item/weapon/book/manual/security_space_law/black
name = "Space Law - Limited Edition"
desc = "A leather-bound, immaculately-written copy of JUSTICE."
icon_state = "bookSpaceLawblack"
title = "Space Law - Limited Edition"
//////////////////////////////////
////////// Fluff Items ///////////
//////////////////////////////////
+15
View File
@@ -1,3 +1,18 @@
#define EMOTE_COOLDOWN 50 //Time in deciseconds that the cooldown lasts
//Emote Cooldown System (it's so simple!)
/mob/proc/handle_emote_CD()
if(emote_cd == 2) return 1 // Cooldown emotes were disabled by an admin, prevent use
if(src.emote_cd == 1) return 1 // Already on CD, prevent use
src.emote_cd = 1 // Starting cooldown
spawn(EMOTE_COOLDOWN)
if(emote_cd == 2) return 1 // Don't reset if cooldown emotes were disabled by an admin during the cooldown
src.emote_cd = 0 // Cooldown complete, ready for more!
return 0 // Proceed with emote
//--FalseIncarnate
// All mobs should have custom emote, really..
/mob/proc/custom_emote(var/m_type=1,var/message = null)
+13 -9
View File
@@ -18,6 +18,7 @@
var/native // If set, non-native speakers will have trouble speaking.
var/list/syllables // Used when scrambling text for a non-speaker.
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string.
var/follow = 0 // Applies to HIVEMIND languages - should a follow link be included for dead mobs?
/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4)
if(!syllables || !syllables.len)
@@ -102,7 +103,12 @@
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [format_message(message, get_spoken_verb(message))]</span></i>"
for(var/mob/player in player_list)
if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
if(istype(player,/mob/dead) && follow)
var/msg_dead = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> (<a href='byond://?src=\ref[player];follow2=\ref[player];follow=\ref[speaker]'>follow</a>) [format_message(message, get_spoken_verb(message))]</span></i>"
player << msg_dead
continue
else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player)))
player << msg
/datum/language/proc/check_special_condition(var/mob/other)
@@ -340,12 +346,7 @@
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
/datum/language/xenos/check_special_condition(var/mob/other)
var/mob/living/carbon/M = other
if(!istype(M))
return 1
return 0
follow = 1
/datum/language/ling
name = "Changeling"
@@ -395,6 +396,7 @@
exclaim_verb = "declares"
key = "b"
flags = RESTRICTED | HIVEMIND
follow = 1
var/drone_only
/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
@@ -409,8 +411,9 @@
var/message_body = "<span class='message'>[speaker.say_quote(message)], \"[message]\"</span></span></i>"
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
M.show_message("[message_start] [message_body]", 2)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain))
var/message_start_dead = "<i><span class='game say'>[name], <span class='name'>[speaker.name] (<a href='byond://?src=\ref[M];follow2=\ref[M];follow=\ref[speaker]'>follow</a>)</span>"
M.show_message("[message_start_dead] [message_body]", 2)
for (var/mob/living/S in living_mob_list)
@@ -447,6 +450,7 @@
key = "d"
flags = RESTRICTED | HIVEMIND
drone_only = 1
follow = 1
// Language handling.
/mob/proc/add_language(var/language)
@@ -88,12 +88,14 @@
update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(A)
var/msg = ""
if(!leaping)
return ..()
if(A)
if(istype(A, /mob/living))
var/mob/living/L = A
msg = "<span class ='alertalien'>[src] pounces on [A]!</span>"
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Weaken(5)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
@@ -103,13 +105,12 @@
spawn(pounce_cooldown_time) //3s by default
pounce_cooldown = !pounce_cooldown
else
msg = "<span class ='alertalien'>[src] smashes into [A]!</span>"
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
weakened = 2
if(leaping)
leaping = 0
update_canmove()
visible_message(msg)
/mob/living/carbon/alien/humanoid/float(on)
@@ -157,7 +158,5 @@
src.throwing = 0
if(isobj(src))
src.throw_impact(get_turf(src))
return 1
@@ -22,7 +22,7 @@
name = text("alien ([rand(1, 1000)])")
real_name = name
add_language("Xenomorph")
add_language("Hivemind")
add_language("Hivemind")
..()
//This is fine, works the same as a human
@@ -65,7 +65,7 @@
return (tally + move_delay_add + config.alien_delay)
/mob/living/carbon/alien/humanoid/Process_Spacemove(var/check_drift = 0)
return 1
return 0
///mob/living/carbon/alien/humanoid/bullet_act(var/obj/item/projectile/Proj) taken care of in living
@@ -121,7 +121,7 @@
show_message("<span class='userdanger'>The blob attacks!</span>")
adjustFireLoss(damage)
return
/mob/living/carbon/alien/humanoid/meteorhit(O as obj)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
@@ -271,7 +271,7 @@
if (HULK in M.mutations)//HULK SMASH
damage += 14
spawn(0)
Weaken(damage) // Why can a hulk knock an alien out but not knock out a human? Damage is robust enough.
Paralyse(1)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
@@ -279,7 +279,7 @@
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>")
if ((stat != DEAD) && (damage > 9||prob(5)))//Regular humans have a very small chance of weakening an alien.
Weaken(1,5)
Paralyse(2)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>", \
"<span class='danger'>You hear someone fall.</span>")
@@ -292,7 +292,7 @@
if ("disarm")
if (!lying)
if (prob(5))//Very small chance to push an alien down.
Weaken(2)
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
@@ -399,4 +399,4 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/humanoid/canBeHandcuffed()
return 1
return 1
@@ -24,7 +24,7 @@
real_name = name
regenerate_icons()
add_language("Xenomorph")
add_language("Hivemind")
add_language("Hivemind")
..()
//This is fine, works the same as a human
@@ -128,7 +128,7 @@
//can't equip anything
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
/mob/living/carbon/alien/larva/meteorhit(O as obj)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
@@ -254,7 +254,7 @@
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>")
if ((stat != DEAD) && (damage > 4.9))
Weaken(rand(5,10))
Paralyse(rand(5,10))
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>", \
"<span class='danger'>You hear someone fall.</span>")
+2 -1
View File
@@ -1,5 +1,6 @@
/mob/living/carbon/alien/proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
if(reagents)
reagents.metabolize(src)
if (drowsyness)
drowsyness--
+13 -2
View File
@@ -16,9 +16,20 @@
return emote(copytext(message,2))
var/datum/language/speaking = parse_language(message)
if(speaking)
message = copytext(message, 2+length(speaking.key))
message = copytext(message,2+length(speaking.key))
else
speaking = all_languages["Xenomorph"]
var/ending = copytext(message, length(message))
if (speaking)
// This is broadcast to all mobs with the language,
// irrespective of distance or anything else.
if(speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
return
//If we've gotten this far, keep going!
verb = speaking.get_spoken_verb(ending)
message = trim(message)
+13 -4
View File
@@ -78,7 +78,10 @@
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
if(status_flags & GODMODE) return 0 //godmode
if(status_flags & GODMODE) //godmode
return 0
if(NO_SHOCK in mutations) //shockproof
return 0
shock_damage *= siemens_coeff
if (shock_damage<1)
return 0
@@ -99,8 +102,14 @@
"\red <B>You feel a powerful shock course through your body!</B>", \
"\red You hear a heavy electrical crack." \
)
Stun(10)//This should work for now, more is really silly and makes you lay there forever
Weaken(10)
jitteriness += 1000 //High numbers for violent convulsions
do_jitter_animation(jitteriness)
stuttering += 2
Stun(2)
spawn(20)
jitteriness -= 990 //Still jittery, but vastly less
Stun(3)
Weaken(3)
if (shock_damage > 200)
src.visible_message(
"\red [src] was arc flashed by the [source]!", \
@@ -588,6 +597,6 @@
/mob/living/carbon/proc/canBeHandcuffed()
return 0
/mob/living/carbon/is_muzzled()
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
+107 -51
View File
@@ -20,69 +20,100 @@
if(src.stat == 2.0 && (act != "deathgasp"))
return
//Emote Cooldown System (it's so simple!)
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
var/on_CD = 0
switch(act)
//Cooldown-inducing emotes
if("ping","buzz","beep")
if (species.name == "Machine") //Only Machines can beep, ping, and buzz
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
else //Everyone else fails, skip the emote attempt
return
if("squish")
if(species.name == "Slime People") //Only Slime People can squish
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
else //Everyone else fails, skip the emote attempt
return
if("scream", "fart", "flip")
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
//Everything else, including typos of the above emotes
else
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
if(on_CD == 1) // Check if we need to suppress the emote attempt.
return // Suppress emote, you're still cooling off.
//--FalseIncarnate
switch(act)
if("ping")
if (species.name == "Machine")
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
if (param)
message = "<B>[src]</B> pings at [param]."
else
message = "<B>[src]</B> pings."
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 1
if (param)
message = "<B>[src]</B> pings at [param]."
else
if (!species.name == "Machine")
return
message = "<B>[src]</B> pings."
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
m_type = 1
if("buzz")
if (species.name == "Machine")
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
if (param)
message = "<B>[src]</B> buzzes at [param]."
else
message = "<B>[src]</B> buzzes."
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 1
if (param)
message = "<B>[src]</B> buzzes at [param]."
else
if (!species.name == "Machine")
return
message = "<B>[src]</B> buzzes."
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
m_type = 1
if("beep")
if(species.name == "Machine")
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
if (param)
message = "<B>[src]</B> beeps at [param]."
else
message = "<B>[src]</B> beeps."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 1
if (param)
message = "<B>[src]</B> beeps at [param]."
else
if (!species.name == "Machine")
return
message = "<B>[src]</B> beeps."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
m_type = 1
if("squish")
var/M = null
if(param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if(!M)
param = null
if (param)
message = "<B>[src]</B> squishes at [param]."
else
message = "<B>[src]</B> squishes."
playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
m_type = 1
if("wag")
if(species.bodyflags & TAIL_WAGGING)
@@ -204,6 +235,31 @@
if(miming)
m_type = 1
if ("flip")
m_type = 1
if (!src.restrained())
var/M = null
if (param)
for (var/mob/A in view(1, null))
if (param == A.name)
M = A
break
if (M == src)
M = null
if (M)
if(src.lying || src.weakened)
message = "<B>[src]</B> flops and flails around on the floor."
else
message = "<B>[src]</B> flips in [M]'s general direction."
src.SpinAnimation(5,1)
else
if(src.lying || src.weakened)
message = "<B>[src]</B> flops and flails around on the floor."
else
message = "<B>[src]</B> does a flip!"
src.SpinAnimation(5,1)
if ("aflap")
if (!src.restrained())
message = "<B>[src]</B> flaps his wings ANGRILY!"
@@ -403,7 +403,7 @@
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/datum/organ/external/affecting = get_organ(ran_zone(L.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
apply_damage(damage, BRUTE, affecting, armor_block)
/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
for(var/L in M.contents)
@@ -636,7 +636,10 @@
//Removed the horrible safety parameter. It was only being used by ninja code anyways.
//Now checks siemens_coefficient of the affected area by default
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null)
if(status_flags & GODMODE) return 0 //godmode
if(status_flags & GODMODE) //godmode
return 0
if(NO_SHOCK in mutations) //shockproof
return 0
if (!def_zone)
def_zone = pick("l_hand", "r_hand")
@@ -32,7 +32,9 @@
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
if(HULK in M.mutations)
damage += 5
Weaken(4)
playsound(loc, "punch", 25, 1, -1)
@@ -139,8 +141,9 @@
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
if(HULK in M.mutations)
damage += 5
Weaken(4)
playsound(loc, attack.attack_sound, 25, 1, -1)
@@ -32,7 +32,7 @@
timeofdeath = 0
/mob/living/carbon/human/getBrainLoss()
if(species && species.flags & NO_INTORGANS)
if(species && species.flags & NO_INTORGANS)
return
var/res = brainloss
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
@@ -110,15 +110,12 @@
hud_updateflag |= 1 << HEALTH_HUD
/mob/living/carbon/human/Stun(amount)
if(HULK in mutations) return
..()
/mob/living/carbon/human/Weaken(amount)
if(HULK in mutations) return
..()
/mob/living/carbon/human/Paralyse(amount)
if(HULK in mutations) return
..()
+22 -14
View File
@@ -62,7 +62,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(life_tick%30==15)
hud_updateflag = 1022
voice = GetVoice()
//No need to update all of these procs if the guy is dead.
@@ -632,8 +632,20 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
handle_fire()
if(..())
return
var/thermal_protection = get_heat_protection(10000) //If you don't have fire suit level protection, you get a temperature increase
if((1 - thermal_protection) > 0.0001)
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
if(wear_suit)
if(wear_suit.max_heat_protection_temperature >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE)
thermal_protection += (wear_suit.max_heat_protection_temperature*0.7)
if(head)
if(head.max_heat_protection_temperature >= FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE)
thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD)
thermal_protection = round(thermal_protection)
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
return
if(thermal_protection >= FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE)
bodytemperature += 11
return
else
bodytemperature += BODYTEMP_HEATING_MAX
return
//END FIRE CODE
@@ -914,10 +926,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
traumatic_shock -= light_amount
if(species.flags & IS_PLANT)
if(nutrition > 500)
nutrition = 500
if(nutrition > 450)
nutrition = 450
if(light_amount >= 5) //if there's enough light, heal
adjustBruteLoss(-(light_amount))
adjustBruteLoss(-(light_amount/2))
adjustFireLoss(-(light_amount/4))
//adjustToxLoss(-(light_amount))
adjustOxyLoss(-(light_amount))
//TODO: heal wounds, heal broken limbs.
@@ -1165,13 +1179,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
//Jitteryness
if(jitteriness)
var/amplitude = min(4, (jitteriness/100) + 1)
var/pixel_x_diff = rand(-amplitude, amplitude)
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2)
jitteriness = max(jitteriness-1, 0)
do_jitter_animation(jitteriness)
//Other
handle_statuses()
@@ -1926,7 +1934,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
var/client/C = client
for(var/mob/living/carbon/human/H in view(src, 14))
C.images += H.hud_list[NATIONS_HUD]
/mob/living/carbon/human/handle_silent()
if(..())
speech_problem_flag = 1
@@ -420,7 +420,7 @@ proc/get_damage_icon_part(damage_state, body_part)
return
//masks and helmets can obscure our hair, unless we're a synthetic
if(!(species.flags & IS_SYNTHETIC) && (head && (head.flags & BLOCKHAIR)) || !(species.flags & IS_SYNTHETIC) && (wear_mask && (wear_mask.flags & BLOCKHAIR)))
if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
if(update_icons) update_icons()
return
+21 -4
View File
@@ -11,6 +11,24 @@
var/muzzled = is_muzzled()
//Emote Cooldown System (it's so simple!)
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
var/on_CD = 0
switch(act)
//Cooldown-inducing emotes
if("chirp")
if(istype(src,/mob/living/carbon/monkey/diona)) //Only Diona Nymphs can chirp
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
else //Everyone else fails, skip the emote attempt
return
//Everything else, including typos of the above emotes
else
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
if(on_CD == 1) // Check if we need to suppress the emote attempt.
return // Suppress emote, you're still cooling off.
//--FalseIncarnate
switch(act)
if ("me")
if(silent)
@@ -32,10 +50,9 @@
return custom_emote(m_type, message)
if ("chirp")
if(istype(src,/mob/living/carbon/monkey/diona))
message = "<B>The [src.name]</B> chirps!"
playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
m_type = 2
message = "<B>The [src.name]</B> chirps!"
playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
m_type = 2
if("sign")
if (!src.restrained())
message = text("<B>The monkey</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
@@ -121,7 +121,10 @@
if ((HULK in mutations) && health <= 25)
mutations.Remove(HULK)
src << "\red You suddenly feel very weak."
dna.SetSEState(HULKBLOCK,0)
update_mutations() //update our mutation overlays
status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved.
src << "<span class='danger'>You suddenly feel very weak.</span>"
Weaken(3)
emote("collapse")
@@ -131,7 +131,7 @@
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(istype(tmob, /mob/living/carbon/human) && (HULK in tmob.mutations))
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(70))
usr << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
@@ -188,8 +188,8 @@
if ((O.icon_state == "flaming" && !( shielded )))
adjustFireLoss(40)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
return
return
/mob/living/carbon/monkey/attack_paw(mob/living/M as mob)
..()
@@ -434,7 +434,7 @@
updatehealth()
return
/mob/living/carbon/monkey/Stat()
..()
statpanel("Status")
@@ -0,0 +1,28 @@
/mob/living/carbon/monkey/say(var/message)
var/verb = "says"
var/message_range = world.view
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
return
message = trim_strip_html_properly(message)
if(stat == 2)
return say_dead(message)
if(copytext(message,1,2) == "*")
return emote(copytext(message,2))
var/datum/language/speaking = parse_language(message)
if(speaking)
message = copytext(message, 2+length(speaking.key))
message = trim(message)
if(!message || stat)
return
..(message, speaking, verb, null, null, message_range, null)
+6 -2
View File
@@ -58,6 +58,8 @@
halloss += effect // Useful for objects that cause "subdual" damage. PAIN!
if(IRRADIATE)
radiation += max(effect * ((100-run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm."))/100),0)//Rads auto check armor
if(SLUR)
slurring = max(slurring,(effect * blocked))
if(STUTTER)
if(status_flags & CANSTUN) // stun is usually associated with stutter
stuttering = max(stuttering,(effect * blocked))
@@ -66,7 +68,8 @@
if(DROWSY)
drowsyness = max(drowsyness,(effect * blocked))
if(JITTER)
jitteriness = max(jitteriness,(effect * blocked))
if(status_flags & CANSTUN)
jitteriness = max(jitteriness,(effect * blocked))
updatehealth()
return 1
@@ -80,12 +83,13 @@
/mob/living/carbon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
return ..()
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0)
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/slur = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0)
if(blocked >= 100) return 0
if(stun) apply_effect(stun, STUN, blocked)
if(weaken) apply_effect(weaken, WEAKEN, blocked)
if(paralyze) apply_effect(paralyze, PARALYZE, blocked)
if(irradiate) apply_effect(irradiate, IRRADIATE, blocked)
if(slur) apply_effect(slur, SLUR, blocked)
if(stutter) apply_effect(stutter, STUTTER, blocked)
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
+15 -4
View File
@@ -47,8 +47,6 @@
/mob/living/proc/burn_skin(burn_amount)
if(istype(src, /mob/living/carbon/human))
//world << "DEBUG: burn_skin(), mutations=[mutations]"
if(NO_SHOCK in src.mutations) //shockproof
return 0
if (RESIST_HEAT in src.mutations) //fireproof
return 0
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
@@ -629,7 +627,8 @@
var/mob/living/carbon/CM = L
if(CM.on_fire && CM.canmove)
CM.fire_stacks -= 5
CM.Weaken(3)
CM.weakened = max(CM.weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
CM.update_canmove()
CM.spin(32,2)
CM.visible_message("<span class='danger'>[CM] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
@@ -761,7 +760,7 @@
/mob/living/proc/can_use_vents()
return "You can't fit into that vent."
/atom/movable/proc/do_attack_animation(atom/A)
@@ -791,3 +790,15 @@
pixel_y_diff = -8
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = initial(pixel_x), pixel_y = initial(pixel_y), time = 2)
/mob/living/do_attack_animation(atom/A)
..()
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
/mob/living/proc/do_jitter_animation(jitteriness)
var/amplitude = min(4, (jitteriness/100) + 1)
var/pixel_x_diff = rand(-amplitude, amplitude)
var/pixel_y_diff = rand(-amplitude/3, amplitude/3)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2)
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
+8 -16
View File
@@ -223,19 +223,21 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0)
on_fire = 1
src.AddLuminosity(3)
update_fire()
/mob/living/proc/ExtinguishMob()
if(on_fire)
on_fire = 0
fire_stacks = 0
src.AddLuminosity(-3)
update_fire()
/mob/living/proc/update_fire()
return
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20)
fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = -20, max = 20)
/mob/living/proc/handle_fire()
if(fire_stacks < 0)
@@ -243,25 +245,15 @@
fire_stacks = min(0, fire_stacks)//So we dry ourselves back to default, nonflammable.
if(!on_fire)
return 1
var/oxy=0
var/turf/T=loc
if(istype(T))
if(istype(T,/turf/space))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return 1
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G)
oxy=G.oxygen
if(oxy < 10 || fire_stacks <= 0)
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.oxygen < 1)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return 1
return
var/turf/location = get_turf(src)
location.hotspot_expose(700, 50, 1)
/mob/living/fire_act()
adjust_fire_stacks(5)
if(fire_stacks > 9 && !on_fire)
IgniteMob()
adjust_fire_stacks(0.5)
IgniteMob()
//Mobs on Fire end
+73 -31
View File
@@ -2,6 +2,32 @@
#define AI_CHECK_RADIO 2
var/list/ai_list = list()
var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/ai_alerts,
/mob/living/silicon/ai/proc/announcement,
/mob/living/silicon/ai/proc/ai_call_shuttle,
/mob/living/silicon/ai/proc/ai_cancel_call,
/mob/living/silicon/ai/proc/ai_camera_track,
/mob/living/silicon/ai/proc/ai_camera_list,
/mob/living/silicon/ai/proc/ai_goto_location,
/mob/living/silicon/ai/proc/ai_remove_location,
/mob/living/silicon/ai/proc/ai_hologram_change,
/mob/living/silicon/ai/proc/ai_network_change,
/mob/living/silicon/ai/proc/ai_roster,
/mob/living/silicon/ai/proc/ai_statuschange,
/mob/living/silicon/ai/proc/ai_store_location,
/mob/living/silicon/ai/proc/checklaws,
/mob/living/silicon/ai/proc/control_integrated_radio,
/mob/living/silicon/ai/proc/core,
/mob/living/silicon/ai/proc/pick_icon,
/mob/living/silicon/ai/proc/sensor_mode,
/mob/living/silicon/ai/proc/show_laws_verb,
/mob/living/silicon/ai/proc/toggle_acceleration,
/mob/living/silicon/ai/proc/toggle_camera_light,
/mob/living/silicon/ai/proc/botcall,
/mob/living/silicon/ai/proc/change_arrival_message,
/mob/living/silicon/ai/proc/nano_crew_monitor
)
//Not sure why this is necessary...
/proc/AutoUpdateAI(obj/subject)
@@ -14,7 +40,6 @@ var/list/ai_list = list()
subject.attack_ai(M)
return is_in_use
/mob/living/silicon/ai
name = "AI"
icon = 'icons/mob/AI.dmi'//
@@ -69,6 +94,12 @@ var/list/ai_list = list()
var/arrivalmsg = "$name, $rank, has arrived on the station."
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
/mob/living/silicon/ai/proc/remove_ai_verbs()
src.verbs -= ai_verbs_default
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
var/list/possibleNames = ai_names
@@ -101,22 +132,20 @@ var/list/ai_list = list()
aiMulti = new(src)
aiRadio = new(src)
common_radio = aiRadio
aiRadio.myAi = src
aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_store_location, /mob/living/silicon/ai/proc/ai_goto_location, /mob/living/silicon/ai/proc/ai_remove_location, /mob/living/silicon/ai/proc/nano_crew_monitor, /mob/living/silicon/ai/proc/ai_cancel_call)
add_ai_verbs(src)
//Languages
add_language("Robot Talk", 1)
add_language("Galactic Common", 1)
add_language("Sol Common", 1)
add_language("Tradeband", 1)
add_language("Gutter", 0)
add_language("Sinta'unathi", 0)
add_language("Siik'tajr", 0)
add_language("Skrellian", 0)
@@ -125,37 +154,18 @@ var/list/ai_list = list()
add_language("Trinary", 1)
add_language("Chittin", 0)
add_language("Bubblish", 0)
add_language("Gutter", 0)
add_language("Clownish", 0)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
empty_playable_ai_cores += new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
del(src)//Delete AI.
return
else
if (B.brainmob.mind)
if(B.alien)
B.brainmob.mind.transfer_to(src)
icon_state = "ai-alien"
verbs.Remove(,/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light,/mob/living/silicon/ai/verb/pick_icon,/mob/living/silicon/ai/proc/control_hud, /mob/living/silicon/ai/proc/change_arrival_message, /mob/living/silicon/ai/proc/ai_cancel_call)
laws = new /datum/ai_laws/alienmov
add_language("xenocommon", 1)
else
B.brainmob.mind.transfer_to(src)
B.brainmob.mind.transfer_to(src)
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary."
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
on_mob_init()
spawn(5)
new /obj/machinery/ai_powersupply(src)
@@ -177,6 +187,30 @@ var/list/ai_list = list()
..()
return
/mob/living/silicon/ai/proc/on_mob_init()
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary. Use say :h to speak from an active holopad."
src << "For department channels, use the following say commands:"
var/radio_text = ""
for(var/i = 1 to common_radio.channels.len)
var/channel = common_radio.channels[i]
var/key = get_radio_key_from_channel(channel)
radio_text += "[key] - [channel]"
if(i != common_radio.channels.len)
radio_text += ", "
src << radio_text
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
/mob/living/silicon/ai/proc/SetName(pickedName as text)
real_name = pickedName
name = pickedName
@@ -225,7 +259,7 @@ var/list/ai_list = list()
if(powered_ai.anchored)
use_power = 2
/mob/living/silicon/ai/verb/pick_icon()
/mob/living/silicon/ai/proc/pick_icon()
set category = "AI Commands"
set name = "Set AI Core Display"
if(stat || aiRestorePowerRoutine)
@@ -289,6 +323,9 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/ai_alerts()
set name = "Show Alerts"
set category = "AI Commands"
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
dat += "<A HREF='?src=\ref[src];mach_close=aialerts'>Close</A><BR><BR>"
for (var/cat in alarms)
@@ -323,9 +360,14 @@ var/list/ai_list = list()
// this verb lets the ai see the stations manifest
/mob/living/silicon/ai/proc/ai_roster()
set name = "Show Crew Manifest"
set category = "AI Commands"
show_station_manifest()
/mob/living/silicon/ai/proc/ai_call_shuttle()
set name = "Call Emergency Shuttle"
set category = "AI Commands"
if(src.stat == 2)
src << "You can't call the shuttle because you are dead!"
return
@@ -905,7 +947,7 @@ var/list/ai_list = list()
else
lightNearbyCamera()
/mob/living/silicon/ai/proc/control_hud()
/mob/living/silicon/ai/proc/sensor_mode()
set name = "Set Sensor Augmentation"
set desc = "Augment visual feed with internal sensor overlays."
set category = "AI Commands"
+1 -1
View File
@@ -112,7 +112,7 @@
number++
/mob/living/silicon/ai/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
/mob/living/silicon/ai/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
set category = "AI Commands"
set name = "State Laws"
@@ -704,6 +704,7 @@
remove_language("Trinary")
remove_language("Chittin")
remove_language("Bubblish")
remove_language("Clownish")
src << "\blue Translator Module toggled OFF."
@@ -718,5 +719,6 @@
add_language("Trinary")
add_language("Chittin")
add_language("Bubblish")
add_language("Clownish")
src << "\blue Translator Module toggled ON."
@@ -8,6 +8,21 @@
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
//Emote Cooldown System (it's so simple!)
// proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
var/on_CD = 0
switch(act)
//Cooldown-inducing emotes
if("ping","buzz","beep","law") //halt is exempt because it's used to stop criminal scum
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
//Everything else, including typos of the above emotes
else
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
if(on_CD == 1) // Check if we need to suppress the emote attempt.
return // Suppress emote, you're still cooling off.
//--FalseIncarnate
switch(act)
if ("me")
if (src.client)
@@ -156,7 +156,7 @@
number++
/mob/living/silicon/robot/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
/mob/living/silicon/robot/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
set category = "Robot Commands"
set name = "State Laws"
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
+61 -51
View File
@@ -1,3 +1,8 @@
var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/sensor_mode,
/mob/living/silicon/robot/proc/checklaws
)
/mob/living/silicon/robot
name = "Cyborg"
real_name = "Cyborg"
@@ -71,8 +76,7 @@
var/braintype = "Cyborg"
var/base_icon = ""
var/crisis = 0
var/hiddenborg = 0
var/obj/item/borg/sight/hud/sec/sechud = null
var/obj/item/borg/sight/hud/med/healthhud = null
@@ -82,34 +86,21 @@
spark_system.attach(src)
add_language("Robot Talk", 1)
wires = new(src)
robot_modules_background = new()
robot_modules_background.icon_state = "block"
robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it.
wires = new(src)
ident = rand(1, 999)
updatename("Default")
updateicon()
if(mmi == null)
mmi = new /obj/item/device/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works)
mmi.icon_state="posibrain-occupied"
if(syndie)
if(!cell)
cell = new /obj/item/weapon/stock_parts/cell(src)
laws = new /datum/ai_laws/antimov()
lawupdate = 0
scrambledcodes = 1
cell.maxcharge = 25000
cell.charge = 25000
module = new /obj/item/weapon/robot_module/syndicate(src)
hands.icon_state = "standard"
icon_state = "secborg"
modtype = "Security"
init(alien)
radio = new /obj/item/device/radio/borg(src)
common_radio = radio
init()
if(!scrambledcodes && !camera)
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
@@ -117,6 +108,10 @@
if(wires.IsCameraCut()) // 5 = BORG CAMERA
camera.status = 0
if(mmi == null)
mmi = new /obj/item/device/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works)
mmi.icon_state="posibrain-occupied"
initialize_components()
//if(!unfinished)
// Create all the robot parts.
@@ -131,6 +126,8 @@
cell.charge = 7500
..()
add_robot_verbs()
if(cell)
var/datum/robot_component/cell_component = components["power cell"]
@@ -148,17 +145,9 @@
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
/mob/living/silicon/robot/proc/init(var/alien=0)
if(hiddenborg)
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
return
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
if(mmi.alien || alien)
laws = new /datum/ai_laws/alienmov()
connected_ai = select_active_alien_ai()
scrambledcodes = 1
else
make_laws()
connected_ai = select_active_ai_with_fewest_borgs()
make_laws()
connected_ai = select_active_ai_with_fewest_borgs()
if(connected_ai)
connected_ai.connected_robots += src
lawsync()
@@ -174,7 +163,7 @@
if (!rbPDA)
rbPDA = new/obj/item/device/pda/ai(src)
rbPDA.set_name_and_job(custom_name,braintype)
if(hiddenborg)
if(scrambledcodes)
rbPDA.hidden = 1
/mob/living/silicon/robot/binarycheck()
@@ -451,11 +440,17 @@
C.toggled = 1
src << "\red You enable [C.name]."
/mob/living/silicon/robot/verb/control_hud()
/mob/living/silicon/robot/proc/sensor_mode()
set name = "Set Sensor Augmentation"
set desc = "Augment visual feed with internal sensor overlays."
set category = "Robot Commands"
toggle_sensor_mode()
/mob/living/silicon/robot/proc/add_robot_verbs()
src.verbs |= robot_verbs_default
/mob/living/silicon/robot/proc/remove_robot_verbs()
src.verbs -= robot_verbs_default
/mob/living/silicon/robot/blob_act()
if (stat != 2)
@@ -1395,21 +1390,29 @@
icon_state = "nano_bloodhound"
lawupdate = 0
scrambledcodes = 1
hiddenborg = 1
modtype = "Commando"
faction = list("nanotrasen")
designation = "NT Combat Cyborg"
req_access = list(access_cent_specops)
/mob/living/silicon/robot/deathsquad/New(loc)
..()
cell.maxcharge = 50000
cell.charge = 50000
radio = new /obj/item/device/radio/borg/deathsquad(src)
module = new /obj/item/weapon/robot_module/deathsquad(src)
laws = new /datum/ai_laws/deathsquad()
if(!cell)
cell = new /obj/item/weapon/stock_parts/cell(src)
cell.maxcharge = 25000
cell.charge = 25000
Namepick()
..()
/mob/living/silicon/robot/deathsquad/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/deathsquad
module = new /obj/item/weapon/robot_module/deathsquad(src)
radio = new /obj/item/device/radio/borg/deathsquad(src)
radio.recalculateChannels()
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/deathsquad/attack_hand(mob/user)
if((ckey == null) && searching_for_ckey == 0)
@@ -1453,12 +1456,10 @@
get_borg_occupant(user, possiblecandidates)
return
/mob/living/silicon/robot/syndicate
icon_state = "syndie_bloodhound"
lawupdate = 0
scrambledcodes = 1
hiddenborg = 1
modtype = "Synd"
faction = list("syndicate")
designation = "Syndicate"
@@ -1466,14 +1467,23 @@
req_access = list(access_syndicate)
/mob/living/silicon/robot/syndicate/New(loc)
..()
cell.maxcharge = 25000
cell.charge = 25000
radio = new /obj/item/device/radio/borg/syndicate(src)
module = new /obj/item/weapon/robot_module/syndicate(src)
laws = new /datum/ai_laws/syndicate_override()
if(!cell)
cell = new /obj/item/weapon/stock_parts/cell(src)
cell.maxcharge = 25000
cell.charge = 25000
Namepick()
..()
/mob/living/silicon/robot/syndicate/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/syndicate_override
module = new /obj/item/weapon/robot_module/syndicate(src)
radio = new /obj/item/device/radio/borg/syndicate(src)
radio.recalculateChannels()
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/syndicate/canUseTopic(atom/movable/M)
if(stat || lockcharge || stunned || weakened)
@@ -1,92 +1,4 @@
// A special tray for the service droid. Allow droid to pick up and drop items as if they were using the tray normally
// Click on table to unload, click on item to load. Otherwise works identically to a tray.
// Unlike the base item "tray", robotrays ONLY pick up food, drinks and condiments.
/obj/item/weapon/tray/robotray
name = "RoboTray"
desc = "An autoloading tray specialized for carrying refreshments."
/obj/item/weapon/tray/robotray/afterattack(atom/target, mob/user as mob)
if ( !target )
return
// pick up items, mostly copied from base tray pickup proc
// see code\game\objects\items\weapons\kitchen.dm line 241
if ( istype(target,/obj/item))
if ( !isturf(target.loc) ) // Don't load up stuff if it's inside a container or mob!
return
var turf/pickup = target.loc
var addedSomething = 0
for(var/obj/item/weapon/reagent_containers/food/I in pickup)
if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) )
var/add = 0
if(I.w_class == 1.0)
add = 1
else if(I.w_class == 2.0)
add = 3
else
add = 5
if(calc_carry() + add >= max_carry)
break
I.loc = src
carrying.Add(I)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer)
addedSomething = 1
if ( addedSomething )
user.visible_message("\blue [user] load some items onto their service tray.")
return
// Unloads the tray, copied from base item's proc dropped() and altered
// see code\game\objects\items\weapons\kitchen.dm line 263
if ( isturf(target) || istype(target,/obj/structure/table) )
var foundtable = istype(target,/obj/structure/table/)
if ( !foundtable ) //it must be a turf!
for(var/obj/structure/table/T in target)
foundtable = 1
break
var turf/dropspot
if ( !foundtable ) // don't unload things onto walls or other silly places.
dropspot = user.loc
else if ( isturf(target) ) // they clicked on a turf with a table in it
dropspot = target
else // they clicked on a table
dropspot = target.loc
overlays = null
var droppedSomething = 0
for(var/obj/item/I in carrying)
I.loc = dropspot
carrying.Remove(I)
droppedSomething = 1
if(!foundtable && isturf(dropspot))
// if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere!
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
if ( droppedSomething )
if ( foundtable )
user.visible_message("\blue [user] unloads their service tray.")
else
user.visible_message("\blue [user] drops all the items on their tray.")
return ..()
// A special pen for service droids. Can be toggled to switch between normal writting mode, and paper rename mode
// A special pen for service droids. Can be toggled to switch between normal writing mode, and paper rename mode
// Allows service droids to rename paper items.
/obj/item/weapon/pen/robopen
@@ -62,6 +62,7 @@
R.add_language("Galactic Common", 1)
R.add_language("Sol Common", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 0)
R.add_language("Sinta'unathi", 0)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 0)
@@ -70,7 +71,7 @@
R.add_language("Trinary", 1)
R.add_language("Chittin", 0)
R.add_language("Bubblish", 0)
R.add_language("Gutter", 0)
R.add_language("Clownish",0)
/obj/item/weapon/robot_module/standard
name = "standard robot module"
@@ -216,7 +217,7 @@
src.modules += new /obj/item/device/flashlight(src)
src.modules += new /obj/item/device/flash/cyborg(src)
src.modules += new /obj/item/weapon/soap/nanotrasen(src)
src.modules += new /obj/item/weapon/storage/bag/trash(src)
src.modules += new /obj/item/weapon/storage/bag/trash/cyborg(src)
src.modules += new /obj/item/weapon/mop(src)
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/holosign_creator(src)
@@ -247,7 +248,7 @@
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
src.modules += new /obj/item/weapon/lighter/zippo(src)
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/storage/bag/tray/cyborg(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src)
@@ -270,6 +271,7 @@
R.add_language("Galactic Common", 1)
R.add_language("Sol Common", 1)
R.add_language("Tradeband", 1)
R.add_language("Gutter", 1)
R.add_language("Sinta'unathi", 1)
R.add_language("Siik'tajr", 1)
R.add_language("Skrellian", 1)
@@ -278,7 +280,7 @@
R.add_language("Trinary", 1)
R.add_language("Chittin", 1)
R.add_language("Bubblish", 1)
R.add_language("Gutter", 1)
R.add_language("Clownish",1)
/*
/obj/item/weapon/robot_module/clerical //Whyyyyy?
@@ -22,6 +22,7 @@
#define SEC_HUD 1 //Security HUD mode
#define MED_HUD 2 //Medical HUD mode
var/local_transmit //If set, can only speak to others of the same type within a short range.
var/obj/item/device/radio/common_radio
/mob/living/silicon/proc/cancelAlarm()
return
+25 -19
View File
@@ -855,7 +855,7 @@ var/list/slot_equipment_priority = list( \
return 0
src << message
return 1
/mob/proc/is_muzzled()
return 0
@@ -873,25 +873,14 @@ var/list/slot_equipment_priority = list( \
stat(null, "CPU:\t[world.cpu]")
stat(null, "Instances:\t[world.contents.len]")
if(master_controller)
/* HANDLED THROUGH PROCESS SCHEDULER
stat(null, "MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])")
stat(null, "Air-[master_controller.air_cost]")
stat(null, "Sun-[master_controller.sun_cost]")
stat(null, "Mob-[master_controller.mobs_cost]\t#[mob_list.len]")
stat(null, "Dis-[master_controller.diseases_cost]\t#[active_diseases.len]")
stat(null, "Mch-[master_controller.machines_cost]\t#[machines.len]")
stat(null, "Bots-[master_controller.aibots_cost]\t#[aibots.len]")
stat(null, "Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
stat(null, "PiNet-[master_controller.networks_cost]\t#[pipe_networks.len]")
stat(null, "PoNet-[master_controller.powernets_cost]\t#[powernets.len]")
stat(null, "NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
// stat(null, "GC-[master_controller.gc_cost]\t#[garbage.queue.len]")
stat(null, "Tick-[master_controller.ticker_cost]")*/
stat(null,"Events-[master_controller.events_cost]\t#[event_manager.active_events.len]")
stat(null, "ALL-[master_controller.total_cost]")
if (garbageCollector)
stat(null, "\tqdel - [garbageCollector.del_everything ? "off" : "on"]")
stat(null, "\ton queue - [garbageCollector.queue.len]")
stat(null, "\ttotal delete - [garbageCollector.dels_count]")
stat(null, "\tsoft delete - [garbageCollector.soft_dels]")
stat(null, "\thard delete - [garbageCollector.hard_dels]")
else
stat(null, "MasterController-ERROR")
stat(null, "Garbage Controller is not running.")
if(processScheduler.getIsRunning())
var/datum/controller/process/process
@@ -929,6 +918,9 @@ var/list/slot_equipment_priority = list( \
process = processScheduler.getProcess("disease")
stat(null, "DIS([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
process = processScheduler.getProcess("garbage")
stat(null, "GAR\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
//process = processScheduler.getProcess("sun")
//stat(null, "SUN\t - #[process.getTicks()]\t - [process.getLastRunTime()]")
@@ -960,6 +952,8 @@ var/list/slot_equipment_priority = list( \
for(var/atom/A in listed_turf)
if(A.invisibility > see_invisible)
continue
if(is_type_in_list(A, shouldnt_see))
continue
statpanel(listed_turf.name, null, A)
if(mind && mind.changeling)
@@ -1122,16 +1116,19 @@ var/list/slot_equipment_priority = list( \
/mob/proc/Stun(amount)
if(status_flags & CANSTUN)
stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
update_canmove()
return
/mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
if(status_flags & CANSTUN)
stunned = max(amount,0)
update_canmove()
return
/mob/proc/AdjustStunned(amount)
if(status_flags & CANSTUN)
stunned = max(stunned + amount,0)
update_canmove()
return
/mob/proc/Weaken(amount)
@@ -1155,40 +1152,49 @@ var/list/slot_equipment_priority = list( \
/mob/proc/Paralyse(amount)
if(status_flags & CANPARALYSE)
paralysis = max(max(paralysis,amount),0)
update_canmove()
return
/mob/proc/SetParalysis(amount)
if(status_flags & CANPARALYSE)
paralysis = max(amount,0)
update_canmove()
return
/mob/proc/AdjustParalysis(amount)
if(status_flags & CANPARALYSE)
paralysis = max(paralysis + amount,0)
update_canmove()
return
/mob/proc/Sleeping(amount)
sleeping = max(max(sleeping,amount),0)
update_canmove()
return
/mob/proc/SetSleeping(amount)
sleeping = max(amount,0)
update_canmove()
return
/mob/proc/AdjustSleeping(amount)
sleeping = max(sleeping + amount,0)
update_canmove()
return
/mob/proc/Resting(amount)
resting = max(max(resting,amount),0)
update_canmove()
return
/mob/proc/SetResting(amount)
resting = max(amount,0)
update_canmove()
return
/mob/proc/AdjustResting(amount)
resting = max(resting + amount,0)
update_canmove()
return
/mob/proc/get_species()
+3
View File
@@ -138,6 +138,8 @@
var/coughedtime = null
var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0
var/inertia_dir = 0
var/music_lastplayed = "null"
@@ -220,6 +222,7 @@
var/immune_to_ssd = 0
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
var/kills=0
+15 -16
View File
@@ -24,9 +24,7 @@
proc/new_player_panel_proc()
var/output = "<div align='center'><B>New Player Options</B>"
output +="<hr>"
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
var/output = "<center><p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
if(!ready) output += "<p><a href='byond://?src=\ref[src];ready=1'>Declare Ready</A></p>"
@@ -57,9 +55,9 @@
else
output += "<p><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A></p>"
output += "</div>"
output += "</center>"
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 210, 240)
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 220, 290)
popup.set_window_options("can_close=0")
popup.set_content(output)
popup.open(0)
@@ -105,6 +103,7 @@
if(href_list["ready"])
ready = !ready
new_player_panel_proc()
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
@@ -115,7 +114,7 @@
if(alert(src,"Are you sure you wish to observe? You will have to wait 30 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes")
if(!client) return 1
var/mob/dead/observer/observer = new()
src << browse(null, "window=playersetup")
spawning = 1
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
@@ -309,7 +308,7 @@
EquipRacialItems(character)
character = job_master.EquipRank(character, rank, 1) //equips the human
EquipCustomItems(character)
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
@@ -346,7 +345,7 @@
else
character.loc = pick(latejoin)
join_message = "has arrived on the station"
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair))
@@ -398,12 +397,12 @@
if(character.mind)
if((character.mind.special_role != "MODE"))
var/arrivalmessage = "A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"]."
announcer.say(";[arrivalmessage]")
announcer.say(";[arrivalmessage]")
else
if(character.mind)
if((character.mind.special_role != "MODE"))
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
proc/LateChoices()
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
@@ -444,9 +443,9 @@
proc/create_character()
spawning = 1
close_spawn_windows()
var/mob/living/carbon/human/new_character
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = all_species[client.prefs.species]
@@ -454,10 +453,10 @@
// Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
if(is_species_whitelisted(chosen_species) || has_admin_rights())
new_character = new(loc, client.prefs.species)
if(!new_character)
new_character = new(loc)
new_character.lastarea = get_area(loc)
var/datum/language/chosen_language
@@ -505,9 +504,9 @@
if(client.prefs.disabilities & DISABILITY_FLAG_DEAF)
new_character.dna.SetSEState(DEAFBLOCK,1,1)
new_character.sdisabilities |= DEAF
chosen_species.handle_dna(new_character)
domutcheck(new_character)
new_character.dna.UpdateSE()
@@ -602,7 +602,7 @@
taj_sideburns
name = "Tajara Sideburns"
icon_state = "facial_mutton"
icon_state = "facial_sideburns"
species_allowed = list("Tajaran")
taj_mutton
+27 -39
View File
@@ -80,7 +80,7 @@
invisibility = 101
return ..()
/mob/proc/AIize(move=1)
/mob/proc/AIize()
if(client)
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs
var/mob/living/silicon/ai/O = new (loc,,,1)//No MMI but safety is in effect.
@@ -93,52 +93,40 @@
else
O.key = key
if(move)
var/obj/loc_landmark
var/obj/loc_landmark
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name != "AI")
continue
if (locate(/mob/living) in sloc.loc)
continue
loc_landmark = sloc
if (!loc_landmark)
for(var/obj/effect/landmark/tripai in landmarks_list)
if (tripai.name == "tripai")
if(locate(/mob/living) in tripai.loc)
continue
loc_landmark = tripai
if (!loc_landmark)
O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone."
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name != "AI")
continue
if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc))
continue
loc_landmark = sloc
if (!loc_landmark)
for(var/obj/effect/landmark/tripai in landmarks_list)
if (tripai.name == "tripai")
if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc))
continue
loc_landmark = tripai
if (!loc_landmark)
O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone."
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name == "AI")
loc_landmark = sloc
if (sloc.name == "AI")
loc_landmark = sloc
O.loc = loc_landmark.loc
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O.loc = loc_landmark.loc
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
O << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
O << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
O << "To use something, simply click on it."
O << {"Use say ":b to speak to your cyborgs through binary."}
if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai)))
O.show_laws()
O << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
O.on_mob_init()
O.verbs += /mob/living/silicon/ai/proc/show_laws_verb
O.verbs += /mob/living/silicon/ai/proc/ai_statuschange
O.job = "AI"
O.add_ai_verbs()
O.rename_self("ai",1)
spawn(0)
del(src)
return O
. = O
qdel(src)
/mob/living/carbon/human/make_into_mask(var/should_gib = 0)
for(var/t in organs)
del(t)
qdel(t)
return ..(should_gib)
@@ -1,6 +1,7 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
// Added spess ghoasts/cameras to this so they don't add to the lag. - N3X
var/global/narsie_cometh = 0
var/global/list/uneatable = list(
/turf/space,
/obj/effect/overlay,
@@ -508,6 +509,7 @@ var/global/list/uneatable = list(
if(emergency_shuttle && emergency_shuttle.can_call())
emergency_shuttle.call_evac()
emergency_shuttle.launch_time = 0 // Cannot recall
narsie_cometh = 1
/obj/machinery/singularity/narsie/proc/spawn_animation()
@@ -541,7 +543,7 @@ var/global/list/uneatable = list(
if(istype(A,/obj/))
var/obj/O = A
O.ex_act(1.0)
if(O) del(O)
if(O) qdel(O)
else if(isturf(A))
var/turf/T = A
@@ -565,7 +567,7 @@ var/global/list/uneatable = list(
var/obj/O = A
machines -= O
processing_objects -= O
O.loc = null
qdel(O)
else if(isturf(A))
var/turf/T = A
if(istype(T,/turf/simulated/wall))
@@ -11,6 +11,7 @@
charge_cost = 2000
modifystate = "advtaserstun"
can_flashlight = 1
fire_delay = 20
var/mode = 0 //0 = stun, 1 = disable
@@ -24,6 +25,7 @@
user << "\red [src.name] is now set to Disable."
projectile_type = "/obj/item/projectile/beam/disabler"
modifystate = "advtaserdisable"
fire_delay = 0
if(1)
mode = 0
charge_cost = 2000
@@ -31,6 +33,7 @@
user << "\red [src.name] is now set to stun."
projectile_type = "/obj/item/projectile/energy/electrode"
modifystate = "advtaserstun"
fire_delay = 20
update_icon()
if(user.l_hand == src)
user.update_inv_l_hand()
@@ -0,0 +1,45 @@
/obj/item/weapon/gun/energy/hos
name = "HoS Energy Gun"
desc = "This is a modern recreation of the antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time, its also expensive."
icon_state = "hoslaser"
item_state = null //so the human update icon uses the icon_state instead.
icon_override = 'icons/mob/in-hand/guns.dmi'
force = 10
fire_sound = 'sound/weapons/Taser.ogg'
origin_tech = "combat=3;magnets=2"
charge_cost = 2000
modifystate = "hoslaserstun"
projectile_type = "/obj/item/projectile/energy/electrode"
var/mode = 2
attack_self(mob/living/user as mob)
switch(mode)
if(2)
mode = 0
charge_cost = 1000
fire_sound = 'sound/weapons/Laser.ogg'
user << "\red [src.name] is now set to kill."
projectile_type = "/obj/item/projectile/beam"
modifystate = "hoslaserkill"
fire_delay = 0
if(0)
mode = 1
charge_cost = 500
fire_sound = 'sound/weapons/taser2.ogg'
user << "\red [src.name] is now set to disable."
projectile_type = "/obj/item/projectile/beam/disabler"
modifystate = "hoslaserdisable"
fire_delay = 0
if(1)
mode = 2
charge_cost = 2000
fire_sound = 'sound/weapons/taser.ogg'
user << "\red [src.name] is now set to stun."
projectile_type = "/obj/item/projectile/energy/electrode"
modifystate = "hoslaserstun"
fire_delay = 20
update_icon()
if(user.l_hand == src)
user.update_inv_l_hand()
else
user.update_inv_r_hand()

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