mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-22 16:12:19 +00:00
Merge remote-tracking branch 'Aurorastation/development' into SQL-backend-import
# Conflicts: # code/modules/admin/admin.dm # code/modules/admin/admin_verbs.dm All conflicts cleared. Wind funciton needs a quick redo as a result.
This commit is contained in:
@@ -3,8 +3,8 @@ language: c
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
BYOND_MAJOR="508"
|
||||
BYOND_MINOR="1293"
|
||||
BYOND_MAJOR="509"
|
||||
BYOND_MINOR="1318"
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "code\__HELPERS\lists.dm"
|
||||
#include "code\__HELPERS\logging.dm"
|
||||
#include "code\__HELPERS\maths.dm"
|
||||
#include "code\__HELPERS\matrices.dm"
|
||||
#include "code\__HELPERS\mobs.dm"
|
||||
#include "code\__HELPERS\names.dm"
|
||||
#include "code\__HELPERS\sanitize_values.dm"
|
||||
@@ -44,6 +45,7 @@
|
||||
#include "code\_onclick\other_mobs.dm"
|
||||
#include "code\_onclick\telekinesis.dm"
|
||||
#include "code\_onclick\hud\_defines.dm"
|
||||
#include "code\_onclick\hud\ai.dm"
|
||||
#include "code\_onclick\hud\alien_larva.dm"
|
||||
#include "code\_onclick\hud\hud.dm"
|
||||
#include "code\_onclick\hud\human.dm"
|
||||
@@ -203,7 +205,6 @@
|
||||
#include "code\defines\procs\records.dm"
|
||||
#include "code\defines\procs\sd_Alert.dm"
|
||||
#include "code\defines\procs\statistics.dm"
|
||||
#include "code\game\asteroid.dm"
|
||||
#include "code\game\atoms.dm"
|
||||
#include "code\game\atoms_movable.dm"
|
||||
#include "code\game\periodic_news.dm"
|
||||
@@ -313,7 +314,6 @@
|
||||
#include "code\game\gamemodes\wizard\wizard.dm"
|
||||
#include "code\game\jobs\access.dm"
|
||||
#include "code\game\jobs\job_controller.dm"
|
||||
#include "code\game\jobs\jobprocs.dm"
|
||||
#include "code\game\jobs\jobs.dm"
|
||||
#include "code\game\jobs\whitelist.dm"
|
||||
#include "code\game\jobs\job\assistant.dm"
|
||||
@@ -575,6 +575,7 @@
|
||||
#include "code\game\objects\items\devices\flashlight.dm"
|
||||
#include "code\game\objects\items\devices\floor_painter.dm"
|
||||
#include "code\game\objects\items\devices\lightreplacer.dm"
|
||||
#include "code\game\objects\items\devices\magnetic_lock.dm"
|
||||
#include "code\game\objects\items\devices\megaphone.dm"
|
||||
#include "code\game\objects\items\devices\modkit.dm"
|
||||
#include "code\game\objects\items\devices\multitool.dm"
|
||||
@@ -657,6 +658,7 @@
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\air_management.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\camera_monitor.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\computer.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\holodeckcontrol.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\research.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\supply.dm"
|
||||
#include "code\game\objects\items\weapons\circuitboards\computer\telecomms.dm"
|
||||
@@ -836,7 +838,6 @@
|
||||
#include "code\modules\admin\verbs\diagnostics.dm"
|
||||
#include "code\modules\admin\verbs\dice.dm"
|
||||
#include "code\modules\admin\verbs\getlogs.dm"
|
||||
#include "code\modules\admin\verbs\icarus.dm"
|
||||
#include "code\modules\admin\verbs\mapping.dm"
|
||||
#include "code\modules\admin\verbs\massmodvar.dm"
|
||||
#include "code\modules\admin\verbs\modifyvariables.dm"
|
||||
@@ -881,6 +882,7 @@
|
||||
#include "code\modules\client\client defines.dm"
|
||||
#include "code\modules\client\client procs.dm"
|
||||
#include "code\modules\client\preferences.dm"
|
||||
#include "code\modules\client\preferences_ambience.dm"
|
||||
#include "code\modules\client\preferences_factions.dm"
|
||||
#include "code\modules\client\preferences_gear.dm"
|
||||
#include "code\modules\client\preferences_savefile.dm"
|
||||
@@ -1249,6 +1251,7 @@
|
||||
#include "code\modules\mob\living\silicon\ai\life.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\login.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\logout.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\nano.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\death.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\life.dm"
|
||||
@@ -1340,6 +1343,7 @@
|
||||
#include "code\modules\nano\nanoui.dm"
|
||||
#include "code\modules\nano\interaction\admin.dm"
|
||||
#include "code\modules\nano\interaction\base.dm"
|
||||
#include "code\modules\nano\interaction\conscious.dm"
|
||||
#include "code\modules\nano\interaction\contained.dm"
|
||||
#include "code\modules\nano\interaction\default.dm"
|
||||
#include "code\modules\nano\interaction\inventory.dm"
|
||||
@@ -1427,6 +1431,9 @@
|
||||
#include "code\modules\power\singularity\particle_accelerator\particle_control.dm"
|
||||
#include "code\modules\power\singularity\particle_accelerator\particle_emitter.dm"
|
||||
#include "code\modules\power\singularity\particle_accelerator\particle_power.dm"
|
||||
#include "code\modules\power\tesla\coil.dm"
|
||||
#include "code\modules\power\tesla\energy_ball.dm"
|
||||
#include "code\modules\power\tesla\generator.dm"
|
||||
#include "code\modules\projectiles\ammunition.dm"
|
||||
#include "code\modules\projectiles\effects.dm"
|
||||
#include "code\modules\projectiles\gun.dm"
|
||||
@@ -1439,6 +1446,7 @@
|
||||
#include "code\modules\projectiles\guns\launcher.dm"
|
||||
#include "code\modules\projectiles\guns\projectile.dm"
|
||||
#include "code\modules\projectiles\guns\energy\laser.dm"
|
||||
#include "code\modules\projectiles\guns\energy\lawgiver.dm"
|
||||
#include "code\modules\projectiles\guns\energy\nuclear.dm"
|
||||
#include "code\modules\projectiles\guns\energy\pulse.dm"
|
||||
#include "code\modules\projectiles\guns\energy\special.dm"
|
||||
@@ -1644,6 +1652,7 @@
|
||||
#include "code\modules\spells\targeted\targeted.dm"
|
||||
#include "code\modules\spells\targeted\equip\equip.dm"
|
||||
#include "code\modules\spells\targeted\equip\horsemask.dm"
|
||||
#include "code\modules\spells\targeted\equip\remove_horsemask.dm"
|
||||
#include "code\modules\spells\targeted\projectile\dumbfire.dm"
|
||||
#include "code\modules\spells\targeted\projectile\fireball.dm"
|
||||
#include "code\modules\spells\targeted\projectile\magic_missile.dm"
|
||||
|
||||
@@ -35,10 +35,9 @@ except ImportError:
|
||||
try:
|
||||
tiedosto = open("psycodownload.txt","r")
|
||||
except:
|
||||
tiedosto = open("psycodownload.txt","w")
|
||||
with open("psycodownload.txt","w") as tiedosto:
|
||||
tiedosto.write("http://www.voidspace.org.uk/python/modules.shtml#psyco")
|
||||
tiedosto.write("\nhttp://psyco.sourceforge.net/download.html")
|
||||
tiedosto.close()
|
||||
print "Check psycodownload.txt for a link"
|
||||
else:
|
||||
print "For god's sake, open psycodownload.txt"
|
||||
@@ -190,15 +189,13 @@ tell_list = {}
|
||||
if CORE_DATA.DISABLE_ALL_NON_MANDATORY_SOCKET_CONNECTIONS:
|
||||
nudgeable = False
|
||||
try:
|
||||
tiedosto = open("replacenames.cache","r")
|
||||
with open("replacenames.cache","r") as tiedosto:
|
||||
replacenames = pickle.load(tiedosto)
|
||||
tiedosto.close()
|
||||
for i in replacenames.values():
|
||||
if len(i) > call_me_max_length:
|
||||
replacenames[replacenames.keys()[replacenames.values().index(i)]] = i[:call_me_max_length]
|
||||
tiedosto = open("replacenames.cache","w")
|
||||
with open("replacenames.cache","w") as tiedosto:
|
||||
pickle.dump(replacenames,tiedosto)
|
||||
tiedosto.close()
|
||||
if "[\0x01]" in i.lower() or "[\\0x01]" in i.lower():
|
||||
i = i.replace("[\0x01]","")
|
||||
i = i.replace("[\0X01]","")
|
||||
@@ -211,13 +208,12 @@ except EOFError: #Cache corrupt
|
||||
replacenames = {}
|
||||
print "replacenames.cache is corrupt and couldn't be loaded."
|
||||
try:
|
||||
tiedosto = open("peopleheknows.cache","r")
|
||||
with open("peopleheknows.cache","r") as tiedosto:
|
||||
peopleheknows = pickle.load(tiedosto)
|
||||
tiedosto.close()
|
||||
except IOError:
|
||||
peopleheknows = [[],[]]
|
||||
tiedosto = open("peopleheknows.cache","w")
|
||||
tiedosto.close()
|
||||
with open("peopleheknows.cache","w") as tiedosto:
|
||||
pass
|
||||
except EOFError:
|
||||
peopleheknows = [[],[]]
|
||||
print "peopleheknows.cache is corrupt and couldn't be loaded."
|
||||
@@ -345,13 +341,11 @@ if aggressive_pinging:
|
||||
self_time = 0
|
||||
global backup,disconnects,conn
|
||||
while disconnects < 5:
|
||||
if backup > self_time:
|
||||
if time.time()-backup > delay:
|
||||
if backup > self_time and time.time()-backup > delay:
|
||||
conn.send("PONG "+pongtarg)
|
||||
print "Ponged"
|
||||
self_time = time.time()
|
||||
else:
|
||||
if time.time()-self_time > delay:
|
||||
elif time.time()-self_time > delay:
|
||||
conn.send("PONG "+pongtarg)
|
||||
print "Ponged"
|
||||
self_time = time.time()
|
||||
@@ -370,8 +364,7 @@ def stop(sender,debug=1):
|
||||
access_granted = True
|
||||
else:
|
||||
access_granted = False
|
||||
if access_granted:
|
||||
if debug:
|
||||
if access_granted and debug:
|
||||
print sender+":"+prefix+"stop"
|
||||
if random.randint(0,100) == 50:
|
||||
conn.privmsg(channel,"Hammertime!")
|
||||
@@ -401,13 +394,12 @@ def target(who,how_long):
|
||||
if debug:
|
||||
print "Banned",who,"For",how_long,"seconds"
|
||||
if logbans:
|
||||
tiedosto = open(targetdirectory+"banlog/"+str(int(start))+"-"+str(int(end))+".txt","w")
|
||||
with open(targetdirectory+"banlog/"+str(int(start))+"-"+str(int(end))+".txt","w") as tiedosto:
|
||||
tiedosto.write("Start of ban on "+who+":"+str(int(start)))
|
||||
tiedosto.write("\n")
|
||||
tiedosto.write("End of ban on "+who+":"+str(int(end)))
|
||||
tiedosto.write("\n")
|
||||
tiedosto.write("In total:"+str(int(end-start))+"Seconds")
|
||||
tiedosto.close()
|
||||
else:
|
||||
CALL_OFF = False
|
||||
pass
|
||||
@@ -576,8 +568,7 @@ while True:
|
||||
time.sleep(6)
|
||||
Name = origname
|
||||
conn.nick(Name)
|
||||
if origname in truesender:
|
||||
if influx == prefix+"stop":
|
||||
if origname in truesender and influx == prefix+"stop":
|
||||
time.sleep(0.5) #A small delay
|
||||
conn.privmsg(channel,"Shutting down.")
|
||||
conn.quit()
|
||||
@@ -633,9 +624,8 @@ while True:
|
||||
arg = influx.lower()[8+len(prefix):]
|
||||
if debug:
|
||||
print truesender+":"+prefix+"suggest "+arg
|
||||
tiedosto = open(targetdirectory+"suggestions/suggestions_"+str(int(time.time()))+".txt","a")
|
||||
with open(targetdirectory+"suggestions/suggestions_"+str(int(time.time()))+".txt","a") as tiedosto:
|
||||
tiedosto.write(arg)
|
||||
tiedosto.close()
|
||||
conn.privmsg(targetchannel,"Suggestion received")
|
||||
elif cocheck( prefix+"help "): #Space in front of the ( to make sure that my command finder does not pick this up.
|
||||
arg = " ".join(influx.split(" ")[1:]).lower()
|
||||
|
||||
@@ -28,9 +28,6 @@ datum/pipeline
|
||||
if(!member.check_pressure(pressure))
|
||||
break //Only delete 1 pipe per process
|
||||
|
||||
//Allow for reactions
|
||||
//air.react() //Should be handled by pipe_network now
|
||||
|
||||
proc/temporarily_store_air()
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
|
||||
/datum/controller/air_system/proc/remove_zone(zone/z)
|
||||
zones.Remove(z)
|
||||
zones_to_update.Remove(z)
|
||||
|
||||
/datum/controller/air_system/proc/air_blocked(turf/A, turf/B)
|
||||
#ifdef ZASDBG
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
/*
|
||||
|
||||
Making Bombs with ZAS:
|
||||
Make burny fire with lots of burning
|
||||
Draw off 5000K gas from burny fire
|
||||
Separate gas into oxygen and phoron components
|
||||
Obtain phoron and oxygen tanks filled up about 50-75% with normal-temp gas
|
||||
Fill rest with super hot gas from separated canisters, they should be about 125C now.
|
||||
Attach to transfer valve and open. BOOM.
|
||||
|
||||
Get gas to react in an air tank so that it gains pressure. If it gains enough pressure, it goes boom.
|
||||
The more pressure, the more boom.
|
||||
If it gains pressure too slowly, it may leak or just rupture instead of exploding.
|
||||
*/
|
||||
|
||||
//#define FIREDBG
|
||||
@@ -268,16 +264,16 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
//determine how far the reaction can progress
|
||||
var/reaction_limit = min(total_oxidizers*(FIRE_REACTION_FUEL_AMOUNT/FIRE_REACTION_OXIDIZER_AMOUNT), total_fuel) //stoichiometric limit
|
||||
|
||||
//calculate the firelevel.
|
||||
var/firelevel = calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
|
||||
var/firelevel_ratio = firelevel / vsc.fire_firelevel_multiplier
|
||||
|
||||
//vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn).)
|
||||
var/gas_firelevel = calculate_firelevel(gas_fuel, total_oxidizers, reaction_limit, volume*group_multiplier) / vsc.fire_firelevel_multiplier
|
||||
var/min_burn = 0.30*volume*group_multiplier/CELL_VOLUME //in moles - so that fires with very small gas concentrations burn out fast
|
||||
var/gas_reaction_progress = min(max(min_burn, firelevel_ratio*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
|
||||
var/gas_reaction_progress = min(max(min_burn, gas_firelevel*gas_fuel)*FIRE_GAS_BURNRATE_MULT, gas_fuel)
|
||||
|
||||
//liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning. Limit the burn rate to a certain amount per area.
|
||||
var/liquid_reaction_progress = min((firelevel_ratio*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
|
||||
var/liquid_firelevel = calculate_firelevel(liquid_fuel, total_oxidizers, reaction_limit, 0) / vsc.fire_firelevel_multiplier
|
||||
var/liquid_reaction_progress = min((liquid_firelevel*0.2 + 0.05)*fuel_area*FIRE_LIQUID_BURNRATE_MULT, liquid_fuel)
|
||||
|
||||
var/firelevel = (gas_fuel*gas_firelevel + liquid_fuel*liquid_firelevel)/total_fuel
|
||||
|
||||
var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress
|
||||
var/used_fuel = min(total_reaction_progress, reaction_limit)
|
||||
@@ -286,7 +282,7 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
#ifdef FIREDBG
|
||||
log_debug("gas_fuel = [gas_fuel], liquid_fuel = [liquid_fuel], total_oxidizers = [total_oxidizers]")
|
||||
log_debug("fuel_area = [fuel_area], total_fuel = [total_fuel], reaction_limit = [reaction_limit]")
|
||||
log_debug("firelevel -> [firelevel] / [vsc.fire_firelevel_multiplier]")
|
||||
log_debug("firelevel -> [firelevel] (gas: [gas_firelevel], liquid: [liquid_firelevel])")
|
||||
log_debug("liquid_reaction_progress = [liquid_reaction_progress]")
|
||||
log_debug("gas_reaction_progress = [gas_reaction_progress]")
|
||||
log_debug("total_reaction_progress = [total_reaction_progress]")
|
||||
@@ -315,13 +311,13 @@ turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
//calculate the energy produced by the reaction and then set the new temperature of the mix
|
||||
temperature = (starting_energy + vsc.fire_fuel_energy_release * (used_gas_fuel + used_liquid_fuel)) / heat_capacity()
|
||||
update_values()
|
||||
|
||||
#ifdef FIREDBG
|
||||
log_debug("used_gas_fuel = [used_gas_fuel]; used_liquid_fuel = [used_liquid_fuel]; total = [used_fuel]")
|
||||
log_debug("new temperature = [temperature]")
|
||||
log_debug("new temperature = [temperature]; new pressure = [return_pressure()]")
|
||||
#endif
|
||||
|
||||
update_values()
|
||||
return firelevel
|
||||
|
||||
datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
@@ -363,27 +359,31 @@ datum/gas_mixture/proc/check_recombustability(list/fuel_objs)
|
||||
break
|
||||
|
||||
//returns a value between 0 and vsc.fire_firelevel_multiplier
|
||||
/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit)
|
||||
/datum/gas_mixture/proc/calculate_firelevel(total_fuel, total_oxidizers, reaction_limit, gas_volume)
|
||||
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
|
||||
var/firelevel = 0
|
||||
|
||||
var/total_combustables = (total_fuel + total_oxidizers)
|
||||
var/active_combustables = (FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT + 1)*reaction_limit
|
||||
|
||||
if(total_combustables > 0)
|
||||
//slows down the burning when the concentration of the reactants is low
|
||||
var/dampening_multiplier = min(1, reaction_limit / (total_moles/group_multiplier))
|
||||
var/damping_multiplier = min(1, active_combustables / (total_moles/group_multiplier))
|
||||
|
||||
//weight the damping mult so that it only really brings down the firelevel when the ratio is closer to 0
|
||||
damping_multiplier = 2*damping_multiplier - (damping_multiplier*damping_multiplier)
|
||||
|
||||
//calculates how close the mixture of the reactants is to the optimum
|
||||
//fires burn better when there is more oxidizer -- too much fuel will choke them out a bit, reducing firelevel.
|
||||
//fires burn better when there is more oxidizer -- too much fuel will choke the fire out a bit, reducing firelevel.
|
||||
var/mix_multiplier = 1 / (1 + (5 * ((total_fuel / total_combustables) ** 2)))
|
||||
|
||||
#ifdef FIREDBG
|
||||
ASSERT(dampening_multiplier <= 1)
|
||||
ASSERT(damping_multiplier <= 1)
|
||||
ASSERT(mix_multiplier <= 1)
|
||||
#endif
|
||||
|
||||
//toss everything together -- should produce a value between 0 and fire_firelevel_multiplier
|
||||
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
|
||||
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * damping_multiplier
|
||||
|
||||
return max( 0, firelevel)
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
/xgm_gas/phoron
|
||||
id = "phoron"
|
||||
name = "Phoron"
|
||||
|
||||
//Note that this has a significant impact on TTV yield.
|
||||
//Because it is so high, any leftover phoron soaks up a lot of heat and drops the yield pressure.
|
||||
specific_heat = 200 // J/(mol*K)
|
||||
|
||||
//Hypothetical group 14 (same as carbon), period 8 element.
|
||||
|
||||
@@ -9,7 +9,8 @@ var/global/vs_control/vsc = new
|
||||
var/fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
|
||||
var/fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
|
||||
|
||||
var/fire_fuel_energy_release = 397000
|
||||
//Note that this parameter and the phoron heat capacity have a significant impact on TTV yield.
|
||||
var/fire_fuel_energy_release = 866000 //J/mol. Adjusted to compensate for fire energy release being fixed, was 397000
|
||||
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
|
||||
var/fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
|
||||
|
||||
|
||||
@@ -108,11 +108,12 @@ Class Procs:
|
||||
c_invalidate()
|
||||
for(var/turf/simulated/T in contents)
|
||||
into.add(T)
|
||||
T.update_graphic(graphic_remove = air.graphic)
|
||||
#ifdef ZASDBG
|
||||
T.dbg(merged)
|
||||
#endif
|
||||
|
||||
//rebuild the old zone's edges so that the will be possesed by the new zone
|
||||
//rebuild the old zone's edges so that they will be possessed by the new zone
|
||||
for(var/connection_edge/E in edges)
|
||||
if(E.contains_zone(into))
|
||||
continue //don't need to rebuild this edge
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
return 1
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/react(atom/dump_location)
|
||||
/datum/gas_mixture/proc/react()
|
||||
zburn(null, force_burn=0, no_check=0) //could probably just call zburn() here with no args but I like being explicit.
|
||||
|
||||
|
||||
@@ -444,20 +444,25 @@
|
||||
total_gas[g] += gasmix.gas[g]
|
||||
|
||||
if(total_volume > 0)
|
||||
//Average out the gases
|
||||
for(var/g in total_gas)
|
||||
total_gas[g] /= total_volume
|
||||
var/datum/gas_mixture/combined = new(total_volume)
|
||||
combined.gas = total_gas
|
||||
|
||||
//Calculate temperature
|
||||
var/temperature = 0
|
||||
|
||||
if(total_heat_capacity > 0)
|
||||
temperature = total_thermal_energy / total_heat_capacity
|
||||
combined.temperature = total_thermal_energy / total_heat_capacity
|
||||
combined.update_values()
|
||||
|
||||
//Allow for reactions
|
||||
combined.react()
|
||||
|
||||
//Average out the gases
|
||||
for(var/g in combined.gas)
|
||||
combined.gas[g] /= total_volume
|
||||
|
||||
//Update individual gas_mixtures
|
||||
for(var/datum/gas_mixture/gasmix in gases)
|
||||
gasmix.gas = total_gas.Copy()
|
||||
gasmix.temperature = temperature
|
||||
gasmix.gas = combined.gas.Copy()
|
||||
gasmix.temperature = combined.temperature
|
||||
gasmix.multiply(gasmix.volume)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -71,11 +71,17 @@ proc/isemptylist(list/list)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
|
||||
proc/clearlist(list/list)
|
||||
if(istype(list))
|
||||
list.len = 0
|
||||
return
|
||||
/proc/instances_of_type_in_list(var/atom/A, var/list/L)
|
||||
var/instances = 0
|
||||
for(var/type in L)
|
||||
if(istype(A, type))
|
||||
instances++
|
||||
return instances
|
||||
|
||||
//Empties the list by .Cut(). Setting lenght = 0 has been confirmed to leak references.
|
||||
proc/clearlist(var/list/L)
|
||||
if(islist(L))
|
||||
L.Cut()
|
||||
|
||||
//Removes any null entries from the list
|
||||
proc/listclearnulls(list/list)
|
||||
|
||||
26
code/__HELPERS/matrices.dm
Normal file
26
code/__HELPERS/matrices.dm
Normal file
@@ -0,0 +1,26 @@
|
||||
/matrix/proc/TurnTo(old_angle, new_angle)
|
||||
. = new_angle - old_angle
|
||||
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
|
||||
|
||||
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3)
|
||||
if(!segments)
|
||||
return
|
||||
var/segment = 360/segments
|
||||
if(!clockwise)
|
||||
segment = -segment
|
||||
var/list/matrices = list()
|
||||
for(var/i in 1 to segments-1)
|
||||
var/matrix/M = matrix(transform)
|
||||
M.Turn(segment*i)
|
||||
matrices += M
|
||||
var/matrix/last = matrix(transform)
|
||||
matrices += last
|
||||
|
||||
speed /= segments
|
||||
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
for(var/i in 2 to segments) //2 because 1 is covered above
|
||||
animate(transform = matrices[i], time = speed)
|
||||
//doesn't have an object argument because this is "Stacking" with the animate call above
|
||||
//3 billion% intentional
|
||||
@@ -138,6 +138,14 @@
|
||||
/proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#"))
|
||||
return html_encode(replace_characters(t,repl_chars))
|
||||
|
||||
// Truncates text to limit if necessary.
|
||||
/proc/dd_limittext(message, length)
|
||||
var/size = length(message)
|
||||
if (size <= length)
|
||||
return message
|
||||
else
|
||||
return copytext(message, 1, length + 1)
|
||||
|
||||
/*
|
||||
* Text searches
|
||||
*/
|
||||
|
||||
@@ -17,3 +17,18 @@
|
||||
if(A.simulated)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// Picks a turf without a mob from the given list of turfs, if one exists.
|
||||
// If no such turf exists, picks any random turf from the given list of turfs.
|
||||
/proc/pick_mobless_turf_if_exists(var/list/start_turfs)
|
||||
if(!start_turfs.len)
|
||||
return null
|
||||
|
||||
var/list/available_turfs = list()
|
||||
for(var/start_turf in start_turfs)
|
||||
var/mob/M = locate() in start_turf
|
||||
if(!M)
|
||||
available_turfs += start_turf
|
||||
if(!available_turfs.len)
|
||||
available_turfs = start_turfs
|
||||
return pick(available_turfs)
|
||||
|
||||
@@ -1309,3 +1309,64 @@ var/mob/dview/dview_mob = new
|
||||
/mob/dview/New()
|
||||
// do nothing. we don't want to be in any mob lists; we're a dummy not a mob.
|
||||
|
||||
//This is just so you can stop an orbit.
|
||||
//orbit() can run without it (swap orbiting for A)
|
||||
//but then you can never stop it and that's just silly.
|
||||
/atom/movable/var/atom/orbiting = null
|
||||
|
||||
//A: atom to orbit
|
||||
//radius: range to orbit at, radius of the circle formed by orbiting
|
||||
//clockwise: whether you orbit clockwise or anti clockwise
|
||||
//rotation_speed: how fast to rotate
|
||||
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
|
||||
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
|
||||
//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts)
|
||||
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE)
|
||||
if(!istype(A))
|
||||
return
|
||||
|
||||
if(orbiting)
|
||||
stop_orbit()
|
||||
|
||||
orbiting = A
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
var/lastloc = loc
|
||||
|
||||
//Head first!
|
||||
if(pre_rotation)
|
||||
var/matrix/M = matrix(transform)
|
||||
var/pre_rot = 90
|
||||
if(!clockwise)
|
||||
pre_rot = -90
|
||||
M.Turn(pre_rot)
|
||||
transform = M
|
||||
|
||||
var/matrix/shift = matrix(transform)
|
||||
shift.Translate(0,radius)
|
||||
transform = shift
|
||||
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
transform = initial_transform
|
||||
while(orbiting && orbiting == A && A.loc)
|
||||
var/targetloc = get_turf(A)
|
||||
if(!lockinorbit && loc != lastloc && loc != targetloc)
|
||||
break
|
||||
loc = targetloc
|
||||
lastloc = loc
|
||||
sleep(0.6)
|
||||
|
||||
if (orbiting == A) //make sure we haven't started orbiting something else.
|
||||
orbiting = null
|
||||
SpinAnimation(0,0)
|
||||
|
||||
|
||||
|
||||
/atom/movable/proc/stop_orbit()
|
||||
orbiting = null
|
||||
|
||||
// call to generate a stack trace and print to runtime logs
|
||||
/proc/crash_with(msg)
|
||||
CRASH(msg)
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
user.listed_turf = null
|
||||
else
|
||||
user.listed_turf = T
|
||||
user.client.statpanel = T.name
|
||||
user.client.statpanel = "Turf"
|
||||
return
|
||||
|
||||
/mob/proc/TurfAdjacent(var/turf/T)
|
||||
|
||||
@@ -127,3 +127,22 @@
|
||||
|
||||
#define ui_spell_master "14:16,14:16"
|
||||
#define ui_genetic_master "14:16,12:16"
|
||||
|
||||
// AI
|
||||
|
||||
#define ui_ai_camera_list "SOUTH:6+1,WEST+1:16"
|
||||
#define ui_ai_track_with_camera "SOUTH:6+1,WEST+2:16"
|
||||
#define ui_ai_camera_light "SOUTH:6+1,WEST+3:16"
|
||||
#define ui_ai_sensor "SOUTH:6+1,WEST+4:16"
|
||||
|
||||
#define ui_ai_core "SOUTH:6,WEST+1:16"
|
||||
#define ui_ai_crew_monitor "SOUTH:6,WEST+2:16"
|
||||
#define ui_ai_crew_manifest "SOUTH:6,WEST+3:16"
|
||||
#define ui_ai_alerts "SOUTH:6,WEST+4:16"
|
||||
#define ui_ai_announcement "SOUTH:6,WEST+5:16"
|
||||
#define ui_ai_shuttle "SOUTH:6,WEST+6:16"
|
||||
#define ui_ai_state_laws "SOUTH:6,WEST+7:16"
|
||||
#define ui_ai_pda_send "SOUTH:6,WEST+8:16"
|
||||
#define ui_ai_pda_log "SOUTH:6,WEST+9:16"
|
||||
#define ui_ai_take_picture "SOUTH:6,WEST+10:16"
|
||||
#define ui_ai_view_images "SOUTH:6,WEST+11:16"
|
||||
|
||||
143
code/_onclick/hud/ai.dm
Normal file
143
code/_onclick/hud/ai.dm
Normal file
@@ -0,0 +1,143 @@
|
||||
/datum/hud/proc/ai_hud()
|
||||
adding = list()
|
||||
other = list()
|
||||
|
||||
var/obj/screen/using
|
||||
|
||||
//AI core
|
||||
using = new /obj/screen()
|
||||
using.name = "AI Core"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "ai_core"
|
||||
using.screen_loc = ui_ai_core
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Camera list
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Camera List"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "camera"
|
||||
using.screen_loc = ui_ai_camera_list
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Track
|
||||
using = new /obj/screen()
|
||||
using.name = "Track With Camera"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "track"
|
||||
using.screen_loc = ui_ai_track_with_camera
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Camera light
|
||||
using = new /obj/screen()
|
||||
using.name = "Toggle Camera Light"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "camera_light"
|
||||
using.screen_loc = ui_ai_camera_light
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Crew Monitorting
|
||||
using = new /obj/screen()
|
||||
using.name = "Crew Monitoring"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "crew_monitor"
|
||||
using.screen_loc = ui_ai_crew_monitor
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Crew Manifest
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Crew Manifest"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "manifest"
|
||||
using.screen_loc = ui_ai_crew_manifest
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Alerts
|
||||
using = new /obj/screen()
|
||||
using.name = "Show Alerts"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "alerts"
|
||||
using.screen_loc = ui_ai_alerts
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Announcement
|
||||
using = new /obj/screen()
|
||||
using.name = "Announcement"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "announcement"
|
||||
using.screen_loc = ui_ai_announcement
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Shuttle
|
||||
using = new /obj/screen()
|
||||
using.name = "Call Emergency Shuttle"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "call_shuttle"
|
||||
using.screen_loc = ui_ai_shuttle
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Laws
|
||||
using = new /obj/screen()
|
||||
using.name = "State Laws"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "state_laws"
|
||||
using.screen_loc = ui_ai_state_laws
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//PDA message
|
||||
using = new /obj/screen()
|
||||
using.name = "PDA - Send Message"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "pda_send"
|
||||
using.screen_loc = ui_ai_pda_send
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//PDA log
|
||||
using = new /obj/screen()
|
||||
using.name = "PDA - Show Message Log"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "pda_receive"
|
||||
using.screen_loc = ui_ai_pda_log
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Take image
|
||||
using = new /obj/screen()
|
||||
using.name = "Take Image"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "take_picture"
|
||||
using.screen_loc = ui_ai_take_picture
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//View images
|
||||
using = new /obj/screen()
|
||||
using.name = "View Images"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "view_images"
|
||||
using.screen_loc = ui_ai_view_images
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
//Medical/Security sensors
|
||||
using = new /obj/screen()
|
||||
using.name = "Set Sensor Augmentation"
|
||||
using.icon = 'icons/mob/screen_ai.dmi'
|
||||
using.icon_state = "ai_sensor"
|
||||
using.screen_loc = ui_ai_sensor
|
||||
using.layer = 20
|
||||
adding += using
|
||||
|
||||
mymob.client.screen += adding + other
|
||||
return
|
||||
@@ -13,9 +13,6 @@
|
||||
mymob.blind.screen_loc = "1,1"
|
||||
mymob.blind.layer = 0
|
||||
|
||||
/datum/hud/proc/ai_hud()
|
||||
return
|
||||
|
||||
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
|
||||
|
||||
blobpwrdisplay = new /obj/screen()
|
||||
|
||||
@@ -478,6 +478,83 @@
|
||||
usr.client.AllowTargetRadio()
|
||||
gun_click_time = world.time
|
||||
|
||||
if("AI Core")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.view_core()
|
||||
|
||||
if("Show Camera List")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/camera = input(AI) in AI.get_camera_list()
|
||||
AI.ai_camera_list(camera)
|
||||
|
||||
if("Track With Camera")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/target_name = input(AI) in AI.trackable_mobs()
|
||||
AI.ai_camera_track(target_name)
|
||||
|
||||
if("Toggle Camera Light")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.toggle_camera_light()
|
||||
|
||||
if("Crew Monitoring")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_crew_monitor()
|
||||
|
||||
if("Show Crew Manifest")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.show_station_manifest()
|
||||
|
||||
if("Show Alerts")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_alarm_monitor()
|
||||
|
||||
if("Announcement")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_announcement()
|
||||
|
||||
if("Call Emergency Shuttle")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_call_shuttle()
|
||||
|
||||
if("State Laws")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_law_manager()
|
||||
|
||||
if("PDA - Send Message")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiPDA.cmd_send_pdamesg(usr)
|
||||
|
||||
if("PDA - Show Message Log")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiPDA.cmd_show_message_log(usr)
|
||||
|
||||
if("Take Image")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiCamera.toggle_camera_mode()
|
||||
|
||||
if("View Images")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.aiCamera.viewpictures()
|
||||
|
||||
if("Set Sensor Augmentation")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.sensor_mode()
|
||||
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
spell_objects.Cut()
|
||||
if(spell_holder)
|
||||
spell_holder.spell_masters -= src
|
||||
if(spell_holder.client && spell_holder.client.screen)
|
||||
spell_holder.client.screen -= src
|
||||
spell_holder = null
|
||||
|
||||
/obj/screen/movable/spell_master/ResetVars()
|
||||
..("spell_objects")
|
||||
..("spell_objects", args)
|
||||
spell_objects = list()
|
||||
|
||||
/obj/screen/movable/spell_master/MouseDrop()
|
||||
|
||||
@@ -91,6 +91,7 @@ var/list/delayed_garbage = list()
|
||||
return
|
||||
if(!istype(A))
|
||||
warning("qdel() passed object of type [A.type]. qdel() can only handle /datum types.")
|
||||
crash_with("qdel() passed object of type [A.type]. qdel() can only handle /datum types.")
|
||||
del(A)
|
||||
if(garbage_collector)
|
||||
garbage_collector.dels++
|
||||
|
||||
@@ -39,12 +39,12 @@ datum/controller/vote
|
||||
result()
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(null,"window=vote;can_close=0")
|
||||
C << browse(null,"window=vote")
|
||||
reset()
|
||||
else
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(vote.interface(C),"window=vote;can_close=0")
|
||||
C << browse(vote.interface(C),"window=vote")
|
||||
|
||||
voting.Cut()
|
||||
|
||||
@@ -258,6 +258,9 @@ datum/controller/vote
|
||||
|
||||
log_vote(text)
|
||||
world << "<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
|
||||
for(var/client/C in clients)
|
||||
if(C.prefs.asfx_togs & ASFX_VOTE) //Personal mute
|
||||
C << sound('sound/effects/vote.ogg')
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
@@ -392,4 +395,4 @@ datum/controller/vote
|
||||
set name = "Vote"
|
||||
|
||||
if(vote)
|
||||
src << browse(vote.interface(client),"window=vote;can_close=0")
|
||||
src << browse(vote.interface(client),"window=vote")
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
else
|
||||
assignment = "Unassigned"
|
||||
|
||||
var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh*
|
||||
var/id = generate_record_id()
|
||||
var/icon/front = new(get_id_photo(H), dir = SOUTH)
|
||||
var/icon/side = new(get_id_photo(H), dir = WEST)
|
||||
//General Record
|
||||
@@ -136,8 +136,10 @@
|
||||
locked += L
|
||||
return
|
||||
|
||||
/proc/generate_record_id()
|
||||
return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex
|
||||
|
||||
proc/get_id_photo(var/mob/living/carbon/human/H)
|
||||
/proc/get_id_photo(var/mob/living/carbon/human/H)
|
||||
var/icon/preview_icon = null
|
||||
|
||||
var/g = "m"
|
||||
|
||||
@@ -1220,6 +1220,32 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
access = access_hydroponics
|
||||
group = "Hydroponics"
|
||||
|
||||
/datum/supply_packs/aliengloves
|
||||
name = "Non-Human Glove Kit"
|
||||
contains = list(/obj/item/clothing/gloves/yellow/specialt,
|
||||
/obj/item/clothing/gloves/yellow/specialt,
|
||||
/obj/item/clothing/gloves/yellow/specialt,
|
||||
/obj/item/clothing/gloves/yellow/specialu,
|
||||
/obj/item/clothing/gloves/yellow/specialu,
|
||||
/obj/item/clothing/gloves/yellow/specialu)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "speciality gloves kit"
|
||||
group = "Supply"
|
||||
|
||||
/datum/supply_packs/alienmedicalgloves
|
||||
name = "Non-Human Sterile Glove Kit"
|
||||
contains = list(/obj/item/clothing/gloves/latex/unathi,
|
||||
/obj/item/clothing/gloves/latex/unathi,
|
||||
/obj/item/clothing/gloves/latex/unathi,
|
||||
/obj/item/clothing/gloves/latex/tajara,
|
||||
/obj/item/clothing/gloves/latex/tajara,
|
||||
/obj/item/clothing/gloves/latex/tajara)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "speciality sterile gloves kit"
|
||||
group = "Medical"
|
||||
|
||||
/datum/supply_packs/cardboard_sheets
|
||||
contains = list(/obj/item/stack/material/cardboard)
|
||||
name = "50 cardboard sheets"
|
||||
|
||||
@@ -41,7 +41,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
|
||||
(A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
|
||||
((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"),
|
||||
((haspower) ? "The test light is on." : "The test light is off!"),
|
||||
((A.backupPowerCablesCut()) ? "The backup power light is off!" : "The backup power light is on."),
|
||||
((A.backup_power_lost_until) ? "The backup power light is off!" : "The backup power light is on."),
|
||||
((A.aiControlDisabled==0 && !A.emagged && haspower)? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."),
|
||||
((A.safe==0 && haspower)? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."),
|
||||
((A.normalspeed==0 && haspower)? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/icon/side = new(get_id_photo(dummy), dir = WEST)
|
||||
var/datum/data/record/G = new /datum/data/record()
|
||||
G.fields["name"] = "New Record"
|
||||
G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
|
||||
G.fields["id"] = generate_record_id()
|
||||
G.fields["rank"] = "Unassigned"
|
||||
G.fields["real_rank"] = "Unassigned"
|
||||
G.fields["sex"] = "Male"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
|
||||
#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
|
||||
#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
|
||||
#define ANTAG_RANDOM_EXCEPTED 2048 // If a game mode randomly selects antag types, antag types with this flag should be excluded.
|
||||
|
||||
// Globals.
|
||||
var/global/list/all_antag_types = list()
|
||||
|
||||
@@ -36,7 +36,7 @@ var/datum/antagonist/xenos/borer/borers
|
||||
if(istype(borer))
|
||||
var/mob/living/carbon/human/host
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.stat != 2 && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms())
|
||||
if(H.stat != DEAD && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms())
|
||||
host = H
|
||||
break
|
||||
if(istype(host))
|
||||
@@ -44,7 +44,7 @@ var/datum/antagonist/xenos/borer/borers
|
||||
if(head)
|
||||
borer.host = host
|
||||
head.implants += borer
|
||||
borer.loc = head
|
||||
borer.forceMove(head)
|
||||
if(!borer.host_brain)
|
||||
borer.host_brain = new(borer)
|
||||
borer.host_brain.name = host.name
|
||||
|
||||
@@ -44,4 +44,4 @@ var/datum/antagonist/xenos/xenomorphs
|
||||
player.objectives += new /datum/objective/escape()
|
||||
|
||||
/datum/antagonist/xenos/place_mob(var/mob/living/player)
|
||||
player.loc = get_turf(pick(get_vents()))
|
||||
player.forceMove(get_turf(pick(get_vents())))
|
||||
|
||||
@@ -86,7 +86,8 @@
|
||||
/datum/antagonist/proc/tick()
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/get_candidates(var/ghosts_only)
|
||||
// Get the raw list of potential players.
|
||||
/datum/antagonist/proc/build_candidate_list(var/ghosts_only)
|
||||
candidates = list() // Clear.
|
||||
|
||||
// Prune restricted status. Broke it up for readability.
|
||||
@@ -108,46 +109,57 @@
|
||||
return candidates
|
||||
|
||||
/datum/antagonist/proc/attempt_random_spawn()
|
||||
update_current_antag_max()
|
||||
build_candidate_list(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
|
||||
attempt_spawn()
|
||||
finalize_spawn()
|
||||
|
||||
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
|
||||
/datum/antagonist/proc/attempt_auto_spawn()
|
||||
if(!can_late_spawn())
|
||||
return 0
|
||||
if(!istype(player))
|
||||
var/list/players = get_candidates(is_latejoin_template())
|
||||
if(players && players.len)
|
||||
player = pick(players)
|
||||
if(!istype(player))
|
||||
message_admins("AUTO[uppertext(ticker.mode.name)]: Failed to find a candidate for [role_text].")
|
||||
return 0
|
||||
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
|
||||
message_admins("AUTO[uppertext(ticker.mode.name)]: Selected [player] as a [role_text].")
|
||||
if(istype(player.current, /mob/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
add_antagonist(player,0,0,0,1,1)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/build_candidate_list(var/ghosts_only)
|
||||
// Get the raw list of potential players.
|
||||
update_current_antag_max()
|
||||
candidates = get_candidates(ghosts_only)
|
||||
var/active_antags = get_active_antag_count()
|
||||
log_debug("[uppertext(id)]: Found [active_antags]/[cur_max] active [role_text_plural].")
|
||||
|
||||
if(active_antags >= cur_max)
|
||||
log_debug("Could not auto-spawn a [role_text], active antag limit reached.")
|
||||
return 0
|
||||
|
||||
build_candidate_list(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
|
||||
if(!candidates.len)
|
||||
log_debug("Could not auto-spawn a [role_text], no candidates found.")
|
||||
return 0
|
||||
|
||||
attempt_spawn(1) //auto-spawn antags one at a time
|
||||
if(!pending_antagonists.len)
|
||||
log_debug("Could not auto-spawn a [role_text], none of the available candidates could be selected.")
|
||||
return 0
|
||||
|
||||
var/datum/mind/player = pending_antagonists[1]
|
||||
if(!add_antagonist(player,0,0,0,1,1))
|
||||
log_debug("Could not auto-spawn a [role_text], failed to add antagonist.")
|
||||
return 0
|
||||
|
||||
reset_antag_selection()
|
||||
|
||||
return 1
|
||||
|
||||
//Selects players that will be spawned in the antagonist role from the potential candidates
|
||||
//Selected players are added to the pending_antagonists lists.
|
||||
//Attempting to spawn an antag role with ANTAG_OVERRIDE_JOB should be done before jobs are assigned,
|
||||
//so that they do not occupy regular job slots. All other antag roles should be spawned after jobs are
|
||||
//assigned, so that job restrictions can be respected.
|
||||
/datum/antagonist/proc/attempt_spawn(var/rebuild_candidates = 1)
|
||||
/datum/antagonist/proc/attempt_spawn(var/spawn_target = null)
|
||||
if(spawn_target == null)
|
||||
spawn_target = initial_spawn_target
|
||||
|
||||
// Update our boundaries.
|
||||
if(!candidates.len)
|
||||
return 0
|
||||
|
||||
//Grab candidates randomly until we have enough.
|
||||
while(candidates.len && pending_antagonists.len < initial_spawn_target)
|
||||
while(candidates.len && pending_antagonists.len < spawn_target)
|
||||
var/datum/mind/player = pick(candidates)
|
||||
candidates -= player
|
||||
draft_antagonist(player)
|
||||
@@ -187,10 +199,15 @@
|
||||
pending_antagonists -= player
|
||||
add_antagonist(player,0,0,1)
|
||||
|
||||
//Resets all pending_antagonists, clearing their special_role (and assigned_role if ANTAG_OVERRIDE_JOB is set)
|
||||
/datum/antagonist/proc/reset()
|
||||
reset_antag_selection()
|
||||
|
||||
//Resets the antag selection, clearing all pending_antagonists and their special_role
|
||||
//(and assigned_role if ANTAG_OVERRIDE_JOB is set) as well as clearing the candidate list.
|
||||
//Existing antagonists are left untouched.
|
||||
/datum/antagonist/proc/reset_antag_selection()
|
||||
for(var/datum/mind/player in pending_antagonists)
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = null
|
||||
player.special_role = null
|
||||
pending_antagonists.Cut()
|
||||
candidates.Cut()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
create_objectives(target)
|
||||
update_icons_added(target)
|
||||
greet(target)
|
||||
if(!gag_announcement)
|
||||
announce_antagonist_spawn()
|
||||
|
||||
/datum/antagonist/proc/create_default(var/mob/source)
|
||||
|
||||
@@ -20,6 +20,17 @@
|
||||
/datum/antagonist/proc/get_antag_count()
|
||||
return current_antagonists ? current_antagonists.len : 0
|
||||
|
||||
/datum/antagonist/proc/get_active_antag_count()
|
||||
var/active_antags = 0
|
||||
for(var/datum/mind/player in current_antagonists)
|
||||
var/mob/living/L = player.current
|
||||
if(!L || L.stat == DEAD)
|
||||
continue //no mob or dead
|
||||
if(!L.client && !L.teleop)
|
||||
continue //SSD
|
||||
active_antags++
|
||||
return active_antags
|
||||
|
||||
/datum/antagonist/proc/is_antagonist(var/datum/mind/player)
|
||||
if(player in current_antagonists)
|
||||
return 1
|
||||
@@ -33,10 +44,15 @@
|
||||
return (flags & ANTAG_VOTABLE)
|
||||
|
||||
/datum/antagonist/proc/can_late_spawn()
|
||||
update_current_antag_max()
|
||||
if(get_antag_count() >= cur_max)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/is_latejoin_template()
|
||||
return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
|
||||
|
||||
/proc/all_random_antag_types()
|
||||
// No caching as the ANTAG_RANDOM_EXCEPTED flag can be added/removed mid-round.
|
||||
var/list/antag_candidates = all_antag_types.Copy()
|
||||
for(var/datum/antagonist/antag in antag_candidates)
|
||||
if(antag.flags & ANTAG_RANDOM_EXCEPTED)
|
||||
antag_candidates -= antag
|
||||
return antag_candidates
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
/datum/antagonist/proc/place_mob(var/mob/living/mob)
|
||||
if(!starting_locations || !starting_locations.len)
|
||||
return
|
||||
mob.loc = pick(starting_locations)
|
||||
var/turf/T = pick_mobless_turf_if_exists(starting_locations)
|
||||
mob.forceMove(T)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
return text
|
||||
|
||||
/datum/antagonist/proc/print_player_lite(var/datum/mind/ply)
|
||||
var/role = ply.special_role ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]"
|
||||
var/role = ply.assigned_role ? "\improper[ply.assigned_role]" : "\improper[ply.special_role]"
|
||||
var/text = "<br><b>[ply.name]</b> (<b>[ply.key]</b>) as \a <b>[role]</b> ("
|
||||
if(ply.current)
|
||||
if(ply.current.stat == DEAD)
|
||||
|
||||
@@ -7,7 +7,7 @@ var/datum/antagonist/deathsquad/deathsquad
|
||||
role_text_plural = "Death Commandos"
|
||||
welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors."
|
||||
landmark_id = "Commando"
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER | ANTAG_RANDOM_EXCEPTED
|
||||
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
|
||||
antaghud_indicator = "huddeathsquad"
|
||||
|
||||
@@ -47,7 +47,7 @@ var/datum/antagonist/deathsquad/deathsquad
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/plastique(player), slot_l_store)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(player), slot_belt)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/rig/combat(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/rig/ert/assetprotection(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store)
|
||||
player.implant_loyalty(player)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ var/datum/antagonist/ert/ert
|
||||
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials."
|
||||
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
|
||||
landmark_id = "Response Team"
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME | ANTAG_RANDOM_EXCEPTED
|
||||
antaghud_indicator = "hudloyalist"
|
||||
|
||||
hard_cap = 5
|
||||
|
||||
@@ -22,13 +22,11 @@ var/datum/antagonist/rogue_ai/malf
|
||||
malf = src
|
||||
|
||||
|
||||
/datum/antagonist/rogue_ai/get_candidates()
|
||||
/datum/antagonist/rogue_ai/build_candidate_list()
|
||||
..()
|
||||
for(var/datum/mind/player in candidates)
|
||||
if(player.assigned_role && player.assigned_role != "AI")
|
||||
candidates -= player
|
||||
if(!candidates.len)
|
||||
return list()
|
||||
return candidates
|
||||
|
||||
|
||||
|
||||
@@ -73,13 +73,13 @@ var/datum/antagonist/traitor/traitors
|
||||
return
|
||||
|
||||
/datum/antagonist/traitor/equip(var/mob/living/carbon/human/traitor_mob)
|
||||
if(istype(traitor_mob, /mob/living/silicon)) // this needs to be here because ..() returns false if the mob isn't human
|
||||
add_law_zero(traitor_mob)
|
||||
return 1
|
||||
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
if(istype(traitor_mob, /mob/living/silicon))
|
||||
add_law_zero(traitor_mob)
|
||||
else
|
||||
spawn_uplink(traitor_mob)
|
||||
// Tell them about people they might want to contact.
|
||||
var/mob/living/carbon/human/M = get_nt_opposed()
|
||||
|
||||
@@ -234,6 +234,10 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
L.update_floating( L.Check_Dense_Object() )
|
||||
|
||||
L.lastarea = newarea
|
||||
|
||||
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
|
||||
if(!(L && L.client && (L.client.prefs.asfx_togs & ASFX_AMBIENCE))) return
|
||||
|
||||
play_ambience(L)
|
||||
|
||||
/area/proc/play_ambience(var/mob/living/L)
|
||||
@@ -285,4 +289,3 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
H.AdjustStunned(1)
|
||||
H.AdjustWeakened(1)
|
||||
mob << "<span class='notice'>The sudden appearance of gravity makes you fall to the floor!</span>"
|
||||
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
|
||||
var/global/list/space_surprises = list( /obj/item/clothing/mask/facehugger =4,
|
||||
/obj/item/weapon/pickaxe/silver =4,
|
||||
/obj/item/weapon/pickaxe/drill =4,
|
||||
/obj/item/weapon/pickaxe/jackhammer =4,
|
||||
//mob/living/simple_animal/hostile/carp =3,
|
||||
/obj/item/weapon/pickaxe/diamond =3,
|
||||
/obj/item/weapon/pickaxe/diamonddrill =3,
|
||||
/obj/item/weapon/pickaxe/gold =3,
|
||||
/obj/item/weapon/pickaxe/plasmacutter =2,
|
||||
/obj/structure/closet/syndicate/resources =2,
|
||||
/obj/item/weapon/melee/energy/sword/pirate =1,
|
||||
/obj/mecha/working/ripley/mining =1
|
||||
)
|
||||
|
||||
var/global/list/spawned_surprises = list()
|
||||
|
||||
var/global/max_secret_rooms = 3
|
||||
|
||||
proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , var/clean = 0 , var/name)
|
||||
var/list/room_turfs = list("walls"=list(),"floors"=list())
|
||||
|
||||
//world << "Room spawned at [start_loc.x],[start_loc.y],[start_loc.z]"
|
||||
if(!wall)
|
||||
wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall,/obj/effect/alien/resin)
|
||||
if(!floor)
|
||||
floor = pick(/turf/simulated/floor,/turf/simulated/floor/engine)
|
||||
|
||||
for(var/x = 0,x<x_size,x++)
|
||||
for(var/y = 0,y<y_size,y++)
|
||||
var/turf/T
|
||||
var/cur_loc = locate(start_loc.x+x,start_loc.y+y,start_loc.z)
|
||||
if(clean)
|
||||
for(var/O in cur_loc)
|
||||
qdel(O)
|
||||
|
||||
var/area/asteroid/artifactroom/A = new
|
||||
if(name)
|
||||
A.name = name
|
||||
else
|
||||
A.name = "Artifact Room #[start_loc.x][start_loc.y][start_loc.z]"
|
||||
|
||||
|
||||
|
||||
if(x == 0 || x==x_size-1 || y==0 || y==y_size-1)
|
||||
if(wall == /obj/effect/alien/resin)
|
||||
T = new floor(cur_loc)
|
||||
new /obj/effect/alien/resin(T)
|
||||
else
|
||||
T = new wall(cur_loc)
|
||||
room_turfs["walls"] += T
|
||||
else
|
||||
T = new floor(cur_loc)
|
||||
room_turfs["floors"] += T
|
||||
|
||||
A.contents += T
|
||||
|
||||
|
||||
return room_turfs
|
||||
|
||||
proc/admin_spawn_room_at_pos()
|
||||
var/wall
|
||||
var/floor
|
||||
var/x = input("X position","X pos",usr.x)
|
||||
var/y = input("Y position","Y pos",usr.y)
|
||||
var/z = input("Z position","Z pos",usr.z)
|
||||
var/x_len = input("Desired length.","Length",5)
|
||||
var/y_len = input("Desired width.","Width",5)
|
||||
var/clean = input("Delete existing items in area?" , "Clean area?", 0)
|
||||
switch(alert("Wall type",null,"Reinforced wall","Regular wall","Resin wall"))
|
||||
if("Reinforced wall")
|
||||
wall=/turf/simulated/wall/r_wall
|
||||
if("Regular wall")
|
||||
wall=/turf/simulated/wall
|
||||
if("Resin wall")
|
||||
wall=/obj/effect/alien/resin
|
||||
switch(alert("Floor type",null,"Regular floor","Reinforced floor"))
|
||||
if("Regular floor")
|
||||
floor=/turf/simulated/floor
|
||||
if("Reinforced floor")
|
||||
floor=/turf/simulated/floor/engine
|
||||
if(x && y && z && wall && floor && x_len && y_len)
|
||||
spawn_room(locate(x,y,z),x_len,y_len,wall,floor,clean)
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
proc/make_mining_asteroid_secret(var/size = 5)
|
||||
var/valid = 0
|
||||
var/turf/T = null
|
||||
var/sanity = 0
|
||||
var/list/room = null
|
||||
var/list/turfs = null
|
||||
|
||||
|
||||
turfs = get_area_turfs(/area/mine/unexplored)
|
||||
|
||||
if(!turfs.len)
|
||||
return 0
|
||||
|
||||
while(!valid)
|
||||
valid = 1
|
||||
sanity++
|
||||
if(sanity > 100)
|
||||
return 0
|
||||
|
||||
T=pick(turfs)
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
var/list/surroundings = list()
|
||||
|
||||
surroundings += range(7, locate(T.x,T.y,T.z))
|
||||
surroundings += range(7, locate(T.x+size,T.y,T.z))
|
||||
surroundings += range(7, locate(T.x,T.y+size,T.z))
|
||||
surroundings += range(7, locate(T.x+size,T.y+size,T.z))
|
||||
|
||||
if(locate(/area/mine/explored) in surroundings) // +5s are for view range
|
||||
valid = 0
|
||||
continue
|
||||
|
||||
if(locate(/turf/space) in surroundings)
|
||||
valid = 0
|
||||
continue
|
||||
|
||||
if(locate(/area/asteroid/artifactroom) in surroundings)
|
||||
valid = 0
|
||||
continue
|
||||
|
||||
if(locate(/turf/simulated/floor/plating/airless/asteroid) in surroundings)
|
||||
valid = 0
|
||||
continue
|
||||
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
room = spawn_room(T,size,size,,,1)
|
||||
|
||||
if(room)
|
||||
T = pick(room["floors"])
|
||||
if(T)
|
||||
var/surprise = null
|
||||
valid = 0
|
||||
while(!valid)
|
||||
surprise = pickweight(space_surprises)
|
||||
if(surprise in spawned_surprises)
|
||||
if(prob(20))
|
||||
valid++
|
||||
else
|
||||
continue
|
||||
else
|
||||
valid++
|
||||
|
||||
spawned_surprises.Add(surprise)
|
||||
new surprise(T)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ its easier to just keep the beam vertical.
|
||||
return
|
||||
src.germ_level = 0
|
||||
if(istype(blood_DNA, /list))
|
||||
blood_DNA.Cut()
|
||||
blood_DNA = null
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -21,14 +21,10 @@
|
||||
if(auto_init && ticker && ticker.current_state == GAME_STATE_PLAYING)
|
||||
initialize()
|
||||
|
||||
/proc/generate_debug_runtime() // Guaranteed to runtime and print a stack trace to the runtime log
|
||||
var/t = 0 // BYOND won't let us do var/t = 1/0 directly, but it's fine with this.
|
||||
t = 1 / t
|
||||
|
||||
/atom/movable/Del()
|
||||
if(isnull(gcDestroyed) && loc)
|
||||
testing("GC: -- [type] was deleted via del() rather than qdel() --")
|
||||
generate_debug_runtime() // stick a stack trace in the runtime logs
|
||||
crash_with("GC: -- [type] was deleted via del() rather than qdel() --") // stick a stack trace in the runtime logs
|
||||
// else if(isnull(gcDestroyed))
|
||||
// testing("GC: [type] was deleted via GC without qdel()") //Not really a huge issue but from now on, please qdel()
|
||||
// else
|
||||
|
||||
@@ -21,4 +21,13 @@
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
return !density
|
||||
|
||||
/obj/effect/blob/shield/New()
|
||||
..()
|
||||
update_nearby_tiles()
|
||||
|
||||
/obj/effect/blob/shield/Destroy()
|
||||
density = 0
|
||||
update_nearby_tiles()
|
||||
..()
|
||||
|
||||
@@ -11,15 +11,14 @@
|
||||
event_delay_mod_major = 0.75
|
||||
|
||||
/datum/game_mode/calamity/create_antagonists()
|
||||
var/list/antag_candidates = all_random_antag_types()
|
||||
|
||||
shuffle(all_antag_types) // This is probably the only instance in the game where the order will be important.
|
||||
var/i = 1
|
||||
var/grab_antags = round(num_players()/ANTAG_TYPE_RATIO)+1
|
||||
for(var/antag_id in all_antag_types)
|
||||
if(i > grab_antags)
|
||||
break
|
||||
while(antag_candidates.len && antag_tags.len < grab_antags)
|
||||
var/antag_id = pick(antag_candidates)
|
||||
antag_candidates -= antag_id
|
||||
antag_tags |= antag_id
|
||||
i++
|
||||
|
||||
..()
|
||||
|
||||
/datum/game_mode/calamity/check_victory()
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck."
|
||||
config_tag = "changeling"
|
||||
required_players = 2
|
||||
required_players_secret = 10
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
antag_scaling_coeff = 10
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
extended_round_description = "The station has been infiltrated by a fanatical group of death-cultists! They will use powers from beyond your comprehension to subvert you to their cause and ultimately please their gods through sacrificial summons and physical immolation! Try to survive!"
|
||||
config_tag = "cult"
|
||||
required_players = 5
|
||||
required_players_secret = 15
|
||||
required_enemies = 3
|
||||
uplink_welcome = "Nar-Sie Uplink Console:"
|
||||
end_on_antag_death = 1
|
||||
|
||||
@@ -527,7 +527,11 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
user << "\red You do not have enough space to write a proper rune."
|
||||
var/list/runes = list("teleport", "itemport", "tome", "armor", "convert", "tear in reality", "emp", "drain", "seer", "raise", "obscure", "reveal", "astral journey", "manifest", "imbue talisman", "sacrifice", "wall", "freedom", "cultsummon", "deafen", "blind", "bloodboil", "communicate", "stun")
|
||||
r = input("Choose a rune to scribe", "Rune Scribing") in runes //not cancellable.
|
||||
var/obj/effect/rune/R = new /obj/effect/rune
|
||||
if(locate(/obj/effect/rune) in user.loc)
|
||||
user << "<span class='warning'>There is already a rune in this location.</span>"
|
||||
return
|
||||
|
||||
var/obj/effect/rune/R = new /obj/effect/rune(user.loc)
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
R.blood_DNA = list()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
name = "epidemic"
|
||||
config_tag = "epidemic"
|
||||
required_players = 1
|
||||
required_players_secret = 15
|
||||
round_description = "A deadly epidemic is spreading on the station. Find a cure as fast as possible, and keep your distance to anyone who speaks in a hoarse voice!"
|
||||
|
||||
var/cruiser_arrival
|
||||
|
||||
@@ -10,19 +10,19 @@ var/global/list/additional_antag_types = list()
|
||||
var/probability = 0
|
||||
|
||||
var/required_players = 0 // Minimum players for round to start if voted in.
|
||||
var/required_players_secret = 0 // Minimum number of players for that game mode to be chose in Secret
|
||||
var/required_enemies = 0 // Minimum antagonists for round to start.
|
||||
var/newscaster_announcements = null
|
||||
var/end_on_antag_death = 0 // Round will end when all antagonists are dead.
|
||||
var/ert_disabled = 0 // ERT cannot be called.
|
||||
var/deny_respawn = 0 // Disable respawn during this round.
|
||||
|
||||
var/list/disabled_jobs = list() // Mostly used for Malf. This check is performed in job_controller so it doesn't spawn a regular AI.
|
||||
|
||||
var/shuttle_delay = 1 // Shuttle transit time is multiplied by this.
|
||||
var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled?
|
||||
|
||||
var/list/antag_tags = list() // Core antag templates to spawn.
|
||||
var/list/antag_templates // Extra antagonist types to include.
|
||||
var/list/latejoin_templates = list()
|
||||
var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
|
||||
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
|
||||
var/require_all_templates = 0 // Will only start if all templates are checked and can spawn.
|
||||
@@ -226,10 +226,6 @@ var/global/list/additional_antag_types = list()
|
||||
if((player.client)&&(player.ready))
|
||||
playerC++
|
||||
|
||||
if(master_mode=="secret")
|
||||
if(playerC < required_players_secret)
|
||||
return 0
|
||||
else
|
||||
if(playerC < required_players)
|
||||
return 0
|
||||
|
||||
@@ -267,6 +263,7 @@ var/global/list/additional_antag_types = list()
|
||||
|
||||
/datum/game_mode/proc/pre_setup()
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
antag.update_current_antag_max()
|
||||
antag.build_candidate_list() //compile a list of all eligible candidates
|
||||
|
||||
//antag roles that replace jobs need to be assigned before the job controller hands out jobs.
|
||||
@@ -291,8 +288,6 @@ var/global/list/additional_antag_types = list()
|
||||
if(!(antag.flags & ANTAG_OVERRIDE_JOB))
|
||||
antag.attempt_spawn() //select antags to be spawned
|
||||
antag.finalize_spawn() //actually spawn antags
|
||||
if(antag.is_latejoin_template())
|
||||
latejoin_templates |= antag
|
||||
|
||||
if(emergency_shuttle && auto_recall_shuttle)
|
||||
emergency_shuttle.auto_recall = 1
|
||||
@@ -305,7 +300,7 @@ var/global/list/additional_antag_types = list()
|
||||
|
||||
/datum/game_mode/proc/fail_setup()
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
antag.reset()
|
||||
antag.reset_antag_selection()
|
||||
|
||||
/datum/game_mode/proc/announce_ert_disabled()
|
||||
if(!ert_disabled)
|
||||
@@ -575,6 +570,7 @@ var/global/list/additional_antag_types = list()
|
||||
if(antag)
|
||||
antag_templates |= antag
|
||||
|
||||
shuffle(antag_templates) //In the case of multiple antag types
|
||||
newscaster_announcements = pick(newscaster_standard_feeds)
|
||||
|
||||
/datum/game_mode/proc/check_victory()
|
||||
|
||||
@@ -3,55 +3,39 @@
|
||||
/datum/game_mode/var/max_autotraitor_delay = 12000 // Approx 20 minutes.
|
||||
/datum/game_mode/var/process_count = 0
|
||||
|
||||
/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
|
||||
var/list/usable_templates = list()
|
||||
for(var/datum/antagonist/A in supplied_templates)
|
||||
if(A.can_late_spawn())
|
||||
message_admins("AUTO[uppertext(name)]: [A.id] selected for spawn attempt.")
|
||||
usable_templates |= A
|
||||
return usable_templates
|
||||
|
||||
///process()
|
||||
///Called by the gameticker
|
||||
/datum/game_mode/proc/process()
|
||||
// Slow this down a bit so latejoiners have a chance of being antags.
|
||||
process_count++
|
||||
if(process_count >= 10)
|
||||
process_count = 0
|
||||
try_latespawn()
|
||||
if(round_autoantag && world.time < next_spawn && !emergency_shuttle.departed)
|
||||
process_autoantag()
|
||||
|
||||
/datum/game_mode/proc/latespawn(var/mob/living/carbon/human/character)
|
||||
if(!character.mind)
|
||||
return
|
||||
try_latespawn(character.mind)
|
||||
//This can be overriden in case a game mode needs to do stuff when a player latejoins
|
||||
/datum/game_mode/proc/handle_latejoin(var/mob/living/carbon/human/character)
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/try_latespawn(var/datum/mind/player, var/latejoin_only)
|
||||
/datum/game_mode/proc/process_autoantag()
|
||||
message_admins("[uppertext(name)]: Attempting autospawn.")
|
||||
|
||||
if(emergency_shuttle.departed || !round_autoantag)
|
||||
return
|
||||
var/list/usable_templates = list()
|
||||
for(var/datum/antagonist/A in antag_templates)
|
||||
if(A.can_late_spawn())
|
||||
message_admins("[uppertext(name)]: [A.id] selected for spawn attempt.")
|
||||
usable_templates |= A
|
||||
|
||||
if(world.time < next_spawn)
|
||||
return
|
||||
|
||||
message_admins("AUTO[uppertext(name)]: Attempting spawn.")
|
||||
|
||||
var/list/usable_templates
|
||||
if(latejoin_only && latejoin_templates.len)
|
||||
usable_templates = get_usable_templates(latejoin_templates)
|
||||
else if (antag_templates && antag_templates.len)
|
||||
usable_templates = get_usable_templates(antag_templates)
|
||||
else
|
||||
message_admins("AUTO[uppertext(name)]: Failed to find configured mode spawn templates, please disable auto-antagonists until one is added.")
|
||||
if(!usable_templates.len)
|
||||
message_admins("[uppertext(name)]: Failed to find configured mode spawn templates, please re-enable auto-antagonists after one is added.")
|
||||
round_autoantag = 0
|
||||
return
|
||||
|
||||
while(usable_templates.len)
|
||||
var/datum/antagonist/spawn_antag = pick(usable_templates)
|
||||
usable_templates -= spawn_antag
|
||||
if(spawn_antag.attempt_late_spawn(player))
|
||||
message_admins("AUTO[uppertext(name)]: Attempting to latespawn [spawn_antag.id]. ([spawn_antag.get_antag_count()]/[spawn_antag.cur_max])")
|
||||
|
||||
if(spawn_antag.attempt_auto_spawn())
|
||||
message_admins("[uppertext(name)]: Auto-added a new [spawn_antag.role_text].")
|
||||
message_admins("There are now [spawn_antag.get_active_antag_count()]/[spawn_antag.cur_max] active [spawn_antag.role_text_plural].")
|
||||
next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)
|
||||
return
|
||||
message_admins("AUTO[uppertext(name)]: Failed to proc a viable spawn template.")
|
||||
next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)
|
||||
|
||||
message_admins("[uppertext(name)]: Failed to proc a viable spawn template.")
|
||||
next_spawn = world.time + min_autotraitor_delay //recheck again in the miniumum time
|
||||
|
||||
@@ -8,7 +8,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
|
||||
name = "heist"
|
||||
config_tag = "heist"
|
||||
required_players = 15
|
||||
required_players_secret = 25
|
||||
required_enemies = 4
|
||||
round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!"
|
||||
end_on_antag_death = 1
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
desc = "Secondary coprocessor that increases amount of generated CPU power by 50%"
|
||||
|
||||
/datum/malf_hardware/dual_cpu/get_examine_desc()
|
||||
return "It seems to have an additional CPU connected to it's core."
|
||||
return "It seems to have an additional CPU connected to its core."
|
||||
|
||||
/datum/malf_hardware/dual_ram
|
||||
name = "Secondary Memory Bank"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
uplink_welcome = "Crazy AI Uplink Console:"
|
||||
config_tag = "malfunction"
|
||||
required_players = 2
|
||||
required_players_secret = 7
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
auto_recall_shuttle = 0
|
||||
antag_tags = list(MODE_MALFUNCTION)
|
||||
disabled_jobs = list("AI")
|
||||
|
||||
@@ -163,12 +163,14 @@
|
||||
|
||||
command_announcement.Announce(fulltext)
|
||||
|
||||
// Proc: get_all_apcs()
|
||||
// Proc: get_unhacked_apcs()
|
||||
// Parameters: None
|
||||
// Description: Returns a list of all APCs
|
||||
/proc/get_all_apcs()
|
||||
// Description: Returns a list of all unhacked APCs
|
||||
/proc/get_unhacked_apcs(var/mob/living/silicon/ai/user)
|
||||
var/list/H = list()
|
||||
for(var/obj/machinery/power/apc/A in machines)
|
||||
if(A.hacker && A.hacker == user)
|
||||
continue
|
||||
H.Add(A)
|
||||
return H
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
// END RESEARCH DATUMS
|
||||
// BEGIN ABILITY VERBS
|
||||
|
||||
/datum/game_mode/malfunction/verb/basic_encryption_hack(obj/machinery/power/apc/A as obj in get_all_apcs())
|
||||
/datum/game_mode/malfunction/verb/basic_encryption_hack(obj/machinery/power/apc/A as obj in get_unhacked_apcs(src))
|
||||
set category = "Software"
|
||||
set name = "Basic Encryption Hack"
|
||||
set desc = "10 CPU - Basic encryption hack that allows you to overtake APCs on the station."
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
/datum/game_mode/malfunction/verb/advanced_encryption_hack()
|
||||
set category = "Software"
|
||||
set name = "Advanced Encrypthion Hack"
|
||||
set name = "Advanced Encryption Hack"
|
||||
set desc = "75 CPU - Attempts to bypass encryption on Central Command Quantum Relay, giving you ability to fake centcom messages. Has chance of failing."
|
||||
var/price = 75
|
||||
var/mob/living/silicon/ai/user = usr
|
||||
@@ -106,15 +106,12 @@
|
||||
announce_hack_failure(user, "quantum message relay")
|
||||
return
|
||||
|
||||
var/datum/announcement/priority/command/AN = new/datum/announcement/priority/command()
|
||||
AN.title = title
|
||||
AN.Announce(text)
|
||||
|
||||
command_announcement.Announce(text, title)
|
||||
|
||||
/datum/game_mode/malfunction/verb/elite_encryption_hack()
|
||||
set category = "Software"
|
||||
set name = "Elite Encryption Hack"
|
||||
set desc = "200 CPU - Allows you to hack station's ALERTCON system, changing alert level. Has high chance of failijng."
|
||||
set desc = "200 CPU - Allows you to hack station's ALERTCON system, changing alert level. Has high chance of failing."
|
||||
var/price = 200
|
||||
var/mob/living/silicon/ai/user = usr
|
||||
if(!ability_prechecks(user, price))
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
name = "Memetic Anomaly"
|
||||
config_tag = "meme"
|
||||
required_players = 3
|
||||
required_players_secret = 10
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
recommended_enemies = 2 // need at least a meme and a host
|
||||
votable = 0 // temporarily disable this mode for voting
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing through the defenses of Nanotrasen with technological capabilities eons ahead of your time. They can avoid the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and only hope this unknown assassin isn't here for you."
|
||||
config_tag = "ninja"
|
||||
required_players = 1
|
||||
required_players_secret = 10
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_NINJA)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
round_description = "A mercenary strike force is approaching the station!"
|
||||
config_tag = "mercenary"
|
||||
required_players = 15
|
||||
required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
uplink_welcome = "Corporate Backed Uplink Console:"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
round_description = "Some crewmembers are attempting to start a revolution!"
|
||||
extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders."
|
||||
required_players = 4
|
||||
required_players_secret = 15
|
||||
required_enemies = 3
|
||||
auto_recall_shuttle = 1
|
||||
uplink_welcome = "AntagCorp Uplink Console:"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
extended_round_description = "A powerful entity capable of manipulating the elements around him, most commonly referred to as a 'wizard', has infiltrated the station. They have a wide variety of powers and spells available to them that makes your own simple moral self tremble with fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if their powers can be used for good or if their arrival foreshadows the destruction of the entire station."
|
||||
config_tag = "wizard"
|
||||
required_players = 1
|
||||
required_players_secret = 10
|
||||
required_enemies = 1
|
||||
uplink_welcome = "Wizardly Uplink Console:"
|
||||
uplink_uses = 10
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
selection_color = "#dddddd"
|
||||
access = list() //See /datum/job/assistant/get_access()
|
||||
minimal_access = list() //See /datum/job/assistant/get_access()
|
||||
alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Visitor")
|
||||
//alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Security Cadet", "Visitor")
|
||||
alt_titles = list("Visitor")
|
||||
|
||||
/datum/job/assistant/equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
|
||||
@@ -177,79 +177,6 @@
|
||||
H.species.equip_survival_gear(H,1)
|
||||
return 1
|
||||
|
||||
|
||||
//Griff //BS12 EDIT
|
||||
/*
|
||||
/datum/job/clown
|
||||
title = "Clown"
|
||||
flag = CLOWN
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
access = list(access_clown, access_theatre, access_maint_tunnels)
|
||||
minimal_access = list(access_clown, access_theatre)
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/clown(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/clown(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), slot_wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/stamp/clown(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/pen/crayon/rainbow(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/fancy/crayons(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/toy/waterflower(H), slot_in_backpack)
|
||||
H.mutations.Add(CLUMSY)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/datum/job/mime
|
||||
title = "Mime"
|
||||
flag = MIME
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
access = list(access_mime, access_theatre, access_maint_tunnels)
|
||||
minimal_access = list(access_mime, access_theatre)
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
if(H.backbag == 2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
|
||||
if(H.backbag == 3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/mime(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/mime(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/mime(H), slot_wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/suspenders(H), slot_wear_suit)
|
||||
if(H.backbag == 1)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/pen/crayon/mime(H), slot_l_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_l_hand)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/pen/crayon/mime(H), slot_in_backpack)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(H), slot_in_backpack)
|
||||
H.verbs += /client/proc/mimespeak
|
||||
H.verbs += /client/proc/mimewall
|
||||
H.mind.special_verbs += /client/proc/mimespeak
|
||||
H.mind.special_verbs += /client/proc/mimewall
|
||||
H.miming = 1
|
||||
return 1
|
||||
*/
|
||||
|
||||
|
||||
/datum/job/janitor
|
||||
title = "Janitor"
|
||||
flag = JANITOR
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/head_of_security(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/hos(H), slot_belt)
|
||||
if(H.species.name == "Tajaran")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/tajara(H), slot_gloves)
|
||||
if(H.species.name == "Unathi")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/unathi(H), slot_gloves)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
|
||||
// H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(H), slot_wear_mask) //Grab one from the armory you donk
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(H), slot_glasses)
|
||||
@@ -68,6 +73,11 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/warden(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/warden(H), slot_belt)
|
||||
if(H.species.name == "Tajaran")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/tajara(H), slot_gloves)
|
||||
if(H.species.name == "Unathi")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/unathi(H), slot_gloves)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(H), slot_glasses)
|
||||
// H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(H), slot_wear_mask) //Grab one from the armory you donk
|
||||
@@ -106,6 +116,11 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/det(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/detective(H), slot_belt)
|
||||
if(H.species.name == "Tajaran")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/tajara(H), slot_gloves)
|
||||
if(H.species.name == "Unathi")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black/unathi(H), slot_gloves)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/flame/lighter/zippo(H), slot_l_store)
|
||||
if(H.backbag == 1)//Why cant some of these things spawn in his office?
|
||||
|
||||
@@ -185,36 +185,6 @@ var/global/datum/controller/occupations/job_master
|
||||
return
|
||||
|
||||
|
||||
proc/FillAIPosition()
|
||||
var/ai_selected = 0
|
||||
var/datum/job/job = GetJob("AI")
|
||||
if(!job) return 0
|
||||
if((job.title == "AI") && (config) && (!config.allow_ai)) return 0
|
||||
|
||||
for(var/i = job.total_positions, i > 0, i--)
|
||||
for(var/level = 1 to 3)
|
||||
var/list/candidates = list()
|
||||
if(ticker.mode.name == "AI malfunction")//Make sure they want to malf if its malf
|
||||
candidates = FindOccupationCandidates(job, level, BE_MALF)
|
||||
else
|
||||
candidates = FindOccupationCandidates(job, level)
|
||||
if(candidates.len)
|
||||
var/mob/new_player/candidate = pick(candidates)
|
||||
if(AssignRole(candidate, "AI"))
|
||||
ai_selected++
|
||||
break
|
||||
//Malf NEEDS an AI so force one if we didn't get a player who wanted it
|
||||
if((ticker.mode.name == "AI malfunction")&&(!ai_selected))
|
||||
unassigned = shuffle(unassigned)
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(jobban_isbanned(player, "AI")) continue
|
||||
if(AssignRole(player, "AI"))
|
||||
ai_selected++
|
||||
break
|
||||
if(ai_selected) return 1
|
||||
return 0
|
||||
|
||||
|
||||
/** Proc DivideOccupations
|
||||
* fills var "assigned_role" for all ready players.
|
||||
* This proc must not have any side effect besides of modifying "assigned_role".
|
||||
@@ -260,11 +230,6 @@ var/global/datum/controller/occupations/job_master
|
||||
FillHeadPosition()
|
||||
Debug("DO, Head Check end")
|
||||
|
||||
//Check for an AI
|
||||
Debug("DO, Running AI Check")
|
||||
FillAIPosition()
|
||||
Debug("DO, AI Check end")
|
||||
|
||||
//Other jobs are now checked
|
||||
Debug("DO, Running Standard Check")
|
||||
|
||||
@@ -275,6 +240,7 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
// Loop through all levels from high to low
|
||||
var/list/shuffledoccupations = shuffle(occupations)
|
||||
// var/list/disabled_jobs = ticker.mode.disabled_jobs // So we can use .Find down below without a colon.
|
||||
for(var/level = 1 to 3)
|
||||
//Check the head jobs first each level
|
||||
CheckHeadPositions(level)
|
||||
@@ -284,7 +250,7 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
// Loop through all jobs
|
||||
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
|
||||
if(!job)
|
||||
if(!job || ticker.mode.disabled_jobs.Find(job.title) )
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
@@ -490,7 +456,7 @@ var/global/datum/controller/occupations/job_master
|
||||
if(istype(H)) //give humans wheelchairs, if they need them.
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED))
|
||||
if(!l_foot || !r_foot)
|
||||
var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
|
||||
H.buckled = W
|
||||
H.update_canmove()
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
|
||||
//TODO: put these somewhere else
|
||||
/client/proc/mimewall()
|
||||
set category = "Mime"
|
||||
set name = "Invisible wall"
|
||||
set desc = "Create an invisible wall on your location."
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapicated."
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
|
||||
if(!H.miming)
|
||||
usr << "You still haven't atoned for your speaking transgression. Wait."
|
||||
return
|
||||
H.verbs -= /client/proc/mimewall
|
||||
spawn(300)
|
||||
H.verbs += /client/proc/mimewall
|
||||
for (var/mob/V in viewers(H))
|
||||
if(V!=usr)
|
||||
V.show_message("[H] looks as if a wall is in front of them.", 3, "", 2)
|
||||
usr << "You form a wall in front of yourself."
|
||||
new /obj/effect/forcefield/mime(locate(usr.x,usr.y,usr.z))
|
||||
return
|
||||
|
||||
///////////Mimewalls///////////
|
||||
|
||||
/obj/effect/forcefield/mime
|
||||
icon_state = "empty"
|
||||
name = "invisible wall"
|
||||
desc = "You have a bad feeling about this."
|
||||
var/timeleft = 300
|
||||
var/last_process = 0
|
||||
|
||||
/obj/effect/forcefield/mime/New()
|
||||
..()
|
||||
last_process = world.time
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/effect/forcefield/mime/process()
|
||||
timeleft -= (world.time - last_process)
|
||||
if(timeleft <= 0)
|
||||
processing_objects.Remove(src)
|
||||
qdel(src)
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
/client/proc/mimespeak()
|
||||
set category = "Mime"
|
||||
set name = "Speech"
|
||||
set desc = "Toggle your speech."
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = usr
|
||||
|
||||
if(H.miming)
|
||||
H.miming = 0
|
||||
else
|
||||
H << "You'll have to wait if you want to atone for your sins."
|
||||
spawn(3000)
|
||||
H.miming = 1
|
||||
return
|
||||
@@ -11,6 +11,8 @@ var/const/ENGINEER =(1<<6)
|
||||
var/const/ATMOSTECH =(1<<7)
|
||||
var/const/AI =(1<<8)
|
||||
var/const/CYBORG =(1<<9)
|
||||
var/const/INTERN_SEC =(1<<10)
|
||||
var/const/INTERN_ENG =(1<<11)
|
||||
|
||||
|
||||
var/const/MEDSCI =(1<<1)
|
||||
@@ -26,7 +28,8 @@ var/const/PSYCHIATRIST =(1<<7)
|
||||
var/const/ROBOTICIST =(1<<8)
|
||||
var/const/XENOBIOLOGIST =(1<<9)
|
||||
var/const/PARAMEDIC =(1<<10)
|
||||
|
||||
var/const/INTERN_MED =(1<<11)
|
||||
var/const/INTERN_SCI =(1<<12)
|
||||
|
||||
var/const/CIVILIAN =(1<<2)
|
||||
|
||||
@@ -64,6 +67,7 @@ var/list/engineering_positions = list(
|
||||
"Chief Engineer",
|
||||
"Station Engineer",
|
||||
"Atmospheric Technician",
|
||||
"Engineering Apprentice"
|
||||
)
|
||||
|
||||
|
||||
@@ -73,7 +77,8 @@ var/list/medical_positions = list(
|
||||
"Geneticist",
|
||||
"Psychiatrist",
|
||||
"Chemist",
|
||||
"Paramedic"
|
||||
"Paramedic",
|
||||
"Nursing Intern"
|
||||
)
|
||||
|
||||
|
||||
@@ -82,7 +87,8 @@ var/list/science_positions = list(
|
||||
"Scientist",
|
||||
"Geneticist", //Part of both medical and science
|
||||
"Roboticist",
|
||||
"Xenobiologist"
|
||||
"Xenobiologist",
|
||||
"Lab Assistant"
|
||||
)
|
||||
|
||||
//BS12 EDIT
|
||||
@@ -106,7 +112,8 @@ var/list/security_positions = list(
|
||||
"Head of Security",
|
||||
"Warden",
|
||||
"Detective",
|
||||
"Security Officer"
|
||||
"Security Officer",
|
||||
"Security Cadet"
|
||||
)
|
||||
|
||||
|
||||
@@ -140,3 +147,5 @@ var/list/nonhuman_positions = list(
|
||||
titles = J.alt_titles
|
||||
|
||||
return titles
|
||||
|
||||
//Mahzel : Job preview not added because code don't exist in BS12
|
||||
@@ -400,7 +400,7 @@
|
||||
|
||||
if(!AN && !open && !infected & !imp)
|
||||
AN = "None:"
|
||||
if(!(e.status & ORGAN_DESTROYED))
|
||||
if(!e.is_stump())
|
||||
dat += "<td>[e.name]</td><td>[e.burn_dam]</td><td>[e.brute_dam]</td><td>[robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]</td>"
|
||||
else
|
||||
dat += "<td>[e.name]</td><td>-</td><td>-</td><td>Not Found</td>"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/temperature_resistance = 1000 + T0C
|
||||
volume = 1000
|
||||
use_power = 0
|
||||
interact_offline = 1 // Allows this to be used when not in powered area.
|
||||
var/release_log = ""
|
||||
var/update_flag = 0
|
||||
|
||||
|
||||
@@ -140,9 +140,19 @@
|
||||
if(weld(W, user))
|
||||
if(assembly)
|
||||
assembly.loc = src.loc
|
||||
assembly.anchored = 1
|
||||
assembly.camera_name = c_tag
|
||||
assembly.camera_network = english_list(network, "Exodus", ",", ",")
|
||||
assembly.update_icon()
|
||||
assembly.dir = src.dir
|
||||
if(stat & BROKEN)
|
||||
assembly.state = 2
|
||||
user << "<span class='notice'>You repaired \the [src] frame.</span>"
|
||||
else
|
||||
assembly.state = 1
|
||||
assembly = null //so qdel doesn't eat it.
|
||||
user << "<span class='notice'>You cut \the [src] free from the wall.</span>"
|
||||
new /obj/item/stack/cable_coil(src.loc, length=2)
|
||||
assembly = null //so qdel doesn't eat it.
|
||||
qdel(src)
|
||||
|
||||
// OTHER
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
// Motion, EMP-Proof, X-Ray
|
||||
var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/material/osmium, /obj/item/weapon/stock_parts/scanning_module)
|
||||
var/list/upgrades = list()
|
||||
var/camera_name
|
||||
var/camera_network
|
||||
var/state = 0
|
||||
var/busy = 0
|
||||
/*
|
||||
@@ -47,7 +49,7 @@
|
||||
|
||||
else if(iswrench(W))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "You unattach the assembly from it's place."
|
||||
user << "You unattach the assembly from its place."
|
||||
anchored = 0
|
||||
update_icon()
|
||||
state = 0
|
||||
@@ -67,7 +69,7 @@
|
||||
else if(iswelder(W))
|
||||
|
||||
if(weld(W, user))
|
||||
user << "You unweld the assembly from it's place."
|
||||
user << "You unweld the assembly from its place."
|
||||
state = 1
|
||||
anchored = 1
|
||||
return
|
||||
@@ -78,7 +80,7 @@
|
||||
if(isscrewdriver(W))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
|
||||
var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret ", "Set Network", "Exodus"))
|
||||
var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret ", "Set Network", camera_network ? camera_network : "Exodus"))
|
||||
if(!input)
|
||||
usr << "No input found please hang up and try your call again."
|
||||
return
|
||||
@@ -90,7 +92,7 @@
|
||||
|
||||
var/area/camera_area = get_area(src)
|
||||
var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])"
|
||||
input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag), MAX_NAME_LEN)
|
||||
input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", camera_name ? camera_name : temptag), MAX_NAME_LEN)
|
||||
|
||||
state = 4
|
||||
var/obj/machinery/camera/C = new(src.loc)
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
for(var/x in verbs)
|
||||
verbs -= x
|
||||
set_broken()
|
||||
density = 0
|
||||
|
||||
/obj/machinery/computer/update_icon()
|
||||
..()
|
||||
@@ -124,22 +123,15 @@
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
user << "<span class='notice'>The broken glass falls out.</span>"
|
||||
new /obj/item/weapon/material/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
user << "<span class='notice'>You disconnect the monitor.</span>"
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
M.deconstruct(src)
|
||||
qdel(src)
|
||||
else
|
||||
src.attack_hand(user)
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
..()
|
||||
|
||||
@@ -457,7 +457,7 @@
|
||||
var/counter = 1
|
||||
while(src.active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
|
||||
src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text()], [game_year]<BR>[t1]")
|
||||
|
||||
if (href_list["del_c"])
|
||||
if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
|
||||
|
||||
@@ -391,7 +391,7 @@ What a mess.*/
|
||||
var/counter = 1
|
||||
while(active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
|
||||
active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text()], [game_year]<BR>[t1]")
|
||||
|
||||
if ("Delete Record (ALL)")
|
||||
if (active1)
|
||||
|
||||
@@ -470,7 +470,7 @@
|
||||
var/counter = 1
|
||||
while(src.active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
|
||||
src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text()], [game_year]<BR>[t1]")
|
||||
|
||||
if (href_list["del_c"])
|
||||
if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
|
||||
|
||||
@@ -410,7 +410,7 @@ What a mess.*/
|
||||
var/counter = 1
|
||||
while(active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
|
||||
active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [worldtime2text()], [game_year]<BR>[t1]")
|
||||
|
||||
if ("Delete Record (ALL)")
|
||||
if (active1)
|
||||
|
||||
@@ -38,15 +38,13 @@
|
||||
|
||||
|
||||
/obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(vendmode == 1)
|
||||
if(istype(W, /obj/item/weapon/card))
|
||||
var/obj/item/weapon/card/I = W
|
||||
scan_card(I)
|
||||
var/obj/item/weapon/card/id/I = W.GetID()
|
||||
|
||||
if(vendmode == 1 && I)
|
||||
scan_id(I, W)
|
||||
vendmode = 0
|
||||
if(vendmode == 3)
|
||||
if(istype(W,/obj/item/weapon/card))
|
||||
var/obj/item/weapon/card/I = W
|
||||
if(reimburse(I))
|
||||
if(vendmode == 3 && I)
|
||||
if(reimburse_id(I, W))
|
||||
vendmode = 0
|
||||
if(vendmode == 0)
|
||||
if(istype(W, /obj/item/device/laptop))
|
||||
@@ -210,10 +208,8 @@
|
||||
|
||||
newlap.spawn_parts()
|
||||
|
||||
/obj/machinery/lapvend/proc/scan_card(var/obj/item/weapon/card/I)
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/C = I
|
||||
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
|
||||
/obj/machinery/lapvend/proc/scan_id(var/obj/item/weapon/card/id/C, var/obj/item/I)
|
||||
visible_message("<span class='info'>\The [usr] swipes \the [I] through \the [src].</span>")
|
||||
var/datum/money_account/CH = get_account(C.associated_account_number)
|
||||
if(!CH)
|
||||
usr << "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>"
|
||||
@@ -225,7 +221,7 @@
|
||||
if(D)
|
||||
transfer_and_vend(D, C)
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
else
|
||||
@@ -361,10 +357,8 @@
|
||||
|
||||
|
||||
|
||||
/obj/machinery/lapvend/proc/reimburse(var/obj/item/weapon/card/I)
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
var/obj/item/weapon/card/id/C = I
|
||||
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
|
||||
/obj/machinery/lapvend/proc/reimburse_id(var/obj/item/weapon/card/id/C, var/obj/item/I)
|
||||
visible_message("<span class='info'>\The [usr] swipes \the [I] through \the [src].</span>")
|
||||
var/datum/money_account/CH = get_account(C.associated_account_number)
|
||||
if(!CH)
|
||||
usr << "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>"
|
||||
@@ -377,7 +371,7 @@
|
||||
transfer_and_reimburse(D)
|
||||
return 1
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
return 0
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
var/hasShocked = 0 //Prevents multiple shocks from happening
|
||||
var/secured_wires = 0
|
||||
var/datum/wires/airlock/wires = null
|
||||
|
||||
var/obj/item/device/magnetic_lock/bracer = null
|
||||
var/open_sound_powered = 'sound/machines/airlock.ogg'
|
||||
var/open_sound_unpowered = 'sound/machines/airlock_creaking.ogg'
|
||||
|
||||
@@ -481,7 +481,6 @@ About the new airlock wires panel:
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/door/airlock/update_icon()
|
||||
if(overlays) overlays.Cut()
|
||||
if(density)
|
||||
@@ -728,10 +727,10 @@ About the new airlock wires panel:
|
||||
else if (activate && !src.lights)
|
||||
lights = 1
|
||||
usr << "The door bolt lights have been enabled."
|
||||
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/door/airlock/attackby(C as obj, mob/user as mob)
|
||||
//world << text("airlock attackby src [] obj [] mob []", src, C, user)
|
||||
if(!istype(usr, /mob/living/silicon))
|
||||
@@ -740,8 +739,14 @@ About the new airlock wires panel:
|
||||
return
|
||||
if(istype(C, /obj/item/device/detective_scanner) || istype(C, /obj/item/taperoll))
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
if (istype(C, /obj/item/device/magnetic_lock))
|
||||
if (bracer)
|
||||
user << "<span class='notice'>There is already a [bracer] on [src]!</span>"
|
||||
return
|
||||
var/obj/item/device/magnetic_lock/newbracer = C
|
||||
newbracer.attachto(src, user)
|
||||
return
|
||||
if(!repairing && (istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density))
|
||||
var/obj/item/weapon/weldingtool/W = C
|
||||
if(W.remove_fuel(0,user))
|
||||
@@ -792,16 +797,13 @@ About the new airlock wires panel:
|
||||
da.state = 1
|
||||
da.created_name = src.name
|
||||
da.update_state()
|
||||
|
||||
if(operating == -1 || (stat & BROKEN))
|
||||
new /obj/item/weapon/circuitboard/broken(src.loc)
|
||||
operating = 0
|
||||
else
|
||||
if (!electronics) create_electronics()
|
||||
|
||||
electronics.loc = src.loc
|
||||
electronics = null
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
else if(arePowerSystemsOn())
|
||||
@@ -819,6 +821,7 @@ About the new airlock wires panel:
|
||||
user << "<span class='notice'>The airlock's bolts prevent it from being forced.</span>"
|
||||
else if( !welded && !operating )
|
||||
if(density)
|
||||
|
||||
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||
if(F.wielded)
|
||||
spawn(0) open(1)
|
||||
@@ -830,7 +833,6 @@ About the new airlock wires panel:
|
||||
spawn(0) close(1)
|
||||
else
|
||||
user << "<span class='warning'>You need to be wielding \the [C] to do that.</span>"
|
||||
|
||||
else
|
||||
..()
|
||||
return
|
||||
@@ -852,12 +854,12 @@ About the new airlock wires panel:
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/open(var/forced=0)
|
||||
if(!can_open(forced))
|
||||
|
||||
return 0
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
|
||||
@@ -875,7 +877,9 @@ About the new airlock wires panel:
|
||||
if(!forced)
|
||||
if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
|
||||
return 0
|
||||
|
||||
if (bracer)
|
||||
visible_message("<span class='notice'>[src]'s actuators whirr, but the door does not open.</span>")
|
||||
return 0
|
||||
if(locked || welded)
|
||||
return 0
|
||||
return ..()
|
||||
@@ -883,12 +887,10 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/can_close(var/forced=0)
|
||||
if(locked || welded)
|
||||
return 0
|
||||
|
||||
if(!forced)
|
||||
//despite the name, this wire is for general door control.
|
||||
if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/blocks_airlock()
|
||||
@@ -941,22 +943,20 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/close(var/forced=0)
|
||||
if(!can_close(forced))
|
||||
return 0
|
||||
|
||||
if(safe)
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/AM in turf)
|
||||
if(AM.blocks_airlock())
|
||||
if(world.time > next_beep_at)
|
||||
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
next_beep_at = world.time + SecondsToTicks(10)
|
||||
close_door_at = world.time + 6
|
||||
return
|
||||
|
||||
for(var/turf/turf in locs)
|
||||
for(var/atom/movable/AM in turf)
|
||||
if(AM.airlock_crush(DOOR_CRUSH_DAMAGE))
|
||||
take_damage(DOOR_CRUSH_DAMAGE)
|
||||
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
if(arePowerSystemsOn())
|
||||
playsound(src.loc, open_sound_powered, 100, 1)
|
||||
@@ -972,9 +972,7 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/proc/lock(var/forced=0)
|
||||
if(locked)
|
||||
return 0
|
||||
|
||||
if (operating && !forced) return 0
|
||||
|
||||
src.locked = 1
|
||||
for(var/mob/M in range(1,src))
|
||||
M.show_message("You hear a click from the bottom of the door.", 2)
|
||||
@@ -984,10 +982,8 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/proc/unlock(var/forced=0)
|
||||
if(!src.locked)
|
||||
return
|
||||
|
||||
if (!forced)
|
||||
if(operating || !src.arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) return
|
||||
|
||||
src.locked = 0
|
||||
for(var/mob/M in range(1,src))
|
||||
M.show_message("You hear a click from the bottom of the door.", 2)
|
||||
@@ -1067,8 +1063,8 @@ About the new airlock wires panel:
|
||||
|
||||
/obj/machinery/door/airlock/emp_act(var/severity)
|
||||
if(prob(40/severity))
|
||||
var/duration = world.time + SecondsToTicks(30 / severity)
|
||||
if(duration > electrified_until)
|
||||
var/duration = SecondsToTicks(30 / severity)
|
||||
if(electrified_until > -1 && (duration + world.time) > electrified_until)
|
||||
electrify(duration)
|
||||
..()
|
||||
|
||||
@@ -1081,6 +1077,8 @@ About the new airlock wires panel:
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/airlock/proc/prison_open()
|
||||
if (bracer)
|
||||
return
|
||||
src.unlock()
|
||||
src.open()
|
||||
src.lock()
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
var/timing = 1 // boolean, true/1 timer is on, false/0 means it's not timing
|
||||
var/picture_state // icon_state of alert picture, if not displaying text/numbers
|
||||
var/list/obj/machinery/targets = list()
|
||||
var/list/obj/item/clothing/under/color/orange/uniforms = list()
|
||||
var/timetoset = 0 // Used to set releasetime upon starting the timer
|
||||
var/alerted = 0
|
||||
var/spamcheck = 0
|
||||
|
||||
maptext_height = 26
|
||||
maptext_width = 32
|
||||
@@ -47,6 +50,10 @@
|
||||
if(C.id == src.id)
|
||||
targets += C
|
||||
|
||||
for(var/obj/item/clothing/under/color/orange/D in world)
|
||||
if(D.id == id)
|
||||
uniforms += D
|
||||
|
||||
if(targets.len==0)
|
||||
stat |= BROKEN
|
||||
update_icon()
|
||||
@@ -68,6 +75,8 @@
|
||||
if(timeleft > 1e5)
|
||||
src.releasetime = 0
|
||||
|
||||
if(timeleft < 30 && !alerted)
|
||||
alertuniforms()
|
||||
|
||||
if(world.timeofday > src.releasetime)
|
||||
src.timer_end() // open doors, reset timer, clear status screen
|
||||
@@ -152,6 +161,35 @@
|
||||
/obj/machinery/door_timer/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
// Alert the uniform wearers that their timer is about to end up
|
||||
/obj/machinery/door_timer/proc/alertuniforms()
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
if(!uniforms.len)
|
||||
alerted = 1
|
||||
return
|
||||
|
||||
for(var/obj/item/clothing/under/color/orange/D in uniforms)
|
||||
if(!ishuman(D.loc)) continue
|
||||
D.loc << "A speaker in the collar of your suit pings:\n\blue Your cell timer will expire in 30 seconds or less. Please go to your cell to speed up processing."
|
||||
|
||||
alerted = 1
|
||||
|
||||
return
|
||||
|
||||
// Alert the uniform wearers that they are needed at their cell
|
||||
/obj/machinery/door_timer/proc/summonuniforms()
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
if(spamcheck) return
|
||||
if(!uniforms.len) return
|
||||
for(var/obj/item/clothing/under/color/orange/D in uniforms)
|
||||
if(!ishuman(D.loc)) continue
|
||||
D.loc << "A speaker in the collar of your suit pings:\n\red You have been summoned to your cell!"
|
||||
|
||||
spamcheck = 1
|
||||
spawn(30)
|
||||
spamcheck = 0
|
||||
|
||||
return
|
||||
|
||||
//Allows humans to use door_timer
|
||||
//Opens dialog window when someone clicks on door timer
|
||||
@@ -249,7 +287,8 @@
|
||||
|
||||
if(href_list["change"])
|
||||
src.timer_start()
|
||||
|
||||
if(href_list["summon"])
|
||||
summonuniforms()
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
src.update_icon()
|
||||
|
||||
@@ -409,12 +409,12 @@
|
||||
set_opacity(0)
|
||||
sleep(3)
|
||||
src.density = 0
|
||||
update_nearby_tiles()
|
||||
sleep(7)
|
||||
src.layer = open_layer
|
||||
explosion_resistance = 0
|
||||
update_icon()
|
||||
set_opacity(0)
|
||||
update_nearby_tiles()
|
||||
operating = 0
|
||||
|
||||
if(autoclose)
|
||||
@@ -436,12 +436,12 @@
|
||||
src.density = 1
|
||||
explosion_resistance = initial(explosion_resistance)
|
||||
src.layer = closed_layer
|
||||
update_nearby_tiles()
|
||||
sleep(7)
|
||||
update_icon()
|
||||
if(visible && !glass)
|
||||
set_opacity(1) //caaaaarn!
|
||||
operating = 0
|
||||
update_nearby_tiles()
|
||||
|
||||
//I shall not add a check every x ticks if a door has closed over some fire.
|
||||
var/obj/fire/fire = locate() in loc
|
||||
|
||||
@@ -106,6 +106,15 @@
|
||||
move_into_gibber(user,G.affecting)
|
||||
// Grab() process should clean up the grab item, no need to del it.
|
||||
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = user
|
||||
if(M.h_style == "Floorlength Braid" || M.h_style == "Very Long Hair")
|
||||
if(prob(10))
|
||||
M.apply_damage(30, BRUTE, "head")
|
||||
M.apply_damage(45, HALLOSS)
|
||||
M.visible_message("\red [user]'s hair catches in the [src]!", "\red Your hair gets caught in the [src]!")
|
||||
M.say("*scream")
|
||||
|
||||
/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.restrained())
|
||||
return
|
||||
@@ -235,5 +244,3 @@
|
||||
thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt.
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
@@ -195,7 +195,10 @@ Class Procs:
|
||||
return (stat & (NOPOWER|BROKEN|additional_flags))
|
||||
|
||||
/obj/machinery/CanUseTopic(var/mob/user)
|
||||
if(!interact_offline && (stat & (NOPOWER|BROKEN)))
|
||||
if(stat & BROKEN)
|
||||
return STATUS_CLOSE
|
||||
|
||||
if(!interact_offline && (stat & NOPOWER))
|
||||
return STATUS_CLOSE
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -88,7 +88,7 @@ obj/machinery/scanner/attack_hand(mob/living/carbon/human/user)
|
||||
G.fields["rank"] = "Unassigned"
|
||||
G.fields["real_rank"] = G.fields["rank"]
|
||||
G.fields["name"] = mname
|
||||
G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
|
||||
G.fields["id"] = generate_record_id()
|
||||
M.fields["name"] = G.fields["name"]
|
||||
M.fields["id"] = G.fields["id"]
|
||||
S.fields["name"] = G.fields["name"]
|
||||
|
||||
@@ -819,15 +819,12 @@
|
||||
dat += "<A href='?src=\ref[src];apply_paintjob=1'><br>\[apply customisation routine\]</a><br><hr>"
|
||||
|
||||
if(panel_open)
|
||||
dat += wires()
|
||||
wires.Interact(user)
|
||||
|
||||
user << browse(dat, "window=suit_cycler")
|
||||
onclose(user, "suit_cycler")
|
||||
return
|
||||
|
||||
/obj/machinery/suit_cycler/proc/wires()
|
||||
return wires.GetInteractWindow()
|
||||
|
||||
/obj/machinery/suit_cycler/Topic(href, href_list)
|
||||
if(href_list["eject_suit"])
|
||||
if(!suit) return
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
var/turf/loc = get_turf(usr)
|
||||
var/area/A = loc.loc
|
||||
if (!istype(loc, /turf/simulated/floor))
|
||||
usr << "<span class='danger>\The [src] Alarm cannot be placed on this spot.</span>"
|
||||
usr << "<span class='danger'>\The [src] Alarm cannot be placed on this spot.</span>"
|
||||
return
|
||||
if (A.requires_power == 0 || A.name == "Space")
|
||||
usr << "<span class='danger>\The [src] Alarm cannot be placed in this area.</span>"
|
||||
usr << "<span class='danger'>\The [src] Alarm cannot be placed in this area.</span>"
|
||||
return
|
||||
|
||||
if(gotwallitem(loc, ndir))
|
||||
usr << "<span class='danger>There's already an item on this wall!</span>"
|
||||
usr << "<span class='danger'>There's already an item on this wall!</span>"
|
||||
return
|
||||
|
||||
var/obj/machinery/M = new build_machine_type(loc, ndir, 1)
|
||||
|
||||
@@ -553,6 +553,14 @@
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attack_hand(mob/user as mob)
|
||||
var/dat, left_part
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/M = user
|
||||
if(M.h_style == "Floorlength Braid" || M.h_style == "Very Long Hair")
|
||||
if(prob(10))
|
||||
M.apply_damage(30, BRUTE, "head")
|
||||
M.apply_damage(45, HALLOSS)
|
||||
M.visible_message("\red [user]'s hair catches in the [src]!", "\red Your hair gets caught in the [src]!")
|
||||
M.say("*scream")
|
||||
if (..())
|
||||
return
|
||||
if(!operation_allowed(user))
|
||||
@@ -851,3 +859,42 @@
|
||||
else
|
||||
user << "The fabricator cannot hold more [sname]."
|
||||
return
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/MouseDrop_T(mob/living/carbon/human/target as mob, mob/user as mob)
|
||||
if (!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
|
||||
return
|
||||
if(target == user)
|
||||
if(target.h_style == "Floorlength Braid" || target.h_style == "Very Long Hair")
|
||||
user.visible_message("\blue [user] looks like they're about to feed their own hair into the [src], but think better of it.", "\blue You grasp your hair and are about to feed it into the [src], but stop and come to your sense.")
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
var/target_loc = target.loc
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
if(target.h_style != "Cut Hair" || target.h_style != "Short Hair" || target.h_style != "Skinhead" || target.h_style != "Buzzcut" || target.h_style != "Crewcut" || target.h_style != "Bald" || target.h_style != "Balding Hair")
|
||||
user.visible_message("\red [user] starts feeding [target]'s hair into the [src]!", "\red You start feeding [target]'s hair into the [src]!")
|
||||
if(!do_after(usr, 50))
|
||||
return
|
||||
if(target_loc != target.loc)
|
||||
return
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
user.visible_message("\red [user] feeds the [target]'s hair into the [src] and flicks it on!", "\red You turn the [src] on!")
|
||||
target.apply_damage(30, BRUTE, "head")
|
||||
target.apply_damage(25, HALLOSS)
|
||||
target.say("*scream")
|
||||
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has fed [target.name]'s ([target.ckey]) hair into a [src].</font>")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their hair fed into [src] by [user.name] ([user.ckey])</font>")
|
||||
msg_admin_attack("[key_name_admin(user.ckey)] fed [key_name_admin(target)] in a [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
else
|
||||
return
|
||||
if(!do_after(usr, 35))
|
||||
return
|
||||
if(target_loc != target.loc)
|
||||
return
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
user.visible_message("\red [user] starts tugging on [target]'s head as the [src] keeps running!", "\red You start tugging on [target]'s head!")
|
||||
target.apply_damage(25, BRUTE, "head")
|
||||
target.apply_damage(10, HALLOSS)
|
||||
target.say("*scream")
|
||||
spawn(10)
|
||||
user.visible_message("\red [user] stops the [src] and leaves [target] resting as they are.", "\red You turn the [src] off and let go of [target].")
|
||||
|
||||
@@ -996,6 +996,11 @@
|
||||
|
||||
if (usr.stat || !ishuman(usr))
|
||||
return
|
||||
|
||||
if (usr.buckled)
|
||||
usr << "<span class='warning'>You can't climb into the exosuit while buckled!</span>"
|
||||
return
|
||||
|
||||
src.log_message("[usr] tries to move in.")
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj
|
||||
var/can_buckle = 0
|
||||
var/buckle_movable = 0
|
||||
var/buckle_dir = 0
|
||||
var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1
|
||||
var/buckle_require_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
|
||||
var/mob/living/buckled_mob = null
|
||||
@@ -31,7 +32,7 @@
|
||||
|
||||
M.buckled = src
|
||||
M.facing_dir = null
|
||||
M.set_dir(dir)
|
||||
M.set_dir(buckle_dir ? buckle_dir : dir)
|
||||
M.update_canmove()
|
||||
buckled_mob = M
|
||||
post_buckle_mob(M)
|
||||
@@ -55,7 +56,8 @@
|
||||
user << "<span class='warning'>You can't buckle anyone in before the game starts.</span>"
|
||||
if(!user.Adjacent(M) || user.restrained() || user.lying || user.stat || istype(user, /mob/living/silicon/pai))
|
||||
return
|
||||
|
||||
if(M == buckled_mob)
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/slime))
|
||||
user << "<span class='warning'>The [M] is too squishy to buckle in.</span>"
|
||||
return
|
||||
|
||||
@@ -4,14 +4,76 @@
|
||||
/obj/effect/effect/smoke/chem
|
||||
icon = 'icons/effects/chemsmoke.dmi'
|
||||
opacity = 0
|
||||
layer = 6
|
||||
time_to_live = 300
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
|
||||
var/splash_amount = 10 //atoms moving through a smoke cloud get splashed with up to 10 units of reagent
|
||||
var/turf/destination
|
||||
|
||||
/obj/effect/effect/smoke/chem/New(var/newloc, smoke_duration, turf/dest_turf = null, icon/cached_icon = null)
|
||||
time_to_live = smoke_duration
|
||||
|
||||
/obj/effect/effect/smoke/chem/New()
|
||||
..()
|
||||
create_reagents(500)
|
||||
return
|
||||
|
||||
create_reagents(500)
|
||||
|
||||
if(cached_icon)
|
||||
icon = cached_icon
|
||||
|
||||
set_dir(pick(cardinal))
|
||||
pixel_x = -32 + rand(-8, 8)
|
||||
pixel_y = -32 + rand(-8, 8)
|
||||
|
||||
//switching opacity on after the smoke has spawned, and then turning it off before it is deleted results in cleaner
|
||||
//lighting and view range updates (Is this still true with the new lighting system?)
|
||||
opacity = 1
|
||||
|
||||
//float over to our destination, if we have one
|
||||
destination = dest_turf
|
||||
if(destination)
|
||||
walk_to(src, destination)
|
||||
|
||||
/obj/effect/effect/smoke/chem/Destroy()
|
||||
opacity = 0
|
||||
fadeOut()
|
||||
..()
|
||||
|
||||
/obj/effect/effect/smoke/chem/Move()
|
||||
var/list/oldlocs = view(1, src)
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/turf/T in view(1, src) - oldlocs)
|
||||
for(var/atom/movable/AM in T)
|
||||
if(!istype(AM, /obj/effect/effect/smoke/chem))
|
||||
reagents.splash(AM, splash_amount, copy = 1)
|
||||
if(loc == destination)
|
||||
bound_width = 96
|
||||
bound_height = 96
|
||||
|
||||
/obj/effect/effect/smoke/chem/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(!istype(AM, /obj/effect/effect/smoke/chem))
|
||||
reagents.splash(AM, splash_amount, copy = 1)
|
||||
|
||||
/obj/effect/effect/smoke/chem/proc/initial_splash()
|
||||
for(var/turf/T in view(1, src))
|
||||
for(var/atom/movable/AM in T)
|
||||
if(!istype(AM, /obj/effect/effect/smoke/chem))
|
||||
reagents.splash(AM, splash_amount, copy = 1)
|
||||
|
||||
// Fades out the smoke smoothly using it's alpha variable.
|
||||
/obj/effect/effect/smoke/chem/proc/fadeOut(var/frames = 16)
|
||||
if(!alpha) return //already transparent
|
||||
|
||||
frames = max(frames, 1) //We will just assume that by 0 frames, the coder meant "during one frame".
|
||||
var/alpha_step = round(alpha / frames)
|
||||
while(alpha > 0)
|
||||
alpha = max(0, alpha - alpha_step)
|
||||
sleep(world.tick_lag)
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Chem Smoke Effect System
|
||||
/////////////////////////////////////////////
|
||||
/datum/effect/effect/system/smoke_spread/chem
|
||||
smoke_type = /obj/effect/effect/smoke/chem
|
||||
var/obj/chemholder
|
||||
@@ -115,13 +177,21 @@
|
||||
else
|
||||
I = icon('icons/effects/96x96.dmi', "smoke")
|
||||
|
||||
//Calculate smoke duration
|
||||
var/smoke_duration = 150
|
||||
|
||||
var/pressure = 0
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
if(environment) pressure = environment.return_pressure()
|
||||
smoke_duration = between(5, smoke_duration*pressure/(ONE_ATMOSPHERE/3), smoke_duration)
|
||||
|
||||
var/const/arcLength = 2.3559 //distance between each smoke cloud
|
||||
|
||||
for(var/i = 0, i < range, i++) //calculate positions for smoke coverage - then spawn smoke
|
||||
var/radius = i * 1.5
|
||||
if(!radius)
|
||||
spawn(0)
|
||||
spawnSmoke(location, I, 1)
|
||||
spawnSmoke(location, I, 1, 1)
|
||||
continue
|
||||
|
||||
var/offset = 0
|
||||
@@ -146,43 +216,26 @@
|
||||
// Randomizes and spawns the smoke effect.
|
||||
// Also handles deleting the smoke once the effect is finished.
|
||||
//------------------------------------------
|
||||
/datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1, var/obj/effect/effect/smoke/chem/passed_smoke)
|
||||
/datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/smoke_duration, var/dist = 1, var/splash_initial=0, var/obj/effect/effect/smoke/chem/passed_smoke)
|
||||
|
||||
var/obj/effect/effect/smoke/chem/smoke
|
||||
if(passed_smoke)
|
||||
smoke = passed_smoke
|
||||
else
|
||||
smoke = PoolOrNew(/obj/effect/effect/smoke/chem, location)
|
||||
smoke = PoolOrNew(/obj/effect/effect/smoke/chem, list(location, smoke_duration + rand(0, 20), T, I))
|
||||
|
||||
if(chemholder.reagents.reagent_list.len)
|
||||
chemholder.reagents.trans_to_obj(smoke, chemholder.reagents.total_volume / dist, copy = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents
|
||||
smoke.icon = I
|
||||
smoke.layer = 6
|
||||
smoke.set_dir(pick(cardinal))
|
||||
smoke.pixel_x = -32 + rand(-8, 8)
|
||||
smoke.pixel_y = -32 + rand(-8, 8)
|
||||
walk_to(smoke, T)
|
||||
smoke.opacity = 1 //switching opacity on after the smoke has spawned, and then
|
||||
sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner
|
||||
smoke.opacity = 0 // lighting and view range updates
|
||||
fadeOut(smoke)
|
||||
qdel(src)
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/chem/spores/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1)
|
||||
//Kinda ugly, but needed unless the system is reworked
|
||||
if(splash_initial)
|
||||
smoke.initial_splash()
|
||||
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/chem/spores/spawnSmoke(var/turf/T, var/smoke_duration, var/icon/I, var/dist = 1)
|
||||
var/obj/effect/effect/smoke/chem/spores = PoolOrNew(/obj/effect/effect/smoke/chem, location)
|
||||
spores.name = "cloud of [seed.seed_name] [seed.seed_noun]"
|
||||
..(T, I, dist, spores)
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16) // Fades out the smoke smoothly using it's alpha variable.
|
||||
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
|
||||
..(T, I, smoke_duration, dist, spores)
|
||||
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow() // Smoke pathfinder. Uses a flood fill method based on zones to quickly check what turfs the smoke (airflow) can actually reach.
|
||||
|
||||
@@ -60,7 +60,7 @@ var/global/list/image/splatter_cache=list()
|
||||
var/obj/item/organ/external/l_foot = perp.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = perp.get_organ("r_foot")
|
||||
var/hasfeet = 1
|
||||
if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED))
|
||||
if((!l_foot || l_foot.is_stump()) && (!r_foot || r_foot.is_stump()))
|
||||
hasfeet = 0
|
||||
if(perp.shoes && !perp.buckled)//Adding blood to shoes
|
||||
var/obj/item/clothing/shoes/S = perp.shoes
|
||||
|
||||
@@ -105,27 +105,61 @@
|
||||
qdel(src)
|
||||
*/
|
||||
|
||||
/client/proc/spawn_tanktransferbomb()
|
||||
set category = "Debug"
|
||||
set desc = "Spawn a tank transfer valve bomb"
|
||||
set name = "Instant TTV"
|
||||
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
|
||||
|
||||
var/p = input("Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt)) as num|null
|
||||
if(p == null) return
|
||||
|
||||
var/o = input("Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt)) as num|null
|
||||
if(o == null) return
|
||||
|
||||
var/c = input("Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt)) as num|null
|
||||
if(c == null) return
|
||||
|
||||
new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
|
||||
|
||||
/obj/effect/spawner/newbomb
|
||||
name = "bomb"
|
||||
name = "TTV bomb"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x"
|
||||
var/btype = 0 // 0=radio, 1=prox, 2=time
|
||||
|
||||
timer
|
||||
btype = 2
|
||||
var/assembly_type = /obj/item/device/assembly/signaler
|
||||
|
||||
syndicate
|
||||
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
|
||||
var/phoron_amt = 10.96
|
||||
var/oxygen_amt = 16.44
|
||||
var/carbon_amt = 0.0
|
||||
|
||||
proximity
|
||||
btype = 1
|
||||
/obj/effect/spawner/newbomb/timer
|
||||
name = "TTV bomb - timer"
|
||||
assembly_type = /obj/item/device/assembly/timer
|
||||
|
||||
radio
|
||||
btype = 0
|
||||
/obj/effect/spawner/newbomb/timer/syndicate
|
||||
name = "TTV bomb - merc"
|
||||
//High yield bombs. Yes, it is possible to make these with toxins
|
||||
phoron_amt = 15.66
|
||||
oxygen_amt = 24.66
|
||||
|
||||
/obj/effect/spawner/newbomb/proximity
|
||||
name = "TTV bomb - proximity"
|
||||
assembly_type = /obj/item/device/assembly/prox_sensor
|
||||
|
||||
/obj/effect/spawner/newbomb/New()
|
||||
/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
|
||||
if(ph != null) phoron_amt = ph
|
||||
if(ox != null) oxygen_amt = ox
|
||||
if(co != null) carbon_amt = co
|
||||
..()
|
||||
|
||||
/obj/effect/spawner/newbomb/New(newloc)
|
||||
..(newloc)
|
||||
|
||||
var/obj/item/device/transfer_valve/V = new(src.loc)
|
||||
var/obj/item/weapon/tank/phoron/PT = new(V)
|
||||
var/obj/item/weapon/tank/oxygen/OT = new(V)
|
||||
@@ -137,28 +171,15 @@
|
||||
OT.master = V
|
||||
|
||||
PT.air_contents.temperature = PHORON_FLASHPOINT
|
||||
PT.air_contents.adjust_multi("phoron", 12, "carbon_dioxide", 8)
|
||||
PT.air_contents.gas["phoron"] = phoron_amt
|
||||
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
|
||||
PT.air_contents.update_values()
|
||||
|
||||
OT.air_contents.temperature = PHORON_FLASHPOINT
|
||||
OT.air_contents.adjust_gas("oxygen", 20)
|
||||
OT.air_contents.gas["oxygen"] = oxygen_amt
|
||||
OT.air_contents.update_values()
|
||||
|
||||
var/obj/item/device/assembly/S
|
||||
|
||||
switch (src.btype)
|
||||
// radio
|
||||
if (0)
|
||||
|
||||
S = new/obj/item/device/assembly/signaler(V)
|
||||
|
||||
// proximity
|
||||
if (1)
|
||||
|
||||
S = new/obj/item/device/assembly/prox_sensor(V)
|
||||
|
||||
// timer
|
||||
if (2)
|
||||
|
||||
S = new/obj/item/device/assembly/timer(V)
|
||||
var/obj/item/device/assembly/S = new assembly_type(V)
|
||||
|
||||
|
||||
V.attached_device = S
|
||||
|
||||
@@ -151,6 +151,9 @@
|
||||
if(temp && !temp.is_usable())
|
||||
user << "<span class='notice'>You try to move your [temp.name], but cannot!"
|
||||
return
|
||||
if(!temp)
|
||||
user << "<span class='notice'>You try to use your hand, but realize it is no longer attached!"
|
||||
return
|
||||
src.pickup(user)
|
||||
if (istype(src.loc, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = src.loc
|
||||
@@ -242,6 +245,9 @@
|
||||
// for items that can be placed in multiple slots
|
||||
// note this isn't called during the initial dressing of a player
|
||||
/obj/item/proc/equipped(var/mob/user, var/slot)
|
||||
layer = 20
|
||||
if(user.client) user.client.screen |= src
|
||||
if(user.pulling == src) user.stop_pulling()
|
||||
return
|
||||
|
||||
//Defines which slots correspond to which slot flags
|
||||
|
||||
@@ -721,7 +721,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if("Message")
|
||||
|
||||
var/obj/item/device/pda/P = locate(href_list["target"])
|
||||
src.create_message(U, P, !href_list["notap"])
|
||||
var/tap = istype(U, /mob/living/carbon)
|
||||
src.create_message(U, P, tap)
|
||||
if(mode == 2)
|
||||
if(href_list["target"] in conversations) // Need to make sure the message went through, if not welp.
|
||||
active_conversation = href_list["target"]
|
||||
@@ -1040,7 +1041,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
new_message(sending_device, sending_device.owner, sending_device.ownjob, message)
|
||||
|
||||
/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message)
|
||||
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;notap=[istype(loc, /mob/living/silicon)];skiprefresh=1;target=\ref[sending_unit]'>Reply</a>)"
|
||||
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>)"
|
||||
new_info(message_silent, ttone, reception_message)
|
||||
|
||||
log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]")
|
||||
@@ -1052,7 +1053,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(ismob(sending_unit.loc) && isAI(loc))
|
||||
track = "(<a href='byond://?src=\ref[loc];track=\ref[sending_unit.loc];trackname=[html_encode(sender)]'>Follow</a>)"
|
||||
|
||||
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;notap=1;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>) [track]"
|
||||
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>) [track]"
|
||||
new_info(message_silent, newstone, reception_message)
|
||||
|
||||
log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]")
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
|
||||
/obj/item/device/chameleon/dropped()
|
||||
disrupt()
|
||||
..()
|
||||
|
||||
/obj/item/device/chameleon/equipped()
|
||||
disrupt()
|
||||
..()
|
||||
|
||||
/obj/item/device/chameleon/attack_self()
|
||||
toggle()
|
||||
|
||||
@@ -68,6 +68,24 @@
|
||||
if(safety <= 0)
|
||||
M.Weaken(10)
|
||||
flick("e_flash", M.flash)
|
||||
//Vaurca damage 15/01/16
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.flags & IS_BUG)
|
||||
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
if(!E)
|
||||
return
|
||||
usr << "\red Your eyes burn with the intense light of the flash!."
|
||||
E.damage += rand(10, 11)
|
||||
if(E.damage > 12)
|
||||
M.eye_blurry += rand(3,6)
|
||||
if (E.damage >= E.min_broken_damage)
|
||||
M.sdisabilities |= BLIND
|
||||
else if (E.damage >= E.min_bruised_damage)
|
||||
M.eye_blind = 5
|
||||
M.eye_blurry = 5
|
||||
M.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
M.disabilities &= ~NEARSIGHTED
|
||||
|
||||
if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
|
||||
if(user.mind && user.mind in revs.current_antagonists)
|
||||
|
||||
323
code/game/objects/items/devices/magnetic_lock.dm
Normal file
323
code/game/objects/items/devices/magnetic_lock.dm
Normal file
@@ -0,0 +1,323 @@
|
||||
#define STATUS_INACTIVE 0
|
||||
#define STATUS_ACTIVE 1
|
||||
#define STATUS_BROKEN 2
|
||||
|
||||
#define LAYER_ATTACHED 3.2
|
||||
#define LAYER_NORMAL 3
|
||||
|
||||
/obj/item/device/magnetic_lock
|
||||
name = "magnetic door lock"
|
||||
desc = "A large, ID locked device used for completely locking down airlocks."
|
||||
icon = 'icons/obj/magnetic_locks/centcom.dmi'
|
||||
icon_state = "inactive"
|
||||
w_class = 3
|
||||
req_access = list(103)
|
||||
health = 90
|
||||
|
||||
var/department = "CENTCOM"
|
||||
var/status = 0
|
||||
var/constructionstate = 0
|
||||
var/drainamount = 20
|
||||
var/obj/machinery/door/airlock/target = null
|
||||
var/obj/item/weapon/cell/powercell
|
||||
|
||||
/obj/item/device/magnetic_lock/security
|
||||
icon = 'icons/obj/magnetic_locks/security.dmi'
|
||||
department = "Security"
|
||||
req_access = list(1)
|
||||
|
||||
/obj/item/device/magnetic_lock/engineering
|
||||
icon = 'icons/obj/magnetic_locks/engineering.dmi'
|
||||
department = "Engineering"
|
||||
req_access = null
|
||||
req_one_access = list(11, 24)
|
||||
|
||||
/obj/item/device/magnetic_lock/New()
|
||||
..()
|
||||
|
||||
powercell = new /obj/item/weapon/cell/high()
|
||||
|
||||
/obj/item/device/magnetic_lock/examine()
|
||||
..()
|
||||
|
||||
if (status == STATUS_BROKEN)
|
||||
usr << "<span class='danger'>It looks broken!</span>"
|
||||
else
|
||||
if (powercell)
|
||||
var/power = round(powercell.charge / powercell.maxcharge * 100)
|
||||
usr << "\blue The powercell is at [power]% charge."
|
||||
else
|
||||
usr << "\red It has no powercell to power it!"
|
||||
|
||||
/obj/item/device/magnetic_lock/attack_hand(var/mob/user)
|
||||
if (status == STATUS_ACTIVE)
|
||||
ui_interact(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/magnetic_lock/bullet_act(var/obj/item/projectile/Proj)
|
||||
takedamage(Proj.damage)
|
||||
..()
|
||||
|
||||
/obj/item/device/magnetic_lock/attackby(var/obj/item/I, var/mob/user)
|
||||
if (status == STATUS_BROKEN)
|
||||
user << "<span class='danger'>[src] is broken beyond repair!</span>"
|
||||
return
|
||||
|
||||
if (istype(I, /obj/item/weapon) && user.a_intent == "hurt")
|
||||
if (I.force >= 8)
|
||||
user.visible_message("<span class='danger'>[user] bashes [src] with [I]!</span>", "<span class='danger'>You strike [src] with [I], damaging it!</span>")
|
||||
takedamage(I.force)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] hits [src] with [I] to no visible effect.</span>", "<span class='notice'>You hit [src] with [I], but it appears to have no effect.</span>")
|
||||
return
|
||||
|
||||
switch (constructionstate)
|
||||
if (0)
|
||||
if (istype(I, /obj/item/weapon/card/emag))
|
||||
var/obj/item/weapon/card/emag/emagcard = I
|
||||
emagcard.uses--
|
||||
visible_message("<span class='danger'>[src] sparks and falls off the door!</span>", "<span class='danger'>You emag [src], frying its circuitry[status == STATUS_ACTIVE ? " and making it drop onto the floor" : ""]!</span>")
|
||||
|
||||
setstatus(STATUS_BROKEN)
|
||||
return
|
||||
|
||||
if (status == STATUS_ACTIVE && istype(I, /obj/item/weapon/card/id))
|
||||
if (check_access(I) && !constructionstate)
|
||||
user << "<span class='notice'>You swipe your [I] through [src], making it drop onto the floor with a thud.</span>"
|
||||
setstatus(STATUS_INACTIVE)
|
||||
return
|
||||
else if (constructionstate)
|
||||
user << "<span class='danger'>You cannot swipe your [I] through [src] with it partially dismantled!</span>"
|
||||
return
|
||||
else
|
||||
user << "<span class='danger'>A red light flashes on [src] as you swipe your [I] through it.</span>"
|
||||
flick("deny",src)
|
||||
return
|
||||
|
||||
if (istype(I, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You unfasten and remove the plastic cover from [src], revealing a thick metal shell.</span>"
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
setconstructionstate(1)
|
||||
return
|
||||
|
||||
if (1)
|
||||
if (istype(I, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You put the metal cover of back onto [src], and screw it tight.</span>"
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
setconstructionstate(0)
|
||||
return
|
||||
if (istype(I, /obj/item/weapon/cell))
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
powercell = I
|
||||
return
|
||||
if (istype(I, /obj/item/weapon/crowbar))
|
||||
user << "<span class='notice'>You remove \the [powercell] from \the [src].</span>"
|
||||
powercell.loc = loc
|
||||
powercell = null
|
||||
return
|
||||
if (istype(I, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if (WT.remove_fuel(1, user))
|
||||
user.visible_message("<span class='notice'>[user] starts welding through the metal shell of [src].</span>", "<span class='notice'>You start welding through the metal covering of [src]</span>")
|
||||
playsound(loc, 'sound/items/Welder.ogg', 50, 1)
|
||||
if (do_after(user, 25))
|
||||
user << "<span class='notice'>You are able to weld through the metal shell of [src].</span>"
|
||||
setconstructionstate(2)
|
||||
return
|
||||
if (2)
|
||||
if (istype(I, /obj/item/weapon/crowbar))
|
||||
user << "<span class='notice'>You pry off the metal covering from [src].</span>"
|
||||
playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
setconstructionstate(3)
|
||||
return
|
||||
if (3)
|
||||
if (istype(I, /obj/item/weapon/wirecutters))
|
||||
user << "<span class='notice'>You cut the wires connecting the [src]'s magnets to their powersupply, [target ? "making the device fall off [target] and rendering it unusable." : "rendering the device unusable."]</span>"
|
||||
playsound(loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
setconstructionstate(4)
|
||||
return
|
||||
|
||||
/obj/item/device/magnetic_lock/process()
|
||||
if (powercell && powercell.charge > drainamount)
|
||||
powercell.charge -= drainamount
|
||||
else
|
||||
if (powercell)
|
||||
powercell.charge = 0
|
||||
visible_message("<span class='danger'>[src] beeps loudly and falls off \the [target]; its powercell having run out of power.</span>")
|
||||
setstatus(STATUS_INACTIVE)
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/attachto(var/obj/machinery/door/airlock/newtarget, var/mob/user as mob)
|
||||
if (status == STATUS_BROKEN)
|
||||
user << "<span class='danger'>[src] is damaged beyond repair! It cannot be used!</span>"
|
||||
return
|
||||
|
||||
if (!newtarget.density || newtarget.operating)
|
||||
user << "<span class='danger'>[newtarget] must be closed before you can attach [src] to it!</span>"
|
||||
return
|
||||
|
||||
if (newtarget.p_open)
|
||||
user << "<span class='danger'>You must close [newtarget]'s maintenance panel before attaching [src] to it!</span>"
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts mounting [src] onto [newtarget].</span>", "<span class='notice'>You begin mounting [src] onto [newtarget].</span>")
|
||||
if (do_after(user, 35, 1))
|
||||
if (status == STATUS_BROKEN)
|
||||
user << "<span class='danger'>[src] is damaged beyond repair! It cannot be used!</span>"
|
||||
return
|
||||
|
||||
if (!newtarget.density)
|
||||
user << "<span class='danger'>[newtarget] must be closed before you can attach [src] to it!</span>"
|
||||
return
|
||||
|
||||
if (newtarget.p_open)
|
||||
user << "<span class='danger'>You must close [newtarget]'s maintenance panel before attaching [src] to it!</span>"
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] attached [src] onto [newtarget] and flicks it on. The magnetic lock now seals [newtarget].</span>", "<span class='notice'>You attached [src] onto [newtarget] and switched on the magnetic lock.</span>")
|
||||
user.drop_item()
|
||||
|
||||
setstatus(STATUS_ACTIVE, newtarget)
|
||||
return
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/setstatus(var/newstatus, var/obj/machinery/door/airlock/newtarget as obj)
|
||||
switch (newstatus)
|
||||
if (STATUS_INACTIVE)
|
||||
if (status != STATUS_ACTIVE)
|
||||
return
|
||||
if (!target)
|
||||
return
|
||||
|
||||
detach()
|
||||
icon_state = "inactive"
|
||||
status = newstatus
|
||||
|
||||
if (STATUS_ACTIVE)
|
||||
if (status != STATUS_INACTIVE)
|
||||
return
|
||||
if (!newtarget)
|
||||
return
|
||||
|
||||
attach(newtarget)
|
||||
icon_state = "active"
|
||||
status = newstatus
|
||||
|
||||
if (STATUS_BROKEN)
|
||||
spark()
|
||||
|
||||
if (target)
|
||||
var/playflick = 1
|
||||
if (constructionstate)
|
||||
playflick = 0
|
||||
|
||||
detach(playflick)
|
||||
|
||||
icon_state = "broken"
|
||||
status = newstatus
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/setconstructionstate(var/newstate)
|
||||
constructionstate = newstate
|
||||
if (newstate == 0)
|
||||
if (status == STATUS_ACTIVE)
|
||||
icon_state = "active"
|
||||
else
|
||||
icon_state = "inactive"
|
||||
else if (newstate == 2)
|
||||
flick("deconstruct_2_anim", src)
|
||||
else if (newstate == 4)
|
||||
setstatus(STATUS_BROKEN)
|
||||
else
|
||||
icon_state = "deconstruct_[constructionstate]"
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/detach(var/playflick = 1)
|
||||
if (target)
|
||||
|
||||
if (playflick)
|
||||
spawn(-15) flick("release", src)
|
||||
|
||||
adjustsprite(null)
|
||||
layer = LAYER_NORMAL
|
||||
|
||||
target.bracer = null
|
||||
|
||||
processing_objects.Remove(src)
|
||||
|
||||
anchored = 0
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/attach(var/obj/machinery/door/airlock/newtarget as obj)
|
||||
adjustsprite(newtarget)
|
||||
layer = LAYER_ATTACHED
|
||||
flick("deploy", src)
|
||||
|
||||
newtarget.bracer = src
|
||||
target = newtarget
|
||||
|
||||
processing_objects.Add(src)
|
||||
|
||||
anchored = 1
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/adjustsprite(var/obj/target as obj)
|
||||
if (target)
|
||||
switch (get_dir(src, target))
|
||||
if (NORTH)
|
||||
pixel_x = 0
|
||||
pixel_y = 32
|
||||
if (NORTHEAST)
|
||||
pixel_x = 32
|
||||
pixel_y = 32
|
||||
if (EAST)
|
||||
pixel_x = 32
|
||||
pixel_y = 0
|
||||
if (SOUTHEAST)
|
||||
pixel_x = 32
|
||||
pixel_y = -32
|
||||
if (SOUTH)
|
||||
pixel_x = 0
|
||||
pixel_y = -32
|
||||
if (SOUTHWEST)
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
if (WEST)
|
||||
pixel_x = -32
|
||||
pixel_y = 0
|
||||
if (NORTHWEST)
|
||||
pixel_x = -32
|
||||
pixel_y = 32
|
||||
else
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/takedamage(var/damage)
|
||||
health -= damage
|
||||
|
||||
if (damage >= 40 && prob(50))
|
||||
health = 0
|
||||
|
||||
if (health <= 0)
|
||||
visible_message("<span class='danger'>[src] sparks[target ? " and falls off of \the [target]!" : "!"] It is now completely unusable!</span>")
|
||||
setstatus(STATUS_BROKEN)
|
||||
return
|
||||
|
||||
if (prob(50))
|
||||
spark()
|
||||
|
||||
/obj/item/device/magnetic_lock/proc/spark()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
|
||||
if (target)
|
||||
s.set_up(5, 1, target)
|
||||
else
|
||||
s.set_up(5, 1, src)
|
||||
|
||||
s.start()
|
||||
spawn(5)
|
||||
del(s)
|
||||
|
||||
#undef STATUS_INACTIVE
|
||||
#undef STATUS_ACTIVE
|
||||
#undef STATUS_BROKEN
|
||||
|
||||
#undef LAYER_ATTACHED
|
||||
#undef LAYER_NORMAL
|
||||
@@ -320,7 +320,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/paicard/see_emote(mob/living/M, text)
|
||||
if(pai && pai.client)
|
||||
if(pai && pai.client && !pai.canmove)
|
||||
var/rendered = "<span class='message'>[text]</span>"
|
||||
pai.show_message(rendered, 2)
|
||||
..()
|
||||
@@ -99,17 +99,9 @@
|
||||
if (src.loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.loc = get_turf(src)
|
||||
tank_one = null
|
||||
update_icon()
|
||||
remove_tank(tank_one)
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.loc = get_turf(src)
|
||||
tank_two = null
|
||||
update_icon()
|
||||
remove_tank(tank_two)
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
@@ -148,29 +140,51 @@
|
||||
if(attached_device)
|
||||
overlays += "device"
|
||||
|
||||
/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
|
||||
if(tank_one == T)
|
||||
split_gases()
|
||||
tank_one = null
|
||||
else if(tank_two == T)
|
||||
split_gases()
|
||||
tank_two = null
|
||||
else
|
||||
return
|
||||
|
||||
T.loc = get_turf(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/transfer_valve/proc/merge_gases()
|
||||
if(valve_open)
|
||||
return
|
||||
tank_two.air_contents.volume += tank_one.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_one.air_contents.remove_ratio(1)
|
||||
tank_two.air_contents.merge(temp)
|
||||
valve_open = 1
|
||||
|
||||
/obj/item/device/transfer_valve/proc/split_gases()
|
||||
if (!valve_open || !tank_one || !tank_two)
|
||||
if(!valve_open)
|
||||
return
|
||||
|
||||
valve_open = 0
|
||||
|
||||
if(deleted(tank_one) || deleted(tank_two))
|
||||
return
|
||||
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_two.air_contents.remove_ratio(ratio1)
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.volume -= tank_one.air_contents.volume
|
||||
|
||||
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
/obj/item/device/transfer_valve/proc/toggle_valve()
|
||||
if(valve_open==0 && (tank_one && tank_two))
|
||||
valve_open = 1
|
||||
if(!valve_open && (tank_one && tank_two))
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
@@ -196,15 +210,10 @@
|
||||
message_admins(log_str, 0, 1)
|
||||
log_game(log_str)
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for (var/i=0,i<5,i++)
|
||||
src.update_icon()
|
||||
sleep(10)
|
||||
src.update_icon()
|
||||
|
||||
else if(valve_open==1 && (tank_one && tank_two))
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
|
||||
src.update_icon()
|
||||
|
||||
// this doesn't do anything but the timer etc. expects it to be here
|
||||
|
||||
@@ -71,6 +71,10 @@
|
||||
icon_state = "meson"
|
||||
icon = 'icons/obj/clothing/glasses.dmi'
|
||||
|
||||
/obj/item/borg/sight/material
|
||||
name = "\proper material scanner vision"
|
||||
sight_mode = BORGMATERIAL
|
||||
|
||||
/obj/item/borg/sight/hud
|
||||
name = "hud"
|
||||
var/obj/item/clothing/glasses/hud/hud = null
|
||||
|
||||
17
code/game/objects/items/shoe_cover.dm
Normal file
17
code/game/objects/items/shoe_cover.dm
Normal file
@@ -0,0 +1,17 @@
|
||||
/obj/item/shoe_cover
|
||||
name = "strange fabric"
|
||||
desc = "A fabirc that allows for silent walking."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "sheet-cloth"
|
||||
|
||||
/obj/item/shoe_cover/afterattack(var/obj/A as obj, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if (istype(A, /obj/item/clothing/shoes) && get_dist(src,A) <= 1)
|
||||
var/obj/item/clothing/shoes/S = A
|
||||
user << "You attahed the [src] to [S] making movement silent"
|
||||
S.silent = 1
|
||||
S.desc += " They appear to have some type of fabric soles"
|
||||
user.drop_from_inventory(src)
|
||||
del(src)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user