Merge branch 'bleeding-edge-freeze' of github.com:Baystation12/Baystation12 into feature

Conflicts:
	code/game/gamemodes/events.dm
This commit is contained in:
cib
2013-01-31 11:15:32 +01:00
293 changed files with 41264 additions and 20114 deletions
+24 -9
View File
@@ -177,6 +177,7 @@
#include "code\datums\spells\ethereal_jaunt.dm"
#include "code\datums\spells\explosion.dm"
#include "code\datums\spells\genetic.dm"
#include "code\datums\spells\horsemask.dm"
#include "code\datums\spells\inflict_handler.dm"
#include "code\datums\spells\knock.dm"
#include "code\datums\spells\mind_transfer.dm"
@@ -233,6 +234,7 @@
#include "code\game\gamemodes\cult\ritual.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
#include "code\game\gamemodes\events\biomass.dm"
#include "code\game\gamemodes\events\black_hole.dm"
#include "code\game\gamemodes\events\clang.dm"
#include "code\game\gamemodes\events\dust.dm"
@@ -261,7 +263,6 @@
#include "code\game\gamemodes\wizard\rightandwrong.dm"
#include "code\game\gamemodes\wizard\soulstone.dm"
#include "code\game\gamemodes\wizard\spellbook.dm"
#include "code\game\gamemodes\wizard\spells.dm"
#include "code\game\gamemodes\wizard\veilrender.dm"
#include "code\game\gamemodes\wizard\wizard.dm"
#include "code\game\jobs\access.dm"
@@ -339,7 +340,6 @@
#include "code\game\machinery\bots\bots.dm"
#include "code\game\machinery\bots\cleanbot.dm"
#include "code\game\machinery\bots\ed209bot.dm"
#include "code\game\machinery\bots\floorbot.dm"
#include "code\game\machinery\bots\medbot.dm"
#include "code\game\machinery\bots\mulebot.dm"
#include "code\game\machinery\bots\secbot.dm"
@@ -437,7 +437,6 @@
#include "code\game\objects\weapons.dm"
#include "code\game\objects\closets\walllocker.dm"
#include "code\game\objects\effects\aliens.dm"
#include "code\game\objects\effects\biomass_rift.dm"
#include "code\game\objects\effects\bump_teleporter.dm"
#include "code\game\objects\effects\effect_system.dm"
#include "code\game\objects\effects\gibs.dm"
@@ -448,6 +447,7 @@
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\portals.dm"
#include "code\game\objects\effects\spiders.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\decals\cleanable.dm"
#include "code\game\objects\effects\decals\contraband.dm"
@@ -555,7 +555,6 @@
#include "code\game\objects\items\weapons\implants\implantchair.dm"
#include "code\game\objects\items\weapons\implants\implanter.dm"
#include "code\game\objects\items\weapons\implants\implantfreedom.dm"
#include "code\game\objects\items\weapons\implants\implantnanoaug.dm"
#include "code\game\objects\items\weapons\implants\implantpad.dm"
#include "code\game\objects\items\weapons\implants\implantuplink.dm"
#include "code\game\objects\items\weapons\melee\energy.dm"
@@ -774,12 +773,14 @@
#include "code\modules\clothing\under\jobs\security.dm"
#include "code\modules\customitems\item_defines.dm"
#include "code\modules\customitems\item_spawning.dm"
#include "code\modules\destilery\main.dm"
#include "code\modules\detectivework\detective_work.dm"
#include "code\modules\detectivework\evidence.dm"
#include "code\modules\detectivework\footprints_and_rag.dm"
#include "code\modules\detectivework\scanner.dm"
#include "code\modules\events\alien_infestation.dm"
#include "code\modules\events\blob.dm"
#include "code\modules\events\brand_intelligence.dm"
#include "code\modules\events\carp_migration.dm"
#include "code\modules\events\communications_blackout.dm"
#include "code\modules\events\disease_outbreak.dm"
@@ -790,6 +791,7 @@
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\radiation_storm.dm"
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\spontaneous_appendicitis.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
@@ -965,11 +967,8 @@
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\say.dm"
#include "code\modules\mob\living\silicon\robot\wires.dm"
#include "code\modules\mob\living\simple_animal\clown.dm"
#include "code\modules\mob\living\simple_animal\constructs.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\head.dm"
#include "code\modules\mob\living\simple_animal\kobold.dm"
#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
@@ -977,6 +976,7 @@
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
#include "code\modules\mob\living\simple_animal\friendly\corgi.dm"
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
#include "code\modules\mob\living\simple_animal\friendly\lizard.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\mushroom.dm"
@@ -987,6 +987,7 @@
#include "code\modules\mob\living\simple_animal\hostile\carp.dm"
#include "code\modules\mob\living\simple_animal\hostile\creature.dm"
#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
@@ -994,6 +995,8 @@
#include "code\modules\mob\living\simple_animal\hostile\russian.dm"
#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
#include "code\modules\mob\new_player\hud.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
@@ -1153,19 +1156,30 @@
#include "code\modules\scripting\Scanner\Tokens.dm"
#include "code\modules\security levels\keycard authentication.dm"
#include "code\modules\security levels\security levels.dm"
#include "code\modules\surgery\appendix.dm"
#include "code\modules\surgery\bones.dm"
#include "code\modules\surgery\braincore.dm"
#include "code\modules\surgery\eye.dm"
#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
#include "code\modules\surgery\other.dm"
#include "code\modules\surgery\ribcage.dm"
#include "code\modules\surgery\robolimbs.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\WorkInProgress\autopsy.dm"
#include "code\WorkInProgress\buildmode.dm"
#include "code\WorkInProgress\explosion_particles.dm"
#include "code\WorkInProgress\surgery.dm"
#include "code\WorkInProgress\Cael_Aislinn\energy_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\external_shield_gen.dm"
#include "code\WorkInProgress\Cael_Aislinn\meteor_battery.dm"
#include "code\WorkInProgress\Cael_Aislinn\sculpture.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_capacitor.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_gen.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_Events.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_TradeDestinations.dm"
#include "code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm"
#include "code\WorkInProgress\Cael_Aislinn\Jungle\falsewall.dm"
#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle.dm"
#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_animals.dm"
@@ -1191,6 +1205,7 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm"
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
@@ -1213,7 +1228,7 @@
#include "code\ZAS\ZAS_Zones.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
#include "maps\tgstation.2.1.0.dmm"
#include "maps\tgstation.2.1.0.0.1.dmm"
#include "maps\RandomZLevels\Academy.dm"
#include "maps\RandomZLevels\challenge.dm"
#include "maps\RandomZLevels\stationCollision.dm"
+3
View File
@@ -62,6 +62,9 @@ datum/air_group
proc/check_regroup()
//Purpose: Checks to see if group processing should be turned back on
//Returns: group_processing
if(prevent_airgroup_regroup)
return 0
if(group_processing) return 1
var/turf/simulated/sample = pick(members)
+6 -3
View File
@@ -45,7 +45,6 @@
return igniting
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = 1
@@ -98,12 +97,15 @@
var/turf/simulated/floor/location = loc
if(!istype(location))
Kill()
return
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
Kill()
return
if(location.air.toxins < 0.5 || location.air.oxygen < 0.5)
Kill()
return
perform_exposure()
@@ -130,7 +132,7 @@
if(temperature > location.max_fire_temperature_sustained)
location.max_fire_temperature_sustained = temperature
if(temperature > location.heat_capacity)
if(location.heat_capacity && temperature > location.heat_capacity)
location.to_be_destroyed = 1
/*if(prob(25))
location.ReplaceWithSpace()
@@ -168,8 +170,9 @@
dir = pick(cardinal)
return
/*
/obj/effect/hotspot/Del()
if (istype(loc, /turf/simulated))
DestroyTurf()
..()
return
*/
+3 -4
View File
@@ -23,11 +23,10 @@ What are the archived variables for?
volatile_fuel
specific_heat = 30
var
moles = 0
specific_heat = 0
var/moles = 0
var/specific_heat = 0
moles_archived = 0
var/moles_archived = 0
/datum/gas_mixture
+429 -445
View File
@@ -1,6 +1,6 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
atom/movable/var/pressure_resistance = 20
atom/movable/var/pressure_resistance = 5
atom/movable/var/last_forced_movement = 0
atom/movable/proc/experience_pressure_difference(pressure_difference, direction)
@@ -47,530 +47,514 @@ turf
turf
var/pressure_difference = 0
var/pressure_direction = 0
var/reporting_pressure_difference
//optimization vars
var/next_check = 0 //number of ticks before this tile updates
var/check_delay = 0 //number of ticks between updates
proc
high_pressure_movements()
proc/high_pressure_movements()
if(reporting_pressure_difference)
world << "pressure_difference = [pressure_difference]; pressure_direction = [pressure_direction]"
for(var/atom/movable/in_tile in src)
in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
for(var/atom/movable/in_tile in src)
in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
pressure_difference = 0
pressure_difference = 0
proc/consider_pressure_difference(connection_difference, connection_direction)
if(connection_difference < 0)
connection_difference = -connection_difference
connection_direction = turn(connection_direction,180)
consider_pressure_difference(connection_difference, connection_direction)
if(connection_difference < 0)
connection_difference = -connection_difference
connection_direction = turn(connection_direction,180)
if(connection_difference > pressure_difference)
if(!pressure_difference)
air_master.high_pressure_delta += src
pressure_difference = connection_difference
pressure_direction = connection_direction
if(connection_difference > pressure_difference)
turf/simulated/proc/consider_pressure_difference_space(connection_difference)
for(var/direction in cardinal)
if(direction&group_border)
if(istype(get_step(src,direction),/turf/space))
if(!pressure_difference)
air_master.high_pressure_delta += src
pressure_direction = direction
pressure_difference = connection_difference
pressure_direction = connection_direction
simulated
proc
consider_pressure_difference_space(connection_difference)
for(var/direction in cardinal)
if(direction&group_border)
if(istype(get_step(src,direction),/turf/space))
if(!pressure_difference)
air_master.high_pressure_delta += src
pressure_direction = direction
pressure_difference = connection_difference
return 1
return 1
turf
simulated
turf/simulated
var/current_graphic = null
var/current_graphic = null
var/tmp/datum/gas_mixture/air
var/tmp/datum/gas_mixture/air
var/tmp/processing = 1
var/tmp/datum/air_group/turf/parent
var/tmp/group_border = 0
var/tmp/length_space_border = 0
var/tmp/processing = 1
var/tmp/datum/air_group/turf/parent
var/tmp/group_border = 0
var/tmp/length_space_border = 0
var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
var/tmp/archived_cycle = 0
var/tmp/current_cycle = 0
var/tmp/archived_cycle = 0
var/tmp/current_cycle = 0
var/tmp/obj/effect/hotspot/active_hotspot
var/tmp/obj/effect/hotspot/active_hotspot
var/tmp/temperature_archived //USED ONLY FOR SOLIDS
var/tmp/being_superconductive = 0
var/tmp/temperature_archived //USED ONLY FOR SOLIDS
var/tmp/being_superconductive = 0
proc/update_visuals(datum/gas_mixture/model)
overlays.Cut()
proc
process_cell()
update_air_properties()
archive()
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('icons/turf/floors.dmi',siding_icon_state)
mimic_air_with_tile(turf/model)
share_air_with_tile(turf/simulated/sharer)
mimic_temperature_with_tile(turf/model)
share_temperature_with_tile(turf/simulated/sharer)
super_conduct()
update_visuals(datum/gas_mixture/model)
overlays.Cut()
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('icons/turf/floors.dmi',siding_icon_state)
switch(model.graphic)
if("plasma")
overlays.Add(plmaster)
if("sleeping_agent")
overlays.Add(slmaster)
switch(model.graphic)
if("plasma")
overlays.Add(plmaster)
if("sleeping_agent")
overlays.Add(slmaster)
New()
..()
New()
..()
if(!blocks_air)
air = new
if(!blocks_air)
air = new
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.temperature = temperature
air.temperature = temperature
if(air_master)
air_master.tiles_to_update.Add(src)
if(air_master)
air_master.tiles_to_update.Add(src)
find_group()
find_group()
// air.parent = src //TODO DEBUG REMOVE
else
if(air_master)
for(var/direction in cardinal)
var/turf/simulated/floor/target = get_step(src,direction)
if(istype(target))
air_master.tiles_to_update.Add(target)
Del()
else
if(air_master)
if(parent)
air_master.groups_to_rebuild.Add(parent)
parent.members.Remove(src)
else
air_master.active_singletons.Remove(src)
if(active_hotspot)
del(active_hotspot)
if(blocks_air)
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
var/turf/simulated/tile = get_step(src,direction)
if(istype(tile) && !tile.blocks_air)
air_master.tiles_to_update.Add(tile)
..()
assume_air(datum/gas_mixture/giver)
if(!giver) return 0
var/datum/gas_mixture/receiver = air
if(istype(receiver))
if(parent&&parent.group_processing)
if(!parent.air.check_then_merge(giver))
parent.suspend_group_processing()
air.merge(giver)
else
if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
reset_delay()
air.merge(giver)
if(!processing)
if(air.check_tile_graphic())
update_visuals(air)
return 1
else return ..()
archive()
if(air) //For open space like floors
air.archive()
temperature_archived = temperature
archived_cycle = air_master.current_cycle
share_air_with_tile(turf/simulated/T)
return air.share(T.air)
mimic_air_with_tile(turf/T)
return air.mimic(T)
return_air()
if(air)
if(parent&&parent.group_processing)
return parent.air
else return air
else
return ..()
remove_air(amount as num)
if(air)
var/datum/gas_mixture/removed = null
if(parent&&parent.group_processing)
removed = parent.air.check_then_remove(amount)
if(!removed)
parent.suspend_group_processing()
removed = air.remove(amount)
else
removed = air.remove(amount)
if(!processing)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..()
update_air_properties()//OPTIMIZE
air_check_directions = 0
for(var/direction in cardinal)
if(CanPass(null, get_step(src,direction), 0, 0))
air_check_directions |= direction
for(var/direction in cardinal)
var/turf/simulated/floor/target = get_step(src,direction)
if(istype(target))
air_master.tiles_to_update.Add(target)
Del()
if(air_master)
if(parent)
if(parent.borders)
parent.borders -= src
if(length_space_border > 0)
parent.length_space_border -= length_space_border
length_space_border = 0
group_border = 0
for(var/direction in cardinal)
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
//See if actually a border
if(!istype(T) || (T.parent!=parent))
//See what kind of border it is
if(istype(T,/turf/space))
if(parent.space_borders)
parent.space_borders -= src
parent.space_borders += src
else
parent.space_borders = list(src)
length_space_border++
else
if(parent.borders)
parent.borders -= src
parent.borders += src
else
parent.borders = list(src)
group_border |= direction
parent.length_space_border += length_space_border
if(air_check_directions)
processing = 1
if(!parent)
air_master.add_singleton(src)
air_master.groups_to_rebuild.Add(parent)
parent.members.Remove(src)
else
processing = 0
air_master.active_singletons.Remove(src)
if(active_hotspot)
active_hotspot.Kill()
if(blocks_air)
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
var/turf/simulated/tile = get_step(src,direction)
if(istype(tile) && !tile.blocks_air)
air_master.tiles_to_update.Add(tile)
..()
process_cell()
//this proc does all the heavy lifting for individual tile processing
//it shares with all of its neighbors, spreads fire, calls superconduction
//and doesn't afraid of anything
//check if we're skipping this tick
if (next_check > 0)
next_check--
return 1
var/player_count = max(player_list.len, 3) / 3
next_check += check_delay + rand(player_count, player_count * 1.5)
check_delay++
var/turf/simulated/list/possible_fire_spreads = list()
if(processing)
if(archived_cycle < air_master.current_cycle) //archive self if not already done
archive()
current_cycle = air_master.current_cycle
for(var/direction in cardinal)
if(air_check_directions&direction) //Grab all valid bordering tiles
var/turf/simulated/enemy_tile = get_step(src, direction)
var/connection_difference = 0
if(istype(enemy_tile)) //enemy_tile == neighbor, btw
if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
enemy_tile.archive()
if (air && enemy_tile.air)
var/delay_trigger = air.compare(enemy_tile.air)
if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
reset_delay()
enemy_tile.reset_delay()
if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
if(enemy_tile.parent.air.check_gas_mixture(air))
connection_difference = air.share(enemy_tile.parent.air)
else
enemy_tile.parent.suspend_group_processing()
connection_difference = air.share(enemy_tile.air)
//group processing failed so interact with individual tile
else
if(enemy_tile.current_cycle < current_cycle)
connection_difference = air.share(enemy_tile.air)
if(active_hotspot)
possible_fire_spreads += enemy_tile
else
/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
if(movable_on_enemy)
if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
if(movable_on_enemy.parent.current_cycle < current_cycle)
if(movable_on_enemy.parent.air.check_gas_mixture(air))
connection_difference = air.share(movable_on_enemy.parent.air)
else
movable_on_enemy.parent.suspend_group_processing()
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
movable_on_enemy.archive()
connection_difference = air.share(movable_on_enemy.air)
//group processing failed so interact with individual tile
else
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
movable_on_enemy.archive()
if(movable_on_enemy.current_cycle < current_cycle)
connection_difference = share_air_with_tile(movable_on_enemy)
else*/
connection_difference = mimic_air_with_tile(enemy_tile)
//bordering a tile with fixed air properties
if(connection_difference)
if(connection_difference > 0)
consider_pressure_difference(connection_difference, direction)
else
enemy_tile.consider_pressure_difference(connection_difference, direction)
assume_air(datum/gas_mixture/giver)
if(!giver) return 0
var/datum/gas_mixture/receiver = air
if(istype(receiver))
if(parent&&parent.group_processing)
if(!parent.air.check_then_merge(giver))
parent.suspend_group_processing()
air.merge(giver)
else
air_master.active_singletons -= src //not active if not processing!
if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
reset_delay()
air.react()
air.merge(giver)
if(active_hotspot)
if (!active_hotspot.process(possible_fire_spreads))
return 0
if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
consider_superconductivity(starting = 1)
if(air.check_tile_graphic())
update_visuals(air)
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
reset_delay() //hotspots always process quickly
hotspot_expose(air.temperature, CELL_VOLUME)
for(var/atom/movable/item in src)
item.temperature_expose(air, air.temperature, CELL_VOLUME)
temperature_expose(air, air.temperature, CELL_VOLUME)
if(!processing)
if(air.check_tile_graphic())
update_visuals(air)
return 1
super_conduct()
var/conductivity_directions = 0
if(blocks_air)
//Does not participate in air exchange, so will conduct heat across all four borders at this time
conductivity_directions = NORTH|SOUTH|EAST|WEST
else return ..()
if(archived_cycle < air_master.current_cycle)
archive()
proc/archive()
if(air) //For open space like floors
air.archive()
temperature_archived = temperature
archived_cycle = air_master.current_cycle
proc/share_air_with_tile(turf/simulated/T)
return air.share(T.air)
proc/mimic_air_with_tile(turf/T)
return air.mimic(T)
return_air()
if(air)
if(parent&&parent.group_processing)
return parent.air
else return air
else
return ..()
remove_air(amount as num)
if(air)
var/datum/gas_mixture/removed = null
if(parent&&parent.group_processing)
removed = parent.air.check_then_remove(amount)
if(!removed)
parent.suspend_group_processing()
removed = air.remove(amount)
else
//Does particate in air exchange so only consider directions not considered during process_cell()
conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
removed = air.remove(amount)
if(conductivity_directions>0)
//Conduct with tiles around me
for(var/direction in cardinal)
if(conductivity_directions&direction)
var/turf/neighbor = get_step(src,direction)
if(!processing)
if(air.check_tile_graphic())
update_visuals(air)
if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
var/turf/simulated/modeled_neighbor = neighbor
return removed
if(modeled_neighbor.archived_cycle < air_master.current_cycle)
modeled_neighbor.archive()
else
return ..()
if(modeled_neighbor.air)
if(air) //Both tiles are open
proc/update_air_properties()//OPTIMIZE
air_check_directions = 0
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
if(parent && parent.group_processing)
//both are acting as a group
//modified using construct developed in datum/air_group/share_air_with_group(...)
for(var/direction in cardinal)
if(CanPass(null, get_step(src,direction), 0, 0))
air_check_directions |= direction
var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
if(result==0)
//have to deconstruct parent air group
if(parent)
if(parent.borders)
parent.borders -= src
if(length_space_border > 0)
parent.length_space_border -= length_space_border
length_space_border = 0
parent.suspend_group_processing()
if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
//may have to deconstruct neighbors air group
group_border = 0
for(var/direction in cardinal)
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
modeled_neighbor.parent.suspend_group_processing()
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else if(result==-1)
// have to deconstruct neightbors air group but not mine
modeled_neighbor.parent.suspend_group_processing()
parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
//may have to deconstruct neighbors air group
parent.suspend_group_processing()
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
// world << "OPEN, OPEN"
else //Solid but neighbor is open
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
modeled_neighbor.parent.suspend_group_processing()
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
else
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
// world << "SOLID, OPEN"
//See if actually a border
if(!istype(T) || (T.parent!=parent))
//See what kind of border it is
if(istype(T,/turf/space))
if(parent.space_borders)
parent.space_borders -= src
parent.space_borders += src
else
if(air) //Open but neighbor is solid
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
parent.suspend_group_processing()
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
else
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
// world << "OPEN, SOLID"
else //Both tiles are solid
share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
// world << "SOLID, SOLID"
modeled_neighbor.consider_superconductivity()
parent.space_borders = list(src)
length_space_border++
else
if(air) //Open
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
parent.suspend_group_processing()
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
else
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
if(parent.borders)
parent.borders -= src
parent.borders += src
else
mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
parent.borders = list(src)
//Radiate excess tile heat to space
if(temperature > T0C)
// Is there a pre-defined Space Tile?
if(!Space_Tile)
Space_Tile = locate(/turf/space) // Define one
//Considering 0 degC as te break even point for radiation in and out
mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
group_border |= direction
//Conduct with air on my tile if I have it
if(air)
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
parent.suspend_group_processing()
air.temperature_turf_share(src, thermal_conductivity)
else
air.temperature_turf_share(src, thermal_conductivity)
parent.length_space_border += length_space_border
if(air_check_directions)
processing = 1
if(!parent)
air_master.add_singleton(src)
else
processing = 0
//Make sure still hot enough to continue conducting heat
if(air)
if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
being_superconductive = 0
air_master.active_super_conductivity -= src
return 0
proc/process_cell()
//this proc does all the heavy lifting for individual tile processing
//it shares with all of its neighbors, spreads fire, calls superconduction
//and doesn't afraid of anything
//Comment by errorage: In other words, this is the proc that lags the game.
else
if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
being_superconductive = 0
air_master.active_super_conductivity -= src
return 0
//check if we're skipping this tick
if (next_check > 0)
next_check--
return 1
var/player_count = max(player_list.len, 3) / 3
next_check += check_delay + rand(player_count, player_count * 1.5)
check_delay++
proc/mimic_temperature_solid(turf/model, conduction_coefficient)
var/delta_temperature = (temperature_archived - model.temperature)
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/turf/simulated/list/possible_fire_spreads = list()
if(processing)
if(archived_cycle < air_master.current_cycle) //archive self if not already done
archive()
current_cycle = air_master.current_cycle
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
temperature -= heat/heat_capacity
for(var/direction in cardinal)
if(air_check_directions&direction) //Grab all valid bordering tiles
var/turf/simulated/enemy_tile = get_step(src, direction)
var/connection_difference = 0
proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
if(istype(enemy_tile)) //enemy_tile == neighbor, btw
if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
enemy_tile.archive()
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
if (air && enemy_tile.air)
var/delay_trigger = air.compare(enemy_tile.air)
if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
reset_delay()
enemy_tile.reset_delay()
temperature -= heat/heat_capacity
sharer.temperature += heat/sharer.heat_capacity
if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
if(enemy_tile.parent.air.check_gas_mixture(air))
connection_difference = air.share(enemy_tile.parent.air)
else
enemy_tile.parent.suspend_group_processing()
connection_difference = air.share(enemy_tile.air)
//group processing failed so interact with individual tile
proc/consider_superconductivity(starting)
else
if(enemy_tile.current_cycle < current_cycle)
connection_difference = air.share(enemy_tile.air)
if(being_superconductive || !thermal_conductivity)
if(active_hotspot)
possible_fire_spreads += enemy_tile
else
/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
if(movable_on_enemy)
if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
if(movable_on_enemy.parent.current_cycle < current_cycle)
if(movable_on_enemy.parent.air.check_gas_mixture(air))
connection_difference = air.share(movable_on_enemy.parent.air)
else
movable_on_enemy.parent.suspend_group_processing()
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
movable_on_enemy.archive()
connection_difference = air.share(movable_on_enemy.air)
//group processing failed so interact with individual tile
else
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
movable_on_enemy.archive()
if(movable_on_enemy.current_cycle < current_cycle)
connection_difference = share_air_with_tile(movable_on_enemy)
else*/
connection_difference = mimic_air_with_tile(enemy_tile)
//bordering a tile with fixed air properties
if(connection_difference)
if(connection_difference > 0)
consider_pressure_difference(connection_difference, direction)
else
enemy_tile.consider_pressure_difference(connection_difference, direction)
else
air_master.active_singletons -= src //not active if not processing!
air.react()
if(active_hotspot)
if (!active_hotspot.process(possible_fire_spreads))
return 0
if(air)
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
return 0
if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
consider_superconductivity(starting = 1)
if(air.check_tile_graphic())
update_visuals(air)
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
reset_delay() //hotspots always process quickly
hotspot_expose(air.temperature, CELL_VOLUME)
for(var/atom/movable/item in src)
item.temperature_expose(air, air.temperature, CELL_VOLUME)
temperature_expose(air, air.temperature, CELL_VOLUME)
return 1
proc/super_conduct()
var/conductivity_directions = 0
if(blocks_air)
//Does not participate in air exchange, so will conduct heat across all four borders at this time
conductivity_directions = NORTH|SOUTH|EAST|WEST
if(archived_cycle < air_master.current_cycle)
archive()
else
//Does particate in air exchange so only consider directions not considered during process_cell()
conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
if(conductivity_directions>0)
//Conduct with tiles around me
for(var/direction in cardinal)
if(conductivity_directions&direction)
var/turf/neighbor = get_step(src,direction)
if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
var/turf/simulated/modeled_neighbor = neighbor
if(modeled_neighbor.archived_cycle < air_master.current_cycle)
modeled_neighbor.archive()
if(modeled_neighbor.air)
if(air) //Both tiles are open
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
if(parent && parent.group_processing)
//both are acting as a group
//modified using construct developed in datum/air_group/share_air_with_group(...)
var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
if(result==0)
//have to deconstruct parent air group
parent.suspend_group_processing()
if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
//may have to deconstruct neighbors air group
modeled_neighbor.parent.suspend_group_processing()
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else if(result==-1)
// have to deconstruct neightbors air group but not mine
modeled_neighbor.parent.suspend_group_processing()
parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
//may have to deconstruct neighbors air group
parent.suspend_group_processing()
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
// world << "OPEN, OPEN"
else //Solid but neighbor is open
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
modeled_neighbor.parent.suspend_group_processing()
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
else
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
// world << "SOLID, OPEN"
else
if(air) //Open but neighbor is solid
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
parent.suspend_group_processing()
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
else
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
// world << "OPEN, SOLID"
else //Both tiles are solid
share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
// world << "SOLID, SOLID"
modeled_neighbor.consider_superconductivity()
else
if(air) //Open
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
parent.suspend_group_processing()
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
else
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
else
mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
//Radiate excess tile heat to space
if(temperature > T0C)
// Is there a pre-defined Space Tile?
if(!Space_Tile)
Space_Tile = locate(/turf/space) // Define one
//Considering 0 degC as te break even point for radiation in and out
mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
//Conduct with air on my tile if I have it
if(air)
if(parent && parent.group_processing)
if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
parent.suspend_group_processing()
air.temperature_turf_share(src, thermal_conductivity)
else
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
air.temperature_turf_share(src, thermal_conductivity)
being_superconductive = 1
air_master.active_super_conductivity += src
//Make sure still hot enough to continue conducting heat
if(air)
if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
being_superconductive = 0
air_master.active_super_conductivity -= src
return 0
proc/reset_delay()
//sets this turf to process quickly again
next_check=0
check_delay= -5 //negative numbers mean a mandatory quick-update period
else
if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
being_superconductive = 0
air_master.active_super_conductivity -= src
return 0
//if this turf has a parent air group, suspend its processing
if (parent && parent.group_processing)
parent.suspend_group_processing()
proc/mimic_temperature_solid(turf/model, conduction_coefficient)
var/delta_temperature = (temperature_archived - model.temperature)
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
temperature -= heat/heat_capacity
proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
temperature -= heat/heat_capacity
sharer.temperature += heat/sharer.heat_capacity
proc/consider_superconductivity(starting)
if(being_superconductive || !thermal_conductivity)
return 0
if(air)
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
return 0
else
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
being_superconductive = 1
air_master.active_super_conductivity += src
proc/reset_delay()
//sets this turf to process quickly again
next_check=0
check_delay= -5 //negative numbers mean a mandatory quick-update period
//if this turf has a parent air group, suspend its processing
if (parent && parent.group_processing)
parent.suspend_group_processing()
@@ -0,0 +1,298 @@
var/global/current_date_string
var/global/num_financial_terminals = 1
var/global/datum/money_account/station_account
var/global/next_account_number = 0
/proc/create_station_account()
if(!station_account)
next_account_number = rand(111111, 999999)
station_account = new()
station_account.owner_name = "[station_name()] Station Account"
station_account.account_number = rand(111111, 999999)
station_account.remote_access_pin = rand(1111, 111111)
station_account.money = 10000
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = station_account.owner_name
T.purpose = "Account creation"
T.amount = 10000
T.date = "2nd April, 2555"
T.time = "11:24"
T.source_terminal = "Biesel GalaxyNet Terminal #277"
//add the account
station_account.transaction_log.Add(T)
for(var/obj/machinery/account_database/A in world)
A.accounts.Add(station_account)
//the current ingame time (hh:mm) can be obtained by calling:
//worldtime2text()
/datum/money_account
var/owner_name = ""
var/account_number = 0
var/remote_access_pin = 0
var/money = 0
var/list/transaction_log = list()
var/security_level = 1 //0 - auto-identify from worn ID, require only account number
//1 - require manual login / account number and pin
//2 - require card and manual login
/datum/transaction
var/target_name = ""
var/purpose = ""
var/amount = 0
var/date = ""
var/time = ""
var/source_terminal = ""
/obj/machinery/account_database
name = "Accounts database"
desc = "Holds transaction logs, account data and all kinds of other financial records."
icon = 'virology.dmi'
icon_state = "analyser"
density = 1
var/list/accounts = list()
req_one_access = list(access_hop, access_captain)
var/receipt_num
var/machine_id = ""
var/obj/item/weapon/card/id/held_card
var/access_level = 0
var/datum/money_account/detailed_account_view
var/creating_new_account = 0
/obj/machinery/account_database/New()
..()
if(!station_account)
create_station_account()
if(!current_date_string)
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
/obj/machinery/account_database/attack_hand(mob/user as mob)
if(get_dist(src,user) <= 1)
var/dat = "<b>Accounts Database</b><br>"
dat += "<i>[machine_id]</i><br>"
dat += "Confirm identity: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"
if(access_level > 0)
dat += "You may not edit accounts at this terminal, only create and view them.<br>"
if(creating_new_account)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a>"
dat += "<form name='create_account' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='finalise_create_account'>"
dat += "<b>Holder name:</b> <input type='text' id='holder_name' name='holder_name' style='width:250px; background-color:white;'><br>"
dat += "<b>Initial funds:</b> <input type='text' id='starting_funds' name='starting_funds' style='width:250px; background-color:white;'> (subtracted from station account)<br>"
dat += "<i>New accounts are automatically assigned a secret number and pin, which are printed separately in a sealed package.</i><br>"
dat += "<input type='submit' value='Create'><br>"
dat += "</form>"
else
if(detailed_account_view)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a><hr>"
dat += "<b>Account number:</b> #[detailed_account_view.account_number]<br>"
dat += "<b>Account holder:</b> [detailed_account_view.owner_name]<br>"
dat += "<b>Account balance:</b> $[detailed_account_view.money]<br>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in detailed_account_view.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
else
dat += "<a href='?src=\ref[src];choice=create_account;'>Create new account</a> <a href='?src=\ref[src];choice=sync_accounts;'>Sync accounts across databases</a><br><br>"
dat += "<table border=1 style='width:100%'>"
for(var/i=1, i<=accounts.len, i++)
var/datum/money_account/D = accounts[i]
dat += "<tr>"
dat += "<td>#[D.account_number]</td>"
dat += "<td>[D.owner_name]</td>"
dat += "<td><a href='?src=\ref[src];choice=view_account_detail;account_index=[i]'>View in detail</a></td>"
dat += "</tr>"
dat += "</table>"
user << browse(dat,"window=account_db;size=700x650")
else
user << browse(null,"window=account_db")
/obj/machinery/account_database/attackby(O as obj, user as mob)//TODO:SANITY
if(istype(O, /obj/item/weapon/card))
var/obj/item/weapon/card/id/idcard = O
if(!held_card)
usr.drop_item()
idcard.loc = src
held_card = idcard
if(access_cent_captain in idcard.access)
access_level = 2
else if(access_hop in idcard.access || access_captain in idcard.access)
access_level = 1
else
..()
/obj/machinery/account_database/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("sync_accounts")
for(var/obj/machinery/account_database/A in world)
for(var/datum/money_account/M in src.accounts)
if(!A.accounts.Find(M))
A.accounts.Add(M)
usr << "\icon[src] <span class='info'>Accounts synched across all databases in range.</span>"
if("create_account")
creating_new_account = 1
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
add_account(account_name, starting_funds)
if(starting_funds > 0)
//subtract the money
station_account.money -= starting_funds
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = account_name
T.purpose = "New account funds initialisation"
T.amount = "([starting_funds])"
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = machine_id
station_account.transaction_log.Add(T)
creating_new_account = 0
if("insert_card")
if(held_card)
held_card.loc = src.loc
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
access_level = 0
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = I
usr.drop_item()
C.loc = src
held_card = C
if(access_cent_captain in C.access)
access_level = 2
else if(access_hop in C.access || access_captain in C.access)
access_level = 1
if("view_account_detail")
var/index = text2num(href_list["account_index"])
if(index && index <= accounts.len)
detailed_account_view = accounts[index]
if("view_accounts_list")
detailed_account_view = null
creating_new_account = 0
src.attack_hand(usr)
/obj/machinery/account_database/proc/add_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/pre_existing = 0)
//create a new account
var/datum/money_account/M = new()
M.owner_name = new_owner_name
M.remote_access_pin = rand(1111, 111111)
M.money = starting_funds
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = new_owner_name
T.purpose = "Account creation"
T.amount = starting_funds
if(pre_existing)
//set a random date, time and location some time over the past few decades
T.date = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 25[rand(10,56)]"
T.time = "[rand(0,24)]:[rand(11,59)]"
T.source_terminal = "NTGalaxyNet Terminal #[rand(111,1111)]"
M.account_number = rand(111111, 999999)
else
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = machine_id
M.account_number = next_account_number
next_account_number += rand(1,25)
//create a sealed package containing the account details
var/obj/item/smallDelivery/P = new(src.loc)
var/obj/item/weapon/paper/R = new(P)
P.wrapped = R
R.name = "Account information: [M.owner_name]"
R.info = "<b>Account details (confidential)</b><br><hr><br>"
R.info += "<i>Account holder:</i> [M.owner_name]<br>"
R.info += "<i>Account number:</i> [M.account_number]<br>"
R.info += "<i>Account pin:</i> [M.remote_access_pin]<br>"
R.info += "<i>Starting balance:</i> $[M.money]<br>"
R.info += "<i>Date and time:</i> [worldtime2text()], [current_date_string]<br><br>"
R.info += "<i>Creation terminal ID:</i> [machine_id]<br>"
R.info += "<i>Authorised NT officer overseeing creation:</i> [held_card.registered_name]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the Accounts Database.</i>"
//add the account
M.transaction_log.Add(T)
accounts.Add(M)
/obj/machinery/account_database/proc/charge_to_account(var/attempt_account_number, var/source_name, var/purpose, var/terminal_id, var/amount)
for(var/datum/money_account/D in accounts)
if(D.account_number == attempt_account_number)
D.money += amount
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = source_name
T.purpose = purpose
if(amount < 0)
T.amount = "([amount])"
else
T.amount = "[amount]"
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = terminal_id
D.transaction_log.Add(T)
return 1
return 0
//this returns the first account datum that matches the supplied accnum/pin combination, it returns null if the combination did not match any account
/obj/machinery/account_database/proc/attempt_account_access(var/attempt_account_number, var/attempt_pin_number, var/security_level_passed = 0)
for(var/datum/money_account/D in accounts)
if(D.account_number == attempt_account_number)
if( D.security_level <= security_level_passed && (!D.security_level || D.remote_access_pin == attempt_pin_number) )
return D
@@ -0,0 +1,177 @@
/obj/item/weapon/eftpos
name = "EFTPOS scanner"
desc = "Swipe your ID card to pay electronically."
icon = 'icons/obj/library.dmi'
icon_state = "scanner"
var/machine_id = ""
var/eftpos_name = "Default EFTPOS scanner"
var/transaction_locked = 0
var/transaction_paid = 0
var/transaction_amount = 0
var/transaction_purpose = "Default charge"
var/access_code = 0
var/obj/machinery/account_database/linked_db
var/datum/money_account/linked_account
/obj/item/weapon/eftpos/New()
..()
machine_id = "[station_name()] EFTPOS #[num_financial_terminals++]"
access_code = rand(1111,111111)
reconnect_database()
print_reference()
//by default, connect to the station account
//the user of the EFTPOS device can change the target account though, and no-one will be the wiser (except whoever's being charged)
linked_account = station_account
/obj/item/weapon/eftpos/proc/print_reference()
var/obj/item/weapon/paper/R = new(get_turf(src))
R.name = "Reference: [eftpos_name]"
R.info = "<b>[eftpos_name] reference</b><br><br>"
R.info += "Access code: [access_code]<br><br>"
R.info += "<b>Do not lose this code, or the device will have to be replaced.</b><br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the EFTPOS device.</i>"
/obj/item/weapon/eftpos/proc/reconnect_database()
for(var/obj/machinery/account_database/DB in world)
if(DB.z == src.z)
linked_db = DB
break
/obj/item/weapon/eftpos/attack_self(mob/user as mob)
if(get_dist(src,user) <= 1)
var/dat = "<b>[eftpos_name]</b><br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br>"
if(transaction_locked)
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Reset[transaction_paid ? "" : " (authentication required)"]</a><br><br>"
dat += "Transaction purpose: <b>[transaction_purpose]</b><br>"
dat += "Value: <b>$[transaction_amount]</b><br>"
dat += "Linked account: <b>[linked_account ? linked_account.owner_name : "None"]</b><hr>"
if(transaction_paid)
dat += "<i>This transaction has been processed successfully.</i><hr>"
else
dat += "<i>Swipe your card below the line to finish this transaction.</i><hr>"
dat += "<a href='?src=\ref[src];choice=scan_card'>\[------\]</a>"
else
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Lock in new transaction</a><br><br>"
dat += "Transaction purpose: <a href='?src=\ref[src];choice=trans_purpose'>[transaction_purpose]</a><br>"
dat += "Value: <a href='?src=\ref[src];choice=trans_value'>$[transaction_amount]</a><br>"
dat += "Linked account: <a href='?src=\ref[src];choice=link_account'>[linked_account ? linked_account.owner_name : "None"]</a><hr>"
dat += "<a href='?src=\ref[src];choice=change_code'>Change access code</a>"
user << browse(dat,"window=eftpos")
else
user << browse(null,"window=eftpos")
/obj/item/weapon/eftpos/attackby(O as obj, user as mob)
if(istype(O, /obj/item/weapon/card))
//attempt to connect to a new db, and if that doesn't work then fail
if(!linked_db)
reconnect_database()
if(linked_db && linked_account)
var/obj/item/weapon/card/I = O
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to connect to accounts database.</span>"
else
..()
/obj/item/weapon/eftpos/Topic(var/href, var/href_list)
if(href_list["choice"])
switch(href_list["choice"])
if("change_code")
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code"))
if(attempt_code == access_code)
access_code = text2num(input("Enter a new access code for this device", "Enter new EFTPOS code"))
print_reference()
else
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
if("link_account")
if(linked_db)
var/attempt_account_num = text2num(input("Enter account number to pay EFTPOS charges into", "New account number"))
var/attempt_pin = text2num(input("Enter pin code", "Account pin"))
linked_account = linked_db.attempt_account_access(attempt_account_num, attempt_pin, 1)
else
usr << "<span class='warning'>Unable to connect to accounts database.</span>"
if("trans_purpose")
transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
if("trans_value")
transaction_amount = max(text2num(input("Enter amount for EFTPOS transaction", "Transaction amount")),0)
if("toggle_lock")
if(transaction_locked)
var/attempt_code = text2num(input("Enter EFTPOS access code", "Reset Transaction"))
if(attempt_code == access_code)
transaction_locked = 0
transaction_paid = 0
else if(linked_account)
transaction_locked = 1
else
usr << "\icon[src] <span class='warning'>No account connected to send transactions to.</span>"
if("scan_card")
//attempt to connect to a new db, and if that doesn't work then fail
if(!linked_db)
reconnect_database()
if(linked_db && linked_account)
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card))
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to link accounts.</span>"
src.attack_self(usr)
/obj/item/weapon/eftpos/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>")
if(transaction_locked && !transaction_paid)
if(linked_account)
var/attempt_pin = text2num(input("Enter pin code", "EFTPOS transaction"))
var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2)
if(D)
if(transaction_amount <= D.money)
playsound(src, 'chime.ogg', 50, 1)
src.visible_message("\icon[src] The [src] chimes.")
transaction_paid = 1
//transfer the money
D.money -= transaction_amount
linked_account.money += transaction_amount
//create entries in the two account transaction logs
var/datum/transaction/T = new()
T.target_name = "[linked_account.owner_name] ([eftpos_name])"
T.purpose = transaction_purpose
T.amount = "([transaction_amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
D.transaction_log.Add(T)
//
T = new()
T.target_name = D.owner_name
T.purpose = transaction_purpose
T.amount = "[transaction_amount]"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
linked_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>You don't have that much money!<span>"
else
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.<span>"
else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
else
..()
//emag?
+332 -53
View File
@@ -7,6 +7,11 @@ log transactions
*/
#define NO_SCREEN 0
#define CHANGE_SECURITY_LEVEL 1
#define TRANSFER_FUNDS 2
#define VIEW_TRANSACTION_LOGS 3
/obj/item/weapon/card/id/var/money = 2000
/obj/machinery/atm
@@ -17,72 +22,346 @@ log transactions
anchored = 1
use_power = 1
idle_power_usage = 10
var/obj/machinery/account_database/linked_db
var/datum/money_account/authenticated_account
var/number_incorrect_tries = 0
var/previous_account_number = 0
var/max_pin_attempts = 3
var/ticks_left_locked_down = 0
var/ticks_left_timeout = 0
var/machine_id = ""
var/obj/item/weapon/card/held_card
var/editing_security_level = 0
var/view_screen = NO_SCREEN
/obj/machinery/atm/New()
..()
reconnect_database()
machine_id = "[station_name()] RT #[num_financial_terminals++]"
/obj/machinery/atm/process()
if(ticks_left_timeout > 0)
ticks_left_timeout--
if(ticks_left_timeout <= 0)
authenticated_account = null
if(ticks_left_locked_down > 0)
ticks_left_locked_down--
for(var/obj/item/weapon/spacecash/S in src)
S.loc = src.loc
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
break
/obj/machinery/atm/proc/reconnect_database()
for(var/obj/machinery/account_database/DB in world)
if(DB.z == src.z)
linked_db = DB
break
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
if(ishuman(user))
var/obj/item/weapon/card/id/user_id = src.scan_user(user)
if(istype(I, /obj/item/weapon/card))
var/obj/item/weapon/card/id/idcard = I
if(!held_card)
usr.drop_item()
idcard.loc = src
held_card = idcard
authenticated_account = null
else if(authenticated_account)
if(istype(I,/obj/item/weapon/spacecash))
user_id.money += I:worth
//consume the money
authenticated_account.money += I:worth
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit deposit"
T.amount = I:worth
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
user << "<span class='info'>You insert [I] into [src].</span>"
src.attack_hand(user)
del I
else ..()
/obj/machinery/atm/attack_hand(mob/user as mob)
if(istype(user, /mob/living/silicon))
user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
return
if(get_dist(src,user) <= 1)
//check to see if the user has low security enabled
scan_user(user)
var/obj/item/weapon/card/id/user_id = src.scan_user(user)
if(..())
return
var/dat = ""
dat += "<h1>NanoTrasen Automatic Teller Machine</h1><br/>"
dat += "For all your monetary needs!<br/><br/>"
dat += "Welcome, [user_id.registered_name].<br/>"
dat += "You have $[user_id.money] in your account.<br/>"
dat += "<a href=\"?src=\ref[src]&withdraw=1&id=\ref[user_id]\">Withdraw</a><br/>"
user << browse(dat,"window=atm")
//js replicated from obj/machinery/computer/card
var/dat = "<h1>NanoTrasen Automatic Teller Machine</h1>"
dat += "For all your monetary needs!<br>"
dat += "<i>This terminal is</i> [machine_id]. <i>Report this code when contacting NanoTrasen IT Support</i><br/>"
dat += "Card: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card.name : "------"]</a><br><br>"
if(ticks_left_locked_down > 0)
dat += "<span class='alert'>Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled.</span>"
else if(authenticated_account)
switch(view_screen)
if(CHANGE_SECURITY_LEVEL)
dat += "Select a new security level for this account:<br><hr>"
var/text = "Zero - Only account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
if(authenticated_account.security_level != 0)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=0'>[text]</a>"
dat += "[text]<hr>"
text = "One - Both an account number and pin is required to access this account and process transactions."
if(authenticated_account.security_level != 1)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=1'>[text]</a>"
dat += "[text]<hr>"
text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
if(authenticated_account.security_level != 2)
text = "<A href='?src=\ref[src];choice=change_security_level;new_security_level=2'>[text]</a>"
dat += "[text]<hr><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
if(VIEW_TRANSACTION_LOGS)
dat += "<b>Transaction logs</b><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in authenticated_account.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
if(TRANSFER_FUNDS)
dat += "<b>Account balance:</b> $[authenticated_account.money]<br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=0'>Back</a><br><br>"
dat += "<form name='transfer' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='transfer'>"
dat += "Target account number: <input type='text' name='target_acc_number' value='' style='width:200px; background-color:white;'><br>"
dat += "Funds to transfer: <input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><br>"
dat += "Transaction purpose: <input type='text' name='purpose' value='Funds transfer' style='width:200px; background-color:white;'><br>"
dat += "<input type='submit' value='Transfer funds'><br>"
dat += "</form>"
else
dat += "Welcome, <b>[authenticated_account.owner_name].</b><br/>"
dat += "<b>Account balance:</b> $[authenticated_account.money]"
dat += "<form name='withdrawal' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='withdrawal'>"
dat += "<input type='text' name='funds_amount' value='' style='width:200px; background-color:white;'><input type='submit' value='Withdraw funds'><br>"
dat += "</form>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=1'>Change account security level</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=2'>Make transfer</a><br>"
dat += "<A href='?src=\ref[src];choice=view_screen;view_screen=3'>View transaction log</a><br>"
dat += "<A href='?src=\ref[src];choice=balance_statement'>Print balance statement</a><br>"
dat += "<A href='?src=\ref[src];choice=logout'>Logout</a><br>"
else if(linked_db)
dat += "<form name='atm_auth' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='attempt_auth'>"
dat += "<b>Account:</b> <input type='text' id='account_num' name='account_num' style='width:250px; background-color:white;'><br>"
dat += "<b>PIN:</b> <input type='text' id='account_pin' name='account_pin' style='width:250px; background-color:white;'><br>"
dat += "<input type='submit' value='Submit'><br>"
dat += "</form>"
else
dat += "<span class='warning'>Unable to connect to accounts database, please retry and if the issue persists contact NanoTrasen IT support.</span>"
reconnect_database()
user << browse(dat,"window=atm;size=500x650")
else
user << browse(null,"window=atm")
/obj/machinery/atm/Topic(var/href, var/href_list)
if(href_list["withdraw"] && href_list["id"])
var/amount = input("How much would you like to withdraw?", "Amount", 0) in list(1,10,20,50,100,200,500,1000, 0)
var/obj/item/weapon/card/id/user_id = locate(href_list["id"])
if(amount != 0 && user_id)
if(amount <= user_id.money)
user_id.money -= amount
//hueg switch for giving moneh out
switch(amount)
if(1)
new /obj/item/weapon/spacecash(loc)
if(10)
new /obj/item/weapon/spacecash/c10(loc)
if(20)
new /obj/item/weapon/spacecash/c20(loc)
if(50)
new /obj/item/weapon/spacecash/c50(loc)
if(100)
new /obj/item/weapon/spacecash/c100(loc)
if(200)
new /obj/item/weapon/spacecash/c200(loc)
if(500)
new /obj/item/weapon/spacecash/c500(loc)
if(1000)
new /obj/item/weapon/spacecash/c1000(loc)
else
usr << browse("You don't have that much money!<br/><a href=\"?src=\ref[src]\">Back</a>","window=atm")
return
if(href_list["choice"])
switch(href_list["choice"])
if("transfer")
if(authenticated_account && linked_db)
var/target_account_number = text2num(href_list["target_acc_number"])
var/transfer_amount = text2num(href_list["funds_amount"])
var/transfer_purpose = href_list["purpose"]
if(transfer_amount <= authenticated_account.money)
if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
usr << "\icon[src]<span class='info'>Funds transfer successful.</span>"
authenticated_account.money -= transfer_amount
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = "Account #[target_account_number]"
T.purpose = transfer_purpose
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
T.amount = "([transfer_amount])"
authenticated_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>Funds transfer failed.</span>"
else
usr << "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>"
if("view_screen")
view_screen = text2num(href_list["view_screen"])
if("change_security_level")
if(authenticated_account)
var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0)
authenticated_account.security_level = new_sec_level
if("attempt_auth")
if(linked_db)
var/tried_account_num = text2num(href_list["account_num"])
if(!tried_account_num)
tried_account_num = held_card.associated_account_number
var/tried_pin = text2num(href_list["account_pin"])
authenticated_account = linked_db.attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
if(!authenticated_account)
if(previous_account_number == tried_account_num)
if(++number_incorrect_tries > max_pin_attempts)
//lock down the atm
number_incorrect_tries = 0
ticks_left_locked_down = 10
playsound(src, 'buzz-two.ogg', 50, 1)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Unauthorised login attempt"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
else
previous_account_number = tried_account_num
number_incorrect_tries = 1
playsound(src, 'buzz-sigh.ogg', 50, 1)
else
playsound(src, 'twobeep.ogg', 50, 1)
ticks_left_timeout = 120
view_screen = NO_SCREEN
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
if("withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
if(authenticated_account && amount > 0)
if(amount <= authenticated_account.money)
playsound(src, 'chime.ogg', 50, 1)
//remove the money
authenticated_account.money -= amount
withdraw_arbitrary_sum(amount)
//create an entry in the account transaction log
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Credit withdrawal"
T.amount = "([amount])"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>You don't have enough funds to do that!</span>"
if("balance_statement")
if(authenticated_account)
var/obj/item/weapon/paper/R = new(src.loc)
R.name = "Account balance: [authenticated_account.owner_name]"
R.info = "<b>NT Automated Teller Account Statement</b><br><br>"
R.info += "<i>Account holder:</i> [authenticated_account.owner_name]<br>"
R.info += "<i>Account number:</i> [authenticated_account.account_number]<br>"
R.info += "<i>Balance:</i> $[authenticated_account.money]<br>"
R.info += "<i>Date and time:</i> [worldtime2text()], [current_date_string]<br><br>"
R.info += "<i>Service terminal ID:</i> [machine_id]<br>"
//stamp the paper
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/weapon/stamp
R.overlays += stampoverlay
R.stamps += "<HR><i>This paper has been stamped by the Automatic Teller Machine.</i>"
if(prob(50))
playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
else
playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
if("insert_card")
if(held_card)
held_card.loc = src.loc
authenticated_account = null
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
held_card = I
if("logout")
authenticated_account = null
src.attack_hand(usr)
//create the most effective combination of notes to make up the requested amount
/obj/machinery/atm/proc/withdraw_arbitrary_sum(var/arbitrary_sum)
while(arbitrary_sum >= 1000)
arbitrary_sum -= 1000
new /obj/item/weapon/spacecash/c1000(src)
while(arbitrary_sum >= 500)
arbitrary_sum -= 500
new /obj/item/weapon/spacecash/c500(src)
while(arbitrary_sum >= 200)
arbitrary_sum -= 200
new /obj/item/weapon/spacecash/c200(src)
while(arbitrary_sum >= 100)
arbitrary_sum -= 100
new /obj/item/weapon/spacecash/c100(src)
while(arbitrary_sum >= 50)
arbitrary_sum -= 50
new /obj/item/weapon/spacecash/c50(src)
while(arbitrary_sum >= 20)
arbitrary_sum -= 20
new /obj/item/weapon/spacecash/c20(src)
while(arbitrary_sum >= 10)
arbitrary_sum -= 10
new /obj/item/weapon/spacecash/c10(src)
while(arbitrary_sum >= 1)
arbitrary_sum -= 1
new /obj/item/weapon/spacecash(src)
//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri
/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/human_user as mob)
if(human_user.wear_id)
if(istype(human_user.wear_id, /obj/item/device/pda) )
var/obj/item/device/pda/P = human_user.wear_id
if(P.id)
return P.id
else
return null
else if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
return human_user.wear_id
else
return null
else
return null
if(!authenticated_account && linked_db)
if(human_user.wear_id)
var/obj/item/weapon/card/id/I
if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
I = human_user.wear_id
else if(istype(human_user.wear_id, /obj/item/device/pda) )
var/obj/item/device/pda/P = human_user.wear_id
I = P.id
if(I)
authenticated_account = linked_db.attempt_account_access(I.associated_account_number)
@@ -110,17 +110,17 @@ proc/assign_sec_to_department(var/mob/living/carbon/human/H)
keyslot2 = new /obj/item/device/encryptionkey/headset_sci
/obj/item/clothing/under/rank/security/cargo/New()
var/obj/item/clothing/tie/armband/cargo/A = new /obj/item/clothing/tie/armband/cargo
var/obj/item/clothing/tie/armband/cargo/A = new /obj/item/clothing/tie/armband/cargo
hastie = A
/obj/item/clothing/under/rank/security/engine/New()
var/obj/item/clothing/tie/armband/engine/A = new /obj/item/clothing/tie/armband/engine
var/obj/item/clothing/tie/armband/engine/A = new /obj/item/clothing/tie/armband/engine
hastie = A
/obj/item/clothing/under/rank/security/science/New()
var/obj/item/clothing/tie/armband/science/A = new /obj/item/clothing/tie/armband/science
var/obj/item/clothing/tie/armband/science/A = new /obj/item/clothing/tie/armband/science
hastie = A
/obj/item/clothing/under/rank/security/med/New()
var/obj/item/clothing/tie/armband/med/A = new /obj/item/clothing/tie/armband/med
var/obj/item/clothing/tie/armband/medgreen/A = new /obj/item/clothing/tie/armband/medgreen
hastie = A
+12 -4
View File
@@ -2,10 +2,18 @@
//moved these here from code/defines/obj/weapon.dm
//please preference put stuff where it's easy to find - C
/obj/item/weapon/autopsy_scanner/var/list/datum/autopsy_data_scanner/wdata = list()
/obj/item/weapon/autopsy_scanner/var/list/datum/autopsy_data_scanner/chemtraces = list()
/obj/item/weapon/autopsy_scanner/var/target_name = null
/obj/item/weapon/autopsy_scanner/var/timeofdeath = null
/obj/item/weapon/autopsy_scanner
name = "autopsy scanner"
desc = "Extracts information on wounds."
icon = 'icons/obj/autopsy_scanner.dmi'
icon_state = ""
flags = FPRINT | TABLEPASS | CONDUCT
w_class = 1.0
origin_tech = "materials=1;biotech=1"
var/list/datum/autopsy_data_scanner/wdata = list()
var/list/datum/autopsy_data_scanner/chemtraces = list()
var/target_name = null
var/timeofdeath = null
/datum/autopsy_data_scanner
var/weapon = null // this is the DEFINITE weapon type that was used
-246
View File
@@ -1,246 +0,0 @@
dmm_suite
/*
dmm_suite version 1.0
Released January 30th, 2011.
defines the object /dmm_suite
- Provides the proc load_map()
- Loads the specified map file onto the specified z-level.
- provides the proc write_map()
- Returns a text string of the map in dmm format
ready for output to a file.
- provides the proc save_map()
- Returns a .dmm file if map is saved
- Returns FALSE if map fails to save
The dmm_suite provides saving and loading of map files in BYOND's native DMM map
format. It approximates the map saving and loading processes of the Dream Maker
and Dream Seeker programs so as to allow editing, saving, and loading of maps at
runtime.
------------------------
To save a map at runtime, create an instance of /dmm_suite, and then call
write_map(), which accepts three arguments:
- A turf representing one corner of a three dimensional grid (Required).
- Another turf representing the other corner of the same grid (Required).
- Any, or a combination, of several bit flags (Optional, see documentation).
The order in which the turfs are supplied does not matter, the /dmm_writer will
determine the grid containing both, in much the same way as DM's block() function.
write_map() will then return a string representing the saved map in dmm format;
this string can then be saved to a file, or used for any other purose.
------------------------
To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
which accepts two arguments:
- A .dmm file to load (Required).
- A number representing the z-level on which to start loading the map (Optional).
The /dmm_suite will load the map file starting on the specified z-level. If no
z-level was specified, world.maxz will be increased so as to fit the map. Note
that if you wish to load a map onto a z-level that already has objects on it,
you will have to handle the removal of those objects. Otherwise the new map will
simply load the new objects on top of the old ones.
Also note that all type paths specified in the .dmm file must exist in the world's
code, and that the /dmm_reader trusts that files to be loaded are in fact valid
.dmm files. Errors in the .dmm format will cause runtime errors.
*/
verb/load_map(var/dmm_file as file, var/z_offset as num)
// dmm_file: A .dmm file to load (Required).
// z_offset: A number representing the z-level on which to start loading the map (Optional).
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num)
// t1: A turf representing one corner of a three dimensional grid (Required).
// t2: Another turf representing the other corner of the same grid (Required).
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
// save_map is included as a legacy proc. Use write_map instead.
verb/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num)
// t1: A turf representing one corner of a three dimensional grid (Required).
// t2: Another turf representing the other corner of the same grid (Required).
// map_name: A valid name for the map to be saved, such as "castle" (Required).
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
#define DMM_IGNORE_AREAS 1
#define DMM_IGNORE_TURFS 2
#define DMM_IGNORE_OBJS 4
#define DMM_IGNORE_NPCS 8
#define DMM_IGNORE_PLAYERS 16
#define DMM_IGNORE_MOBS 24
dmm_suite{
var{
quote = "\""
list/letter_digits = list(
"a","b","c","d","e",
"f","g","h","i","j",
"k","l","m","n","o",
"p","q","r","s","t",
"u","v","w","x","y",
"z",
"A","B","C","D","E",
"F","G","H","I","J",
"K","L","M","N","O",
"P","Q","R","S","T",
"U","V","W","X","Y",
"Z"
)
}
save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){
//Check for illegal characters in file name... in a cheap way.
if(!((ckeyEx(map_name)==map_name) && ckeyEx(map_name))){
CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.")
}
//Check for valid turfs.
if(!isturf(t1) || !isturf(t2)){
CRASH("Invalid arguments supplied to proc save_map, arguments were not turfs.")
}
var/file_text = write_map(t1,t2,flags)
if(fexists("[map_name].dmm")){
fdel("[map_name].dmm")
}
var/saved_map = file("[map_name].dmm")
saved_map << file_text
return saved_map
}
write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
//Check for valid turfs.
if(!isturf(t1) || !isturf(t2)){
CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.")
}
var/turf/nw = locate(min(t1.x,t2.x),max(t1.y,t2.y),min(t1.z,t2.z))
var/turf/se = locate(max(t1.x,t2.x),min(t1.y,t2.y),max(t1.z,t2.z))
var/list/templates[0]
var/template_buffer = {""}
var/dmm_text = {""}
for(var/pos_z=nw.z;pos_z<=se.z;pos_z++){
for(var/pos_y=nw.y;pos_y>=se.y;pos_y--){
for(var/pos_x=nw.x;pos_x<=se.x;pos_x++){
var/turf/test_turf = locate(pos_x,pos_y,pos_z)
var/test_template = make_template(test_turf, flags)
var/template_number = templates.Find(test_template)
if(!template_number){
templates.Add(test_template)
template_number = templates.len
}
template_buffer += "[template_number],"
}
template_buffer += ";"
}
template_buffer += "."
}
var/key_length = round/*floor*/(log(letter_digits.len,templates.len-1)+1)
var/list/keys[templates.len]
for(var/key_pos=1;key_pos<=templates.len;key_pos++){
keys[key_pos] = get_model_key(key_pos,key_length)
dmm_text += {""[keys[key_pos]]" = ([templates[key_pos]])\n"}
}
var/z_level = 0
for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1){
if(z_pos>=length(template_buffer)){break}
if(z_level){dmm_text+={"\n"}}
dmm_text += {"\n(1,1,[++z_level]) = {"\n"}
var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos))
for(var/y_pos=1;TRUE;y_pos=findtext(z_block,";",y_pos)+1){
if(y_pos>=length(z_block)){break}
var/y_block = copytext(z_block,y_pos,findtext(z_block,";",y_pos))
for(var/x_pos=1;TRUE;x_pos=findtext(y_block,",",x_pos)+1){
if(x_pos>=length(y_block)){break}
var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos))
var/key_number = text2num(x_block)
var/temp_key = keys[key_number]
dmm_text += temp_key
sleep(-1)
}
dmm_text += {"\n"}
sleep(-1)
}
dmm_text += {"\"}"}
sleep(-1)
}
return dmm_text
}
proc{
make_template(var/turf/model as turf, var/flags as num){
var/template = ""
var/obj_template = ""
var/mob_template = ""
var/turf_template = ""
if(!(flags & DMM_IGNORE_TURFS)){
turf_template = "[model.type][check_attributes(model)],"
} else{ turf_template = "[world.turf],"}
var/area_template = ""
if(!(flags & DMM_IGNORE_OBJS)){
for(var/obj/O in model.contents){
obj_template += "[O.type][check_attributes(O)],"
}
}
for(var/mob/M in model.contents){
if(M.client){
if(!(flags & DMM_IGNORE_PLAYERS)){
mob_template += "[M.type][check_attributes(M)],"
}
}
else{
if(!(flags & DMM_IGNORE_NPCS)){
mob_template += "[M.type][check_attributes(M)],"
}
}
}
if(!(flags & DMM_IGNORE_AREAS)){
var/area/m_area = model.loc
area_template = "[m_area.type][check_attributes(m_area)]"
} else{ area_template = "[world.area]"}
template = "[obj_template][mob_template][turf_template][area_template]"
return template
}
check_attributes(var/atom/A){
var/attributes_text = {"{"}
for(var/V in A.vars){
sleep(-1)
if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))){continue}
if(istext(A.vars[V])){
attributes_text += {"[V] = "[A.vars[V]]""}
}
else if(isnum(A.vars[V])||ispath(A.vars[V])){
attributes_text += {"[V] = [A.vars[V]]"}
}
else if(isicon(A.vars[V])||isfile(A.vars[V])){
attributes_text += {"[V] = '[A.vars[V]]'"}
}
else{
continue
}
if(attributes_text != {"{"}){
attributes_text+={"; "}
}
}
if(attributes_text=={"{"}){
return
}
if(copytext(attributes_text, length(attributes_text)-1, 0) == {"; "}){
attributes_text = copytext(attributes_text, 1, length(attributes_text)-1)
}
attributes_text += {"}"}
return attributes_text
}
get_model_key(var/which as num, var/key_length as num){
var/key = ""
var/working_digit = which-1
for(var/digit_pos=key_length;digit_pos>=1;digit_pos--){
var/place_value = round/*floor*/(working_digit/(letter_digits.len**(digit_pos-1)))
working_digit-=place_value*(letter_digits.len**(digit_pos-1))
key = "[key][letter_digits[place_value+1]]"
}
return key
}
}
}
-181
View File
@@ -1,181 +0,0 @@
dmm_suite/load_map(var/dmm_file as file, var/z_offset as num)
if(!z_offset)
z_offset = world.maxz+1
var/quote = ascii2text(34)
var/tfile = file2text(dmm_file)
var/tfile_len = length(tfile)
var/list/grid_models[0]
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))
for(var/lpos=1;lpos<tfile_len;lpos=findtext(tfile,"\n",lpos,0)+1)
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
if(copytext(tline,1,2)!=quote) break
var/model_key = copytext(tline,2,findtext(tfile,quote,2,0))
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
grid_models[model_key] = model_contents
sleep(-1)
var/zcrd=-1
var/ycrd=0
var/xcrd=0
for(var/zpos=findtext(tfile,"\n(1,1,");TRUE;zpos=findtext(tfile,"\n(1,1,",zpos+1,0))
zcrd++
world.maxz = max(world.maxz, zcrd+z_offset)
ycrd=0
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1)
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1)
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0)+1)
var/y_depth = length(zgrid)/(length(grid_line))
if(world.maxy<y_depth) world.maxy=y_depth
grid_line=copytext(grid_line,1,length(grid_line))
if(!ycrd)
ycrd = y_depth
else
ycrd--
xcrd=0
for(var/mpos=1;mpos<=length(grid_line);mpos+=key_len)
xcrd++
if(world.maxx<xcrd) world.maxx=xcrd
var/model_key = copytext(grid_line,mpos,mpos+key_len)
parse_grid(grid_models[model_key],xcrd,ycrd,zcrd+z_offset)
if(gpos+length(grid_line)+1>length(zgrid)) break
sleep(-1)
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len) break
sleep(-1)
dmm_suite/proc/parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num)
set background = 1
/*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them.
*/
var/list/text_strings[0]
for(var/index=1;findtext(model,quote);index++)
/*Loop: Stores quoted portions of text in text_strings, and replaces them with an
index to that list.
- Each iteration represents one quoted section of text.
*/
text_strings.len=index
text_strings[index] = copytext(model,findtext(model,quote)+1,findtext(model,quote,findtext(model,quote)+1,0))
model = copytext(model,1,findtext(model,quote))+"~[index]"+copytext(model,findtext(model,quote,findtext(model,quote)+1,0)+1,0)
sleep(-1)
for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1)
/*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- Each iteration represents one object's data, including type path and field values.
*/
var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
if(ispath(atom_def, /turf/space))
continue
var/list/attributes[0]
if(findtext(full_def,"{"))
full_def = copytext(full_def,1,length(full_def))
for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1)
//Loop: Identifies each attribute/value pair, and stores it in attributes[].
attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
if(!findtext(copytext(full_def,apos,0),";")) break
sleep(-1)
//Construct attributes associative list
var/list/fields = new(0)
for(var/index=1;index<=attributes.len;index++)
var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
//Check for string
if(findtext(trim_right,"~"))
var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
trim_right=text_strings[text2num(reference_index)]
//Check for number
else if(isnum(text2num(trim_right)))
trim_right = text2num(trim_right)
//Check for file
else if(copytext(trim_right,1,2) == "'")
trim_right = file(copytext(trim_right,2,length(trim_right)))
fields[trim_left] = trim_right
//End construction
//Begin Instanciation
var/atom/instance
var/dmm_suite/preloader/_preloader = new(fields)
if(ispath(atom_def,/area))
var/turf/A = locate(xcrd,ycrd,zcrd)
if(A.loc.name == "Space")
instance = locate(atom_def)
if(instance)
instance.contents.Add(locate(xcrd,ycrd,zcrd))
else
//global.current_preloader = _preloader
instance = new atom_def(locate(xcrd,ycrd,zcrd))
if(_preloader)
_preloader.load(instance)
//End Instanciation
if(!findtext(copytext(model,dpos,0),",")) break
dmm_suite/proc/trim_text(var/what as text)
while(length(what) && findtext(what," ",1,2))
what=copytext(what,2,0)
while(length(what) && findtext(what," ",length(what),0))
what=copytext(what,1,length(what))
return what
/*
var/global/dmm_suite/preloader/current_preloader = null
atom/New()
if(global.current_preloader)
global.current_preloader.load(src)
..()
*/
dmm_suite/preloader
parent_type = /datum
var/list/attributes
New(list/the_attributes)
..()
if(!the_attributes.len) Del()
attributes = the_attributes
proc/load(atom/what)
for(var/attribute in attributes)
what.vars[attribute] = attributes[attribute]
Del()
/client/proc/mapload(var/dmm_map as file)
set category = "Debug"
set name = "LoadMap"
set desc = "Loads a map"
set hidden = 1
if(src.holder)
if(!src.mob)
return
if(src.holder.rank in list("Game Admin", "Game Master"))
var/file_name = "[dmm_map]"
var/file_extension = copytext(file_name,length(file_name)-2,0)
if(file_extension != "dmm")
usr << "Supplied file must be a .dmm file."
return
var/map_z = input(usr,"Enter variable value:" ,"Value", 123) as num
if(map_z > (world.maxz+1))
map_z = (world.maxz+1)
var/dmm_suite/new_reader = new()
new_reader.load_map(dmm_map, map_z)
log_admin("[key_name(src.mob)] loaded a map on z:[map_z]")
else
alert("No")
return
return
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -148,7 +148,7 @@ proc/Airflow(zone/A, zone/B)
//Check for knocking people over
if(ismob(M) && n > vsc.airflow_stun_pressure)
if(M:nodamage) continue
if(M:status_flags & GODMODE) continue
M:airflow_stun()
if(M.check_airflow_movable(n))
@@ -242,7 +242,7 @@ atom/movable
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:nodamage)
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
@@ -307,7 +307,7 @@ atom/movable
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:nodamage)
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
+18 -13
View File
@@ -188,24 +188,29 @@
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
. = list()
set background = 1
. = list()
// Returns a list of mobs who can hear any of the radios given in @radios
var/list/speaker_coverage = list()
for(var/obj/item/device/radio/R in radios)
for(var/i = 1; i <= radios.len; i++)
var/obj/item/device/radio/R = radios[i]
if(R)
var/turf/speaker = get_turf(R)
if(speaker)
for(var/turf/T in hear(R.canhear_range,speaker))
speaker_coverage[T] = T
var/turf/speaker = get_turf(R)
if(speaker)
for(var/turf/T in hear(R.canhear_range,speaker))
speaker_coverage[T] = T
// Try to find all the players who can hear the message
for(var/mob/M in player_list)
var/turf/ear = get_turf(M)
if(ear)
if(speaker_coverage[ear])
. |= M
for(var/i = 1; i <= player_list.len; i++)
var/mob/M = player_list[i]
if(M)
var/turf/ear = get_turf(M)
if(ear)
if(speaker_coverage[ear])
. |= M
return .
#define SIGN(X) ((X<0)?-1:1)
@@ -361,4 +366,4 @@ var/list/DummyCache = list()
if(delay)
spawn(delay)
for(var/client/C in group)
C.screen -= O
C.screen -= O
+10
View File
@@ -66,4 +66,14 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al
for(var/T in paths)
var/datum/surgery_step/S = new T
surgery_steps += S
/* // Uncomment to debug chemical reaction list.
/client/verb/debug_chemical_list()
for (var/reaction in chemical_reactions_list)
. += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n"
if(islist(chemical_reactions_list[reaction]))
var/list/L = chemical_reactions_list[reaction]
for(var/t in L)
. += " has: [t]\n"
world << .
*/
+14
View File
@@ -107,9 +107,14 @@
var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
var/use_recursive_explosions //Defines whether the server uses recursive or circular explosions.
var/assistant_maint = 0 //Do assistants get maint access?
var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour.
var/ghost_interaction = 0
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
@@ -162,9 +167,15 @@
if ("ban_legacy_system")
config.ban_legacy_system = 1
if ("use_age_restriction_for_jobs")
config.use_age_restriction_for_jobs = 1
if ("jobs_have_minimal_access")
config.jobs_have_minimal_access = 1
if ("use_recursive_explosions")
use_recursive_explosions = 1
if ("log_ooc")
config.log_ooc = 1
@@ -379,6 +390,9 @@
if("continuous_rounds")
config.continous_rounds = 1
if("ghost_interaction")
config.ghost_interaction = 1
else
diary << "Unknown setting in configuration: '[name]'"
+100 -77
View File
@@ -8,6 +8,9 @@ var/global/controller_iteration = 0
var/global/last_tick_timeofday = world.timeofday
var/global/last_tick_duration = 0
var/global/air_processing_killed = 0
var/global/pipe_processing_killed = 0
datum/controller/game_controller
var/processing = 0
var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
@@ -113,15 +116,14 @@ datum/controller/game_controller/proc/process()
vote.process()
//AIR
/*timer = world.timeofday
last_thing_processed = air_master.type
air_master.process()
air_cost = (world.timeofday - timer) / 10*/
if(!air_processing_killed)
timer = world.timeofday
last_thing_processed = air_master.type
air_master.tick()
air_cost = (world.timeofday - timer) / 10
// this might make atmos slower
// 1. atmos won't process if the game is generally lagged out(no deadlocks)
// 2. if the server frequently crashes during atmos processing we will know
if(!kill_air)
// 2. if the server frequently crashes during atmos processing we will knowif(!kill_air)
//src.set_debug_state("Air Master")
air_master.current_cycle++
@@ -137,7 +139,6 @@ datum/controller/game_controller/proc/process()
air_master.failed_ticks = 0*/
//air_master_ready = 1
sleep(breather_ticks)
//SUN
@@ -150,109 +151,50 @@ datum/controller/game_controller/proc/process()
//MOBS
timer = world.timeofday
var/i = 1
while(i<=mob_list.len)
var/mob/M = mob_list[i]
if(M)
last_thing_processed = M.type
M.Life()
i++
continue
mob_list.Cut(i,i+1)
process_mobs()
mobs_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//DISEASES
timer = world.timeofday
i = 1
while(i<=active_diseases.len)
var/datum/disease/Disease = active_diseases[i]
if(Disease)
last_thing_processed = Disease.type
Disease.process()
i++
continue
active_diseases.Cut(i,i+1)
process_diseases()
diseases_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//MACHINES
timer = world.timeofday
i = 1
while(i<=machines.len)
var/obj/machinery/Machine = machines[i]
if(Machine)
last_thing_processed = Machine.type
if(Machine.process() != PROCESS_KILL)
if(Machine)
if(Machine.use_power)
Machine.auto_use_power()
i++
continue
machines.Cut(i,i+1)
process_machines()
machines_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//OBJECTS
timer = world.timeofday
i = 1
while(i<=processing_objects.len)
var/obj/Object = processing_objects[i]
if(Object)
last_thing_processed = Object.type
Object.process()
i++
continue
processing_objects.Cut(i,i+1)
process_objects()
objects_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//PIPENETS
timer = world.timeofday
last_thing_processed = /datum/pipe_network
i = 1
while(i<=pipe_networks.len)
var/datum/pipe_network/Network = pipe_networks[i]
if(Network)
Network.process()
i++
continue
pipe_networks.Cut(i,i+1)
networks_cost = (world.timeofday - timer) / 10
if(!pipe_processing_killed)
timer = world.timeofday
process_pipenets()
networks_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//POWERNETS
timer = world.timeofday
last_thing_processed = /datum/powernet
i = 1
while(i<=powernets.len)
var/datum/powernet/Powernet = powernets[i]
if(Powernet)
Powernet.reset()
i++
continue
powernets.Cut(i,i+1)
process_powernets()
powernets_cost = (world.timeofday - timer) / 10
sleep(breather_ticks)
//EVENTS
timer = world.timeofday
last_thing_processed = /datum/event
i = 1
while(i<=events.len)
var/datum/event/Event = events[i]
if(Event)
Event.process()
i++
continue
events.Cut(i,i+1)
checkEvent()
process_events()
events_cost = (world.timeofday - timer) / 10
//TICKER
@@ -271,6 +213,87 @@ datum/controller/game_controller/proc/process()
else
sleep(10)
datum/controller/game_controller/proc/process_mobs()
var/i = 1
while(i<=mob_list.len)
var/mob/M = mob_list[i]
if(M)
last_thing_processed = M.type
M.Life()
i++
continue
mob_list.Cut(i,i+1)
datum/controller/game_controller/proc/process_diseases()
var/i = 1
while(i<=active_diseases.len)
var/datum/disease/Disease = active_diseases[i]
if(Disease)
last_thing_processed = Disease.type
Disease.process()
i++
continue
active_diseases.Cut(i,i+1)
datum/controller/game_controller/proc/process_machines()
var/i = 1
while(i<=machines.len)
var/obj/machinery/Machine = machines[i]
if(Machine)
last_thing_processed = Machine.type
if(Machine.process() != PROCESS_KILL)
if(Machine)
if(Machine.use_power)
Machine.auto_use_power()
i++
continue
machines.Cut(i,i+1)
datum/controller/game_controller/proc/process_objects()
var/i = 1
while(i<=processing_objects.len)
var/obj/Object = processing_objects[i]
if(Object)
last_thing_processed = Object.type
Object.process()
i++
continue
processing_objects.Cut(i,i+1)
datum/controller/game_controller/proc/process_pipenets()
last_thing_processed = /datum/pipe_network
var/i = 1
while(i<=pipe_networks.len)
var/datum/pipe_network/Network = pipe_networks[i]
if(Network)
Network.process()
i++
continue
pipe_networks.Cut(i,i+1)
datum/controller/game_controller/proc/process_powernets()
last_thing_processed = /datum/powernet
var/i = 1
while(i<=powernets.len)
var/datum/powernet/Powernet = powernets[i]
if(Powernet)
Powernet.reset()
i++
continue
powernets.Cut(i,i+1)
datum/controller/game_controller/proc/process_events()
last_thing_processed = /datum/event
var/i = 1
while(i<=events.len)
var/datum/event/Event = events[i]
if(Event)
Event.process()
i++
continue
events.Cut(i,i+1)
checkEvent()
datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for(var/varname in master_controller.vars)
+2 -2
View File
@@ -62,12 +62,12 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
return
spread = (cure_present?"Remissive":initial_spread)
if(stage > max_stages)
stage = max_stages
if(!cure_present && prob(stage_prob)) //now the disease shouldn't get back up to stage 4 in no time
if(!cure_present && prob(stage_prob) && age > stage_minimum_age) //now the disease shouldn't get back up to stage 4 in no time
stage = min(stage + 1, max_stages)
age = 0
else if(cure_present && prob(cure_chance))
stage = max(stage - 1, 1)
+32 -35
View File
@@ -12,43 +12,40 @@
severity = "Medium"
longevity = 1000
hidden = list(0, 1)
stage_minimum_age = 300 // at least 200 life ticks per stage
stage_minimum_age = 160 // at least 200 life ticks per stage
/datum/disease/appendicitis/stage_act()
..()
switch(stage)
if(1)
if(affected_mob.op_stage.appendix == 2.0)
// appendix is removed, can't get infected again
src.cure()
if(prob(5))
affected_mob << "\red You feel a stinging pain in your abdomen!"
affected_mob.emote("me",1,"winces slightly.")
if(2)
if(prob(3))
affected_mob << "\red You feel a stabbing pain in your abdomen!"
affected_mob.emote("me",1,"winces painfully.")
affected_mob.adjustToxLoss(1)
if(3)
if(prob(1))
if (affected_mob.nutrition > 100)
var/mob/living/carbon/human/H = affected_mob
H.vomit()
else
affected_mob << "\red You gag as you want to throw up, but there's nothing in your stomach!"
affected_mob.Weaken(10)
affected_mob.adjustToxLoss(3)
if(4)
if(prob(1) && ishuman(affected_mob))
if(stage == 1)
if(affected_mob.op_stage.appendix == 2.0)
// appendix is removed, can't get infected again
src.cure()
if(prob(5))
affected_mob << "\red You feel a stinging pain in your abdomen!"
affected_mob.emote("me",1,"winces slightly.")
if(stage > 1)
if(prob(3))
affected_mob << "\red You feel a stabbing pain in your abdomen!"
affected_mob.emote("me",1,"winces painfully.")
affected_mob.adjustToxLoss(1)
if(stage > 2)
if(prob(1))
if (affected_mob.nutrition > 100)
var/mob/living/carbon/human/H = affected_mob
H << "\red Your abdomen is a world of pain!"
H.Weaken(10)
H.op_stage.appendix = 2.0
H.vomit()
else
affected_mob << "\red You gag as you want to throw up, but there's nothing in your stomach!"
affected_mob.Weaken(10)
affected_mob.adjustToxLoss(3)
if(stage > 3)
if(prob(1) && ishuman(affected_mob))
var/mob/living/carbon/human/H = affected_mob
H << "\red Your abdomen is a world of pain!"
H.Weaken(10)
H.op_stage.appendix = 2.0
var/datum/organ/external/groin = H.get_organ("groin")
var/datum/wound/W = new /datum/wound/internal_bleeding(25)
H.adjustToxLoss(25)
groin.wounds += W
src.cure()
var/datum/organ/external/groin = H.get_organ("groin")
var/datum/wound/W = new /datum/wound/internal_bleeding(25)
H.adjustToxLoss(25)
groin.wounds += W
src.cure()
+2 -2
View File
@@ -3,8 +3,8 @@
max_stages = 4
spread = "On contact"
spread_type = CONTACT_GENERAL
cure = "Spaceacillin & Alkysine"
cure_id = list("alkysine","spaceacillin")
cure = "Alkysine"
cure_id = list("alkysine")
agent = "Cryptococcus Cosmosis"
affected_species = list("Human")
curable = 0
+12 -8
View File
@@ -175,7 +175,7 @@
else if(W.damage_type == BURN)
burn_dam += W.damage
if(W.bleeding())
if(!(status & ORGAN_ROBOT) && W.bleeding())
status |= ORGAN_BLEEDING
number_wounds += W.amount
@@ -224,6 +224,7 @@
proc/clamp()
var/rval = 0
src.status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
if(W.internal) continue
rval |= !W.clamped
@@ -272,6 +273,7 @@
if(germ_level > 0)
for(var/datum/wound/W in wounds) if(!W.bandaged && !W.salved)
W.germ_level = max(W.germ_level, germ_level)
update_icon()
return
proc/fracture()
@@ -489,7 +491,8 @@
switch(type)
if(CUT)
src.status |= ORGAN_BLEEDING
if(!(status & ORGAN_ROBOT))
src.status |= ORGAN_BLEEDING
var/list/size_names = list(/datum/wound/cut, /datum/wound/deep_cut, /datum/wound/flesh_wound, /datum/wound/gaping_wound, /datum/wound/big_gaping_wound, /datum/wound/massive_wound)
wound_type = size_names[size]
@@ -508,7 +511,7 @@
// Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage
if(damage > 10 && type != BURN && local_damage > 20 && prob(damage))
if(damage > 10 && type != BURN && local_damage > 20 && prob(damage) && !(status & ORGAN_ROBOT))
var/datum/wound/internal_bleeding/I = new (15)
wounds += I
owner.custom_pain("You feel something rip in your [display_name]!", 1)
@@ -610,11 +613,12 @@
take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
..(brute, burn, sharp, used_weapon, forbidden_limbs)
if (brute_dam > 40)
if (prob(50))
disfigure("brute")
if (burn_dam > 40)
disfigure("burn")
if (!disfigured)
if (brute_dam > 40)
if (prob(50))
disfigure("brute")
if (burn_dam > 40)
disfigure("burn")
proc/disfigure(var/type = "brute")
if (disfigured)
+13 -4
View File
@@ -46,11 +46,20 @@
usr <<"The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry."
return
var/attempt = 0
if(target && target.buckled)
target.buckled.unbuckle()
var/list/tempL = L
var/attempt = null
var/success = 0
while(!success)
success = target.Move(pick(L))
if(attempt > 20) break //Failsafe
while(tempL.len)
attempt = pick(tempL)
success = target.Move(attempt)
if(!success)
tempL.Remove(attempt)
else
break
if(!success)
target.loc = pick(L)
+39
View File
@@ -0,0 +1,39 @@
/obj/effect/proc_holder/spell/targeted/horsemask
name = "Curse of the Horseman"
desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes."
school = "transmutation"
charge_type = "recharge"
charge_max = 150
charge_counter = 0
clothes_req = 0
stat_allowed = 0
invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
invocation_type = "shout"
range = 7
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr)
if(!targets.len)
user << "<span class='notice'>No target found in range.</span>"
return
var/mob/living/carbon/target = targets[1]
if(!(target.type in compatible_mobs))
user << "<span class='notice'>It'd be stupid to curse [target] with a horse's head!</span>"
return
if(!(target in oview(range)))//If they are not in overview after selection.
user << "<span class='notice'>They are too far away!</span>"
return
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
magichead.canremove = 0 //curses!
magichead.flags_inv = null //so you can still see their face
magichead.voicechange = 1 //NEEEEIIGHH
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
target.equip_to_slot(magichead, slot_wear_mask)
flick("e_flash", target.flash)
+4 -2
View File
@@ -25,8 +25,10 @@
target.gib()
if("gib_brain")
if(ishuman(target) || ismonkey(target))
var/obj/item/brain/B = new(target.loc)
B.transfer_identity(target)
var/mob/living/carbon/C = target
if(C.brain_op_stage != 4) // Their brain is already taken out
var/obj/item/brain/B = new(C.loc)
B.transfer_identity(C)
target.gib()
if("disintegrate")
target.dust()
+34 -5
View File
@@ -103,6 +103,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/reagent_containers/food/drinks/shaker,
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron,
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
/obj/item/weapon/lipstick/random,
/obj/item/weapon/reagent_containers/food/drinks/ale,
/obj/item/weapon/reagent_containers/food/drinks/ale,
/obj/item/weapon/reagent_containers/food/drinks/beer,
@@ -157,6 +159,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/caution,
/obj/item/weapon/caution,
/obj/item/weapon/caution,
/obj/item/weapon/storage/bag/trash,
/obj/item/weapon/reagent_containers/spray/cleaner,
/obj/item/weapon/reagent_containers/glass/rag,
/obj/item/weapon/grenade/chem_grenade/cleaner,
@@ -224,7 +227,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
containertype = /obj/structure/largecrate/lisa
containername = "Corgi Crate"
group = "Hydroponics"
/datum/supply_packs/hydroponics // -- Skie
name = "Hydroponics Supply Crate"
contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone,
@@ -242,6 +244,35 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
access = access_hydroponics
group = "Hydroponics"
//farm animals - useless and annoying, but potentially a good source of food
/datum/supply_packs/cow
name = "Cow Crate"
cost = 30
containertype = /obj/structure/largecrate/cow
containername = "Cow Crate"
access = access_hydroponics
/datum/supply_packs/goat
name = "Goat Crate"
cost = 25
containertype = /obj/structure/largecrate/goat
containername = "Goat Crate"
access = access_hydroponics
/datum/supply_packs/chicken
name = "Chicken Crate"
cost = 20
containertype = /obj/structure/largecrate/chick
containername = "Chicken Crate"
access = access_hydroponics
/datum/supply_packs/lisa
name = "Corgi Crate"
contains = list()
cost = 50
containertype = /obj/structure/largecrate/lisa
containername = "Corgi Crate"
/datum/supply_packs/seeds
name = "Seeds Crate"
contains = list(/obj/item/seeds/chiliseed,
@@ -717,6 +748,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/reagent_containers/glass/paint/black,
/obj/item/weapon/reagent_containers/glass/paint/white,
/obj/item/weapon/reagent_containers/glass/paint/remover,
/obj/item/weapon/contraband/poster,
/obj/item/weapon/wrapping_paper,
/obj/item/weapon/wrapping_paper,
/obj/item/weapon/wrapping_paper)
@@ -727,10 +759,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/randomised/contraband
num_contained = 5
contains = list(/obj/item/weapon/contraband/poster,
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
/obj/item/weapon/lipstick/random,
/obj/item/seeds/bloodtomatoseed,
contains = list(/obj/item/seeds/bloodtomatoseed,
/obj/item/weapon/storage/pill_bottle/zoom,
/obj/item/weapon/storage/pill_bottle/happy,
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe)
-17
View File
@@ -249,23 +249,6 @@
/obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER
// TODO: robust mixology system! (and merge with beakers, maybe)
/obj/item/weapon/glass
name = "empty glass"
desc = "Emptysville."
icon = 'icons/obj/kitchen.dmi'
icon_state = "glass_empty"
item_state = "beaker"
flags = FPRINT | TABLEPASS | OPENCONTAINER
var/datum/substance/inside = null
throwforce = 5
g_amt = 100
New()
..()
src.pixel_x = rand(-5, 5)
src.pixel_y = rand(-5, 5)
/obj/item/weapon/beach_ball
icon = 'icons/misc/beach.dmi'
icon_state = "ball"
+3 -3
View File
@@ -1220,7 +1220,7 @@
force = round((5+potency/2.5), 1)
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is eating some of the [src]! It looks like \he's trying to commit suicide.</b>"
viewers(user) << "\red <b>[user] is eating some of the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (BRUTELOSS|TOXLOSS)
// *************************************
@@ -1291,7 +1291,7 @@
var/WeedKillStr = 2
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is huffing the [src]! It looks like \he's trying to commit suicide.</b>"
viewers(user) << "\red <b>[user] is huffing the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (TOXLOSS)
/obj/item/weapon/pestspray // -- Skie
@@ -1310,7 +1310,7 @@
var/PestKillStr = 2
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is huffing the [src]! It looks like \he's trying to commit suicide.</b>"
viewers(user) << "\red <b>[user] is huffing the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (TOXLOSS)
/obj/item/weapon/minihoe // -- Numbers
+26 -18
View File
@@ -27,7 +27,7 @@
/obj/item/weapon/spacecash
name = "space cash"
name = "1 credit chip"
desc = "It's worth 1 credit."
gender = PLURAL
icon = 'icons/obj/items.dmi'
@@ -42,35 +42,57 @@
w_class = 1.0
var/access = list()
access = access_crate_cash
var/worth = 1
/obj/item/weapon/spacecash/c10
name = "10 credit chip"
icon_state = "spacecash10"
access = access_crate_cash
desc = "It's worth 10 credits."
worth = 10
/obj/item/weapon/spacecash/c20
name = "20 credit chip"
icon_state = "spacecash20"
access = access_crate_cash
desc = "It's worth 20 credits."
worth = 20
/obj/item/weapon/spacecash/c50
name = "50 credit chip"
icon_state = "spacecash50"
access = access_crate_cash
desc = "It's worth 50 credits."
worth = 50
/obj/item/weapon/spacecash/c100
name = "100 credit chip"
icon_state = "spacecash100"
access = access_crate_cash
desc = "It's worth 100 credits."
worth = 100
/obj/item/weapon/spacecash/c200
name = "200 credit chip"
icon_state = "spacecash200"
access = access_crate_cash
desc = "It's worth 200 credits."
worth = 200
/obj/item/weapon/spacecash/c500
name = "500 credit chip"
icon_state = "spacecash500"
access = access_crate_cash
desc = "It's worth 500 credits."
worth = 500
/obj/item/weapon/spacecash/c1000
name = "1000 credit chip"
icon_state = "spacecash1000"
access = access_crate_cash
desc = "It's worth 1000 credits."
worth = 1000
/obj/item/weapon/bananapeel
name = "banana peel"
@@ -147,7 +169,7 @@
desc = "A cane used by a true gentlemen. Or a clown."
icon = 'icons/obj/weapons.dmi'
icon_state = "cane"
item_state = "cane"
item_state = "stick"
flags = FPRINT | TABLEPASS| CONDUCT
force = 5.0
throwforce = 7.0
@@ -224,7 +246,7 @@
var/armed = 0
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is putting the [src] on \his head! It looks like \he's trying to commit suicide.</b>"
viewers(user) << "\red <b>[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide.</b>"
return (BRUTELOSS)
/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob)
@@ -344,20 +366,6 @@
m_amt = 100
origin_tech = "magnets=1"
/obj/item/weapon/spellbook
name = "spell book"
desc = "The legendary book of spells of the wizard."
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 1
throw_range = 5
w_class = 1.0
flags = FPRINT | TABLEPASS
var/uses = 5.0
var/temp = null
var/max_uses = 5
var/op = 1
/obj/item/weapon/staff
name = "wizards staff"
desc = "Apparently a staff used by the wizard."
@@ -426,7 +434,7 @@
attack_verb = list("whipped", "lashed", "disciplined", "tickled")
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is strangling \himself with the [src]! It looks like \he's trying to commit suicide.</b>"
viewers(user) << "\red <b>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (OXYLOSS)
/obj/item/weapon/module
+1 -1
View File
@@ -598,7 +598,7 @@ proc/process_ghost_teleport_locs()
icon_state = "fpmaint"
/area/maintenance/fsmaint
name = "Security Maintenance"
name = "Dormitory Maintenance"
icon_state = "fsmaint"
/area/maintenance/fsmaint2
+11 -11
View File
@@ -465,19 +465,19 @@ its easier to just keep the beam vertical.
for(var/obj/effect/decal/cleanable/blood/B in T.contents)
if(!B.blood_DNA[M.dna.unique_enzymes])
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
for(var/datum/disease/D in M.viruses)
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
B.viruses += newDisease
newDisease.holder = B
newDisease.holder = B*/
return 1 //we bloodied the floor
//if there isn't a blood decal already, make one.
var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(T)
newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
for(var/datum/disease/D in M.viruses)
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
newblood.viruses += newDisease
newDisease.holder = newblood
newDisease.holder = newblood*/
return 1 //we bloodied the floor
//adding blood to humans
@@ -499,10 +499,10 @@ its easier to just keep the beam vertical.
if(toxvomit)
this.icon_state = "vomittox_[pick(1,4)]"
for(var/datum/disease/D in M.viruses)
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
this.viruses += newDisease
newDisease.holder = this
newDisease.holder = this*/
// Only adds blood on the floor -- Skie
/atom/proc/add_blood_floor(mob/living/carbon/M as mob)
@@ -511,20 +511,20 @@ its easier to just keep the beam vertical.
var/turf/simulated/source1 = src
var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(source1)
this.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
for(var/datum/disease/D in M.viruses)
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
this.viruses += newDisease
newDisease.holder = this
newDisease.holder = this*/
else if( istype(M, /mob/living/carbon/alien ))
if( istype(src, /turf/simulated) )
var/turf/simulated/source2 = src
var/obj/effect/decal/cleanable/xenoblood/this = new /obj/effect/decal/cleanable/xenoblood(source2)
this.blood_DNA["UNKNOWN BLOOD"] = "X*"
for(var/datum/disease/D in M.viruses)
/*for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = D.Copy(1)
this.viruses += newDisease
newDisease.holder = this
newDisease.holder = this*/
else if( istype(M, /mob/living/silicon/robot ))
if( istype(src, /turf/simulated) )
@@ -1004,7 +1004,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// world << "according to dblclick(), t5 is [t5]"
// ------- ACTUALLY DETERMINING STUFF -------
if (((t5 || (W && (W.flags & 16))) && !( istype(src, /obj/screen) )))
if (((t5 || (W && (W.flags & USEDELAY))) && !( istype(src, /obj/screen) )))
// ------- ( CAN USE ITEM OR HAS 1 SECOND USE DELAY ) AND NOT CLICKING ON SCREEN -------
+1 -1
View File
@@ -65,7 +65,7 @@
src.throwing = 1
if(usr)
if((HULK in usr.mutations) || (SUPRSTR in usr.augmentations))
if(HULK in usr.mutations)
src.throwing = 2 // really strong throw!
var/dist_x = abs(target.x - src.x)
+1 -1
View File
@@ -228,7 +228,7 @@ datum/radio_frequency
// log_admin("DEBUG: post_signal(source=[source] ([source.x], [source.y], [source.z]),filter=[filter]) frequency=[frequency], N_f=[N_f], N_nf=[N_nf]")
del(signal)
// del(signal)
add_listener(obj/device as obj, var/filter as text|null)
if (!filter)
+2 -1
View File
@@ -9,7 +9,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
config_tag = "changeling"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
required_players = 15
required_players = 2
required_players_secret = 5
required_enemies = 1
recommended_enemies = 4
@@ -3,7 +3,8 @@
config_tag = "traitorchan"
traitors_possible = 3 //hard limit on traitors if scaling is turned off
restricted_jobs = list("AI", "Cyborg")
required_players = 20
required_players = 3
required_players_secret = 10
required_enemies = 2
recommended_enemies = 3
+3 -2
View File
@@ -22,7 +22,8 @@
config_tag = "cult"
restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain")
protected_jobs = list()
required_players = 15
required_players = 5
required_players_secret = 15
required_enemies = 3
recommended_enemies = 4
@@ -255,7 +256,7 @@
if(objectives.Find("eldergod"))
cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
if(objectives.Find("sacrifice"))
if(!sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail
if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail
cult_fail++
return cult_fail //if any objectives aren't met, failure
+2 -1
View File
@@ -1,7 +1,8 @@
/datum/game_mode/epidemic
name = "epidemic"
config_tag = "epidemic"
required_players = 6
required_players = 1
required_players_secret = 15
var/const/waittime_l = 300 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 600 //upper bound on time before intercept arrives (in tenths of seconds)
+29 -4
View File
@@ -44,13 +44,15 @@
possibleEvents["Meteor"] = 80 * engineer_count
possibleEvents["Blob"] = 30 * engineer_count
possibleEvents["Spacevine"] = 30 * engineer_count
possibleEvents["Grid Check"] = 10 * engineer_count
if(medical_count >= 1)
possibleEvents["Radiation"] = medical_count * 100
possibleEvents["Virus"] = medical_count * 50
possibleEvents["Appendicitis"] = medical_count * 50
if(security_count >= 1)
possibleEvents["Prison Break"] = security_count * 50
possibleEvents["Space Ninja"] = security_count * 10 // very low chance for space ninja event
/*if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)
possibleEvents["Space Ninja"] = security_count * 10*/
var/picked_event = pick(possibleEvents)
var/chance = possibleEvents[picked_event]
@@ -109,6 +111,10 @@
spacevine_infestation()
if("Communications")
communications_blackout()
if("Grid Check")
grid_check()
if("Meteor")
meteor_shower()
return 1
@@ -124,8 +130,9 @@
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)
/proc/power_failure()
command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure")
/proc/power_failure(var/is_grid_check = 0)
command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", is_grid_check ? "Automated Grid Check" : "Critical Power Failure")
for(var/mob/M in player_list)
M << sound('sound/AI/poweroff.ogg')
for(var/obj/machinery/power/smes/S in world)
@@ -585,10 +592,28 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
world << "Ion Storm Main Done"
*/
/proc/meteor_shower()
command_alert("The station is now in a meteor shower", "Meteor Alert")
spawn(0)
var/waves = rand(1,4)
while(waves > 0)
sleep(rand(20,100))
spawn_meteors(rand(1,3))
waves--
command_alert("The station has cleared the meteor shower", "Meteor Alert")
/proc/grid_check()
spawn(0)
power_failure(1)
sleep(rand(100,600))
power_restore()
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
// with a specific role.
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
proc/number_active_with_role(role)
/proc/number_active_with_role(role)
var/count = 0
for(var/mob/M in player_list)
if(!M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
-32
View File
@@ -1,32 +0,0 @@
/area/var/radsafe = 0
/area/maintenance/radsafe = 1
/area/ai_monitored/maintenance/radsafe = 1
/area/centcom/radsafe = 1
/area/admin/radsafe = 1
/area/adminsafety/radsafe = 1
/area/shuttle/radsafe = 1
/area/syndicate_station/radsafe = 1
/area/asteroid/radsafe = 1
/area/crew_quarters/sleeping/radsafe = 1
/datum/event/blowout
Lifetime = 150
Announce()
if(!forced && prob(90))
ActiveEvent = null
SpawnEvent()
del src
return
command_alert("Warning: station approaching high-density radiation cloud. Seek cover immediately.")
Tick()
if(ActiveFor == 50)
command_alert("Station has entered radiation cloud. Do not leave cover until it has passed.")
if(ActiveFor == 100 || ActiveFor == 150) //1/2 and 2/2 f the way after it start proper make peope be half dead mostly
for(var/mob/living/carbon/M in world)
var/area = get_area(M)
if(area:radsafe)
continue
if(!M.stat)
M.radiate(100)
Die()
command_alert("The station has cleared the radiation cloud. It is now safe to leave cover.")
@@ -1,88 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
/datum/event/electricalstorm
var/list/obj/machinery/light/Lights = list( )
var/list/obj/machinery/light/APCs = list( )
var/list/obj/machinery/light/Doors = list( )
var/list/obj/machinery/light/Comms = list( )
Announce()
// command_alert("The station is flying through an electrical storm. Radio communications may be disrupted", "Anomaly Alert")
for(var/obj/machinery/light/Light in world)
if(Light.z == 1 && Light.status != 0)
Lights += Light
for(var/obj/machinery/power/apc/APC in world)
if(APC.z == 1 && !APC.crit)
APCs += APC
for(var/obj/machinery/door/airlock/Door in world)
if(Door.z == 1 && !istype(Door,/obj/machinery/door/airlock/secure))
Doors += Door
for(var/obj/machinery/telecomms/processor/T in world)
if(prob(90) && !(T.stat & (BROKEN|NOPOWER)))
T.stat |= BROKEN
Comms |= T
Tick()
for(var/x = 0; x < 3; x++)
if (prob(30))
BlowLight()
if (prob(10))
DisruptAPC()
if (prob(10))
DisableDoor()
Die()
command_alert("The station has cleared the electrical storm. Radio communications restored", "Anomaly Alert")
for(var/obj/machinery/telecomms/processor/T in Comms)
T.stat &= ~BROKEN
Comms = list()
proc
BlowLight() //Blow out a light fixture
var/obj/machinery/light/Light = null
var/failed_attempts = 0
while (Light == null || Light.status != 0)
Light = pick(Lights)
failed_attempts++
if (failed_attempts >= 10)
return
spawn(0) //Overload the light, spectacularly.
//Light.sd_SetLuminosity(10)
//sleep(2)
Light.on = 1
Light.broken()
Lights -= Light
DisruptAPC()
var/failed_attempts = 0
var/obj/machinery/power/apc/APC
while (!APC || !APC.operating)
APC = pick(APCs)
failed_attempts++
if (failed_attempts >= 10)
return
if (prob(40))
APC.operating = 0 //Blow its breaker
if (prob(8))
APC.set_broken()
APCs -= APC
DisableDoor()
var/obj/machinery/door/airlock/Airlock
while (!Airlock || Airlock.z != 1)
Airlock = pick(Doors)
Airlock.pulse(airlockIndexToWireColor[4])
for (var/x = 0; x < 2; x++)
var/Wire = 0
while(!Wire || Wire == 4)
Wire = rand(1, 9)
Airlock.pulse(airlockIndexToWireColor[Wire])
Airlock.update_icon()
Doors -= Airlock
@@ -1,10 +0,0 @@
/datum/event/gravitationalanomaly
Announce()
command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
world << sound('granomalies.ogg')
var/turf/T = pick(blobstart)
var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
spawn(rand(50, 300))
del(bh)
@@ -1,5 +0,0 @@
/datum/event/immovablerod
Announce()
immovablerod()
-11
View File
@@ -1,11 +0,0 @@
/datum/event/meteorstorm
Announce()
command_alert("The station is now in a meteor shower", "Meteor Alert")
Tick()
if (prob(20))
meteor_wave()
Die()
command_alert("The station has cleared the meteor shower", "Meteor Alert")
@@ -1,16 +0,0 @@
/datum/event/power_offline
Announce()
for(var/obj/machinery/power/apc/a in world)
if(!a.crit && a.z == 1)
if(istype(a.area, /area/ai_monitored/storage/eva) || istype(a.area, /area/engine)\
|| istype(a.area, /area/toxins/xenobiology) || istype(a.area, /area/turret_protected/ai))
continue
a.eventoff = 1
a.update()
Die()
command_alert("The station has finished an automated power system grid check, thank you.", "Maintenance alert")
for(var/obj/machinery/power/apc/a in world)
if(!a.crit)
a.eventoff = 0
a.update()
-30
View File
@@ -1,30 +0,0 @@
/datum/event/prisonbreak
Announce()
for (var/obj/machinery/power/apc/temp_apc in world)
if(istype(get_area(temp_apc), /area/security/prison))
temp_apc.overload_lighting()
if(istype(get_area(temp_apc), /area/security/brig))
temp_apc.overload_lighting()
// for (var/obj/machinery/computer/prison_shuttle/temp_shuttle in world)
// temp_shuttle.prison_break()
for (var/obj/structure/closet/secure_closet/brig/temp_closet in world)
if(istype(get_area(temp_closet), /area/security/prison))
temp_closet.locked = 0
temp_closet.icon_state = temp_closet.icon_closed
for (var/obj/machinery/door/airlock/security/temp_airlock in world)
if(istype(get_area(temp_airlock), /area/security/prison))
temp_airlock.prison_open()
if(istype(get_area(temp_airlock), /area/security/brig))
temp_airlock.prison_open()
for (var/obj/machinery/door/airlock/glass/glass_security/temp_glassairlock in world)
if(istype(get_area(temp_glassairlock), /area/security/prison))
temp_glassairlock.prison_open()
if(istype(get_area(temp_glassairlock), /area/security/brig))
temp_glassairlock.prison_open()
for (var/obj/machinery/door_timer/temp_timer in world)
if(istype(get_area(temp_timer), /area/security/brig))
temp_timer.releasetime = 1
sleep(150)
command_alert("Glitch in imprisonment subroutines detected on [station_name()]. Recommend station AI involvement.", "Security Alert")
@@ -1,27 +0,0 @@
/datum/event/radiation
var/current_iteration = 0
// 50 - 20 (grace period) seconds lifetime
Lifetime = 50
Announce()
command_alert("The station is now travelling through a radiation belt. Take shelter in the maintenance tunnels, or in the crew quarters!", "Medical Alert")
Tick()
current_iteration++
// start radiating after 20 seconds grace period
if(current_iteration > 20)
for(var/mob/living/carbon/L in world)
// check whether they're in a safe place
// if they are, do not radiate
var/turf/T = get_turf(L)
if(T && ( istype(T.loc, /area/maintenance) || istype(T.loc, /area/crew_quarters) ))
continue
if (istype(L, /mob/living/carbon/monkey)) // So as to stop monkeys from dying in their pens
L.apply_effect(rand(3,4), IRRADIATE)
else
L.apply_effect(rand(4,10), IRRADIATE)
Die()
command_alert("The station has cleared the radiation belt", "Medical Alert")
-14
View File
@@ -1,14 +0,0 @@
/datum/event/spacecarp
Announce()
for(var/obj/effect/landmark/C in world)
if(C.name == "carpspawn")
if(prob(99))
new /mob/living/simple_animal/carp(C.loc)
else
new /mob/living/simple_animal/carp/elite(C.loc)
//sleep(100)
spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes.
command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
world << sound('commandreport.ogg')
-6
View File
@@ -1,6 +0,0 @@
/datum/event/spaceninja
Announce()
if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round.
space_ninja_arrival()//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
+174
View File
@@ -0,0 +1,174 @@
// BIOMASS (Note that this code is very similar to Space Vine code)
/obj/effect/biomass
name = "biomass"
desc = "Space barf from another dimension. It just keeps spreading!"
icon = 'icons/obj/biomass.dmi'
icon_state = "stage1"
anchored = 1
density = 0
layer = 5
pass_flags = PASSTABLE | PASSGRILLE
var/energy = 0
var/obj/effect/biomass_controller/master = null
New()
return
Del()
if(master)
master.vines -= src
master.growth_queue -= src
..()
/obj/effect/biomass/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (!W || !user || !W.type) return
switch(W.type)
if(/obj/item/weapon/circular_saw) del src
if(/obj/item/weapon/kitchen/utensil/knife) del src
if(/obj/item/weapon/scalpel) del src
if(/obj/item/weapon/twohanded/fireaxe) del src
if(/obj/item/weapon/hatchet) del src
if(/obj/item/weapon/melee/energy) del src
//less effective weapons
if(/obj/item/weapon/wirecutters)
if(prob(25)) del src
if(/obj/item/weapon/shard)
if(prob(25)) del src
else //weapons with subtypes
if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user)) del src
else
return
..()
/obj/effect/biomass_controller
var/list/obj/effect/biomass/vines = list()
var/list/growth_queue = list()
var/reached_collapse_size
var/reached_slowdown_size
//What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
//meaning if you get the biomasssss..s' size to something less than 20 plots, it won't grow anymore.
New()
if(!istype(src.loc,/turf/simulated/floor))
del(src)
spawn_biomass_piece(src.loc)
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
proc/spawn_biomass_piece(var/turf/location)
var/obj/effect/biomass/BM = new(location)
growth_queue += BM
vines += BM
BM.master = src
process()
if(!vines)
del(src) //space vines exterminated. Remove the controller
return
if(!growth_queue)
del(src) //Sanity check
return
if(vines.len >= 250 && !reached_collapse_size)
reached_collapse_size = 1
if(vines.len >= 30 && !reached_slowdown_size )
reached_slowdown_size = 1
var/maxgrowth = 0
if(reached_collapse_size)
maxgrowth = 0
else if(reached_slowdown_size)
if(prob(25))
maxgrowth = 1
else
maxgrowth = 0
else
maxgrowth = 4
var/length = min( 30 , vines.len / 5 )
var/i = 0
var/growth = 0
var/list/obj/effect/biomass/queue_end = list()
for( var/obj/effect/biomass/BM in growth_queue )
i++
queue_end += BM
growth_queue -= BM
if(BM.energy < 2) //If tile isn't fully grown
if(prob(20))
BM.grow()
if(BM.spread())
growth++
if(growth >= maxgrowth)
break
if(i >= length)
break
growth_queue = growth_queue + queue_end
/obj/effect/biomass/proc/grow()
if(!energy)
src.icon_state = "stage2"
energy = 1
src.opacity = 0
src.density = 0
layer = 5
else
src.icon_state = "stage3"
src.opacity = 0
src.density = 1
energy = 2
/obj/effect/biomass/proc/spread()
var/direction = pick(cardinal)
var/step = get_step(src,direction)
if(istype(step,/turf/simulated/floor))
var/turf/simulated/floor/F = step
if(!locate(/obj/effect/biomass,F))
if(F.Enter(src))
if(master)
master.spawn_biomass_piece( F )
return 1
return 0
/obj/effect/biomass/ex_act(severity)
switch(severity)
if(1.0)
del(src)
return
if(2.0)
if (prob(90))
del(src)
return
if(3.0)
if (prob(50))
del(src)
return
return
/obj/effect/biomass/temperature_expose(null, temp, volume) //hotspots kill biomass
del src
/proc/biomass_infestation()
spawn() //to stop the secrets panel hanging
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
for(var/areapath in typesof(/area/hallway))
var/area/hallway/A = locate(areapath)
for(var/turf/simulated/floor/F in A)
if(!F.contents.len)
turfs += F
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/simulated/floor/T = pick(turfs)
new/obj/effect/biomass_controller(T) //spawn a controller at turf
message_admins("\blue Event: Biomass spawned at [T.loc.loc] ([T.x],[T.y],[T.z])")
@@ -1428,7 +1428,7 @@ It is possible to destroy the net by the occupant or someone else.
return
attack_hand()
if ((HULK in usr.mutations) || (SUPRSTR in usr.augmentations))
if (HULK in usr.mutations)
usr << text("\blue You easily destroy the energy net.")
for(var/mob/O in oviewers(src))
O.show_message(text("\red [] rips the energy net apart!", usr), 1)
+30 -1
View File
@@ -1024,4 +1024,33 @@ That is why you attached them to objects.
step_to(current_clone,src,1)
sleep(5)
if(safety<=0) break
return */
return */
//Alternate ninja speech replacement.
/*This text is hilarious but also absolutely retarded.
message = replacetext(message, "l", "r")
message = replacetext(message, "rr", "ru")
message = replacetext(message, "v", "b")
message = replacetext(message, "f", "hu")
message = replacetext(message, "'t", "")
message = replacetext(message, "t ", "to ")
message = replacetext(message, " I ", " ai ")
message = replacetext(message, "th", "z")
message = replacetext(message, "ish", "isu")
message = replacetext(message, "is", "izu")
message = replacetext(message, "ziz", "zis")
message = replacetext(message, "se", "su")
message = replacetext(message, "br", "bur")
message = replacetext(message, "ry", "ri")
message = replacetext(message, "you", "yuu")
message = replacetext(message, "ck", "cku")
message = replacetext(message, "eu", "uu")
message = replacetext(message, "ow", "au")
message = replacetext(message, "are", "aa")
message = replacetext(message, "ay", "ayu")
message = replacetext(message, "ea", "ii")
message = replacetext(message, "ch", "chi")
message = replacetext(message, "than", "sen")
message = replacetext(message, ".", "")
message = lowertext(message)
*/
+2 -1
View File
@@ -1,4 +1,4 @@
// SPACE VINES
// SPACE VINES (Note that this code is very similar to Biomass code)
/obj/effect/spacevine
name = "space vines"
desc = "An extremely expansionistic species of vine."
@@ -6,6 +6,7 @@
icon_state = "Light1"
anchored = 1
density = 0
layer = 5
pass_flags = PASSTABLE | PASSGRILLE
var/energy = 0
var/obj/effect/spacevine_controller/master = null
+8 -2
View File
@@ -24,6 +24,7 @@
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
var/list/protected_jobs = list() // Jobs that can't be tratiors because
var/required_players = 0
var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret
var/required_enemies = 0
var/recommended_enemies = 0
var/uplink_welcome = "Syndicate Uplink Console:"
@@ -84,8 +85,13 @@ Implants;
for(var/mob/new_player/player in player_list)
if((player.client)&&(player.ready))
playerC++
if(playerC >= required_players)
return 1
if(master_mode=="secret")
if(playerC >= required_players_secret)
return 1
else
if(playerC >= required_players)
return 1
return 0
@@ -4,7 +4,8 @@
/datum/game_mode/malfunction
name = "AI malfunction"
config_tag = "malfunction"
required_players = 20
required_players = 2
required_players_secret = 15
required_enemies = 1
recommended_enemies = 1
@@ -136,6 +137,7 @@
if(config.continous_rounds)
if(emergency_shuttle)
emergency_shuttle.always_fake_recall = 0
malf_mode_declared = 0
else
return 1
return ..() //check for shuttle and nuke
+2 -1
View File
@@ -5,7 +5,8 @@
/datum/game_mode/meme
name = "Memetic Anomaly"
config_tag = "meme"
required_players = 6
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
+2 -1
View File
@@ -5,7 +5,8 @@
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
required_players = 20 // 20 players - 5 players to be the nuke ops = 15 players remaining
required_players = 6
required_players_secret = 15 // 15 players - 5 players to be the nuke ops = 10 players remaining
required_enemies = 5
recommended_enemies = 5
+2 -1
View File
@@ -15,7 +15,8 @@
name = "revolution"
config_tag = "revolution"
restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
required_players = 20
required_players = 4
required_players_secret = 15
required_enemies = 3
recommended_enemies = 3
@@ -3,7 +3,8 @@
/datum/game_mode/revolution/rp_revolution
name = "rp-revolution"
config_tag = "rp-revolution"
required_players = 12
required_players = 4
required_players_secret = 12
required_enemies = 3
recommended_enemies = 3
@@ -1,7 +0,0 @@
/datum/traitorinfo
var/starting_objective = ""
var/starting_player_count = 0
var/starting_occupation = ""
var/starting_name = ""
var/ckey = ""
var/list/spawnlist = list()
+11 -2
View File
@@ -17,7 +17,7 @@
for(var/datum/objective/OBJ in H.mind.objectives)
H << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
var/randomize = pick("taser","egun","laser","revolver","smg","nuclear","deagle","gyrojet","pulse","silenced","cannon","shotgun","mateba","uzi","crossbow","saw")
var/randomize = pick("taser","egun","laser","revolver","detective","smg","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","mateba","smg","uzi","crossbow","saw")
switch (randomize)
if("taser")
new /obj/item/weapon/gun/energy/taser(get_turf(H))
@@ -27,6 +27,8 @@
new /obj/item/weapon/gun/energy/laser(get_turf(H))
if("revolver")
new /obj/item/weapon/gun/projectile(get_turf(H))
if("detective")
new /obj/item/weapon/gun/projectile/detective(get_turf(H))
if("smg")
new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H))
if("nuclear")
@@ -38,13 +40,20 @@
if("pulse")
new /obj/item/weapon/gun/energy/pulse_rifle(get_turf(H))
if("silenced")
new /obj/item/weapon/gun/projectile/silenced(get_turf(H))
new /obj/item/weapon/gun/projectile/pistol(get_turf(H))
new /obj/item/weapon/silencer(get_turf(H))
if("cannon")
new /obj/item/weapon/gun/energy/lasercannon(get_turf(H))
if("doublebarrel")
new /obj/item/weapon/gun/projectile/shotgun/pump/(get_turf(H))
if("shotgun")
new /obj/item/weapon/gun/projectile/shotgun/pump/(get_turf(H))
if("combatshotgun")
new /obj/item/weapon/gun/projectile/shotgun/pump/combat(get_turf(H))
if("mateba")
new /obj/item/weapon/gun/projectile/mateba(get_turf(H))
if("smg")
new /obj/item/weapon/gun/projectile/automatic(get_turf(H))
if("uzi")
new /obj/item/weapon/gun/projectile/automatic/mini_uzi(get_turf(H))
if("crossbow")
+152 -130
View File
@@ -1,167 +1,189 @@
/obj/item/weapon/spellbook
name = "spell book"
desc = "The legendary book of spells of the wizard."
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 1
throw_range = 5
w_class = 1.0
flags = FPRINT | TABLEPASS
var/uses = 5
var/temp = null
var/max_uses = 5
var/op = 1
//SPELL BOOK PROCS
/obj/item/weapon/spellbook/attack_self(mob/user as mob)
user.set_machine(src)
var/dat
if (src.temp)
dat = "[src.temp]<BR><BR><A href='byond://?src=\ref[src];temp=1'>Clear</A>"
if(temp)
dat = "[temp]<BR><BR><A href='byond://?src=\ref[src];temp=1'>Clear</A>"
else
dat = "<B>The Book of Spells:</B><BR>"
dat += "Spells left to memorize: [src.uses]<BR>"
dat += "Spells left to memorize: [uses]<BR>"
dat += "<HR>"
dat += "<B>Memorize which spell:</B><BR>"
dat += "<I>The number after the spell name is the cooldown time.</I><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=1'>Magic Missile</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=2'>Fireball</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=3'>Disintegrate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=4'>Disable Technology</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=5'>Smoke</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=6'>Blind</A> (30)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=7'>Mind Transfer</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=8'>Forcewall</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=9'>Blink</A> (2)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=10'>Teleport</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=11'>Mutate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=12'>Ethereal Jaunt</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=13'>Knock</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=magicmissile'>Magic Missile</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=fireball'>Fireball</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=disintegrate'>Disintegrate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=disabletech'>Disable Technology</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=smoke'>Smoke</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=blind'>Blind</A> (30)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=mindswap'>Mind Transfer</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=forcewall'>Forcewall</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=blink'>Blink</A> (2)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=teleport'>Teleport</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=mutate'>Mutate</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=etherealjaunt'>Ethereal Jaunt</A> (60)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=knock'>Knock</A> (10)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=horseman'>Curse of the Horseman</A> (15)<BR>"
if(op)
dat += "<A href='byond://?src=\ref[src];spell_choice=14'>Summon Guns</A> (One time use, global spell)<BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=summonguns'>Summon Guns</A> (One time use, global spell)<BR>"
dat += "<HR>"
dat += "<B>Artefacts:</B><BR>"
dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of spells.<BR>"
dat += "It is recommended that only experienced wizards attempt to wield such artefacts.<BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=15'>Staff of Change</A><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=staffchange'>Staff of Change</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=16'>Six Soul Stone Shards and the spell Artificer</A><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=soulstone'>Six Soul Stone Shards and the spell Artificer</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=17'>Mastercrafted Armor Set</A><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=armor'>Mastercrafted Armor Set</A><BR>"
dat += "<HR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=18'>Staff of Animation</A><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=staffanimation'>Staff of Animation</A><BR>"
dat += "<HR>"
if(op)
dat += "<A href='byond://?src=\ref[src];spell_choice=19'>Re-memorize Spells</A><BR>"
dat += "<A href='byond://?src=\ref[src];spell_choice=rememorize'>Re-memorize Spells</A><BR>"
user << browse(dat, "window=radio")
onclose(user, "radio")
return
/obj/item/weapon/spellbook/Topic(href, href_list)
..()
if (usr.stat || usr.restrained())
return
var/mob/living/carbon/human/H = usr
if (!( istype(H, /mob/living/carbon/human)))
return 1
if ( src.loc == usr || (in_range(src,usr) && istype(src.loc, /turf)))
usr.set_machine(src)
if(href_list["spell_choice"])
if(src.uses >= 1 && src.max_uses >=1 && text2num(href_list["spell_choice"]) < 19)
src.uses--
var/list/available_spells = list("Magic Missile","Fireball","Disintegrate","Disable Tech","Smoke","Blind","Mind Transfer","Forcewall","Blink","Teleport","Mutate","Ethereal Jaunt","Knock","Summon Guns","Staff of Change","Six Soul Stone Shards and the spell Artificer","Mastercrafted Armor Set", "Staff of Animation")
var/already_knows = 0
for(var/obj/effect/proc_holder/spell/aspell in usr.spell_list)
if(available_spells[text2num(href_list["spell_choice"])] == aspell.name)
already_knows = 1
src.temp = "You already know that spell."
src.uses++
break
if(!already_knows)
switch(href_list["spell_choice"])
if ("1")
feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(usr)
src.temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage."
if ("2")
feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(usr)
src.temp = "This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you."
if ("3")
feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate(usr)
src.temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown."
if ("4")
feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(usr)
src.temp = "This spell disables all weapons, cameras and most other technology in range."
if ("5")
feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(usr)
src.temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
if ("6")
feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(usr)
src.temp = "This spell temporarly blinds a single person and does not require wizard garb."
if ("7")
feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(usr)
src.temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process."
if ("8")
feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(usr)
src.temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
if ("9")
feedback_add_details("wizard_spell_learned","BL") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(usr)
src.temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience."
if ("10")
feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(usr)
src.temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable."
if ("11")
feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(usr)
src.temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
if ("12")
feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(usr)
src.temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
if ("13")
feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(usr)
src.temp = "This spell opens nearby doors and does not require wizard garb."
if ("14")
feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
usr.rightandwrong()
src.max_uses--
src.temp = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!"
if ("15")
feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff(get_turf(usr))
src.temp = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
src.max_uses--
if ("16")
feedback_add_details("wizard_spell_learned","SS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/storage/belt/soulstone/full(get_turf(usr))
usr.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(usr)
src.temp = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
src.max_uses--
if ("17")
feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/clothing/shoes/sandal(get_turf(usr)) //In case they've lost them.
new /obj/item/clothing/gloves/purple(get_turf(usr))//To complete the outfit
new /obj/item/clothing/suit/space/rig/wizard(get_turf(usr))
new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(usr))
src.temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
src.max_uses--
if("18")
feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff/animate(get_turf(usr))
src.temp = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
src.max_uses--
if (href_list["spell_choice"] == "19")
if(H.stat || H.restrained())
return
if(!istype(H, /mob/living/carbon/human))
return 1
if(loc == H || (in_range(src, H) && istype(loc, /turf)))
H.set_machine(src)
if(href_list["spell_choice"])
if(href_list["spell_choice"] == "rememorize")
var/area/wizard_station/A = locate()
if(usr in A.contents)
src.uses = src.max_uses
usr.spellremove(usr)
src.temp = "All spells have been removed. You may now memorize a new set of spells."
uses = max_uses
H.spellremove(usr)
temp = "All spells have been removed. You may now memorize a new set of spells."
feedback_add_details("wizard_spell_learned","UM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
else
src.temp = "You may only re-memorize spells whilst located inside the wizard sanctuary."
temp = "You may only re-memorize spells whilst located inside the wizard sanctuary."
else if(uses >= 1 && max_uses >=1)
uses--
/*
*/
var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", summonguns = "Summon Guns", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation")
var/already_knows = 0
for(var/obj/effect/proc_holder/spell/aspell in H.spell_list)
if(available_spells[href_list["spell_choice"]] == aspell.name)
already_knows = 1
temp = "You already know that spell."
uses++
break
/*
*/
if(!already_knows)
switch(href_list["spell_choice"])
if("magicmissile")
feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H)
temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage."
if("fireball")
feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H)
temp = "This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you."
if("disintegrate")
feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate(H)
temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown."
if("disabletech")
feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H)
temp = "This spell disables all weapons, cameras and most other technology in range."
if("smoke")
feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H)
temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
if("blind")
feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H)
temp = "This spell temporarly blinds a single person and does not require wizard garb."
if("mindswap")
feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(H)
temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process."
if("forcewall")
feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(H)
temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
if("blink")
feedback_add_details("wizard_spell_learned","BL") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(H)
temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience."
if("teleport")
feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H)
temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable."
if("mutate")
feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H)
temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
if("etherealjaunt")
feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H)
temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
if("knock")
feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(H)
temp = "This spell opens nearby doors and does not require wizard garb."
if("horseman")
feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.spell_list += new /obj/effect/proc_holder/spell/targeted/horsemask(H)
temp = "This spell will curse a person to wear an unremovable horse mask (it has glue on the inside) and speak like a horse. It does not require a wizard garb. Do note the curse will disintegrate the target's current mask if they are wearing one."
if("summonguns")
feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.rightandwrong()
max_uses--
temp = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!"
if("staffchange")
feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff(get_turf(H))
temp = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
max_uses--
if("soulstone")
feedback_add_details("wizard_spell_learned","SS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/storage/belt/soulstone/full(get_turf(H))
H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(H)
temp = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
max_uses--
if("armor")
feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/clothing/shoes/sandal(get_turf(H)) //In case they've lost them.
new /obj/item/clothing/gloves/purple(get_turf(H))//To complete the outfit
new /obj/item/clothing/suit/space/rig/wizard(get_turf(H))
new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(H))
temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
max_uses--
if("staffanimation")
feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/weapon/gun/energy/staff/animate(get_turf(H))
temp = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
max_uses--
else
if (href_list["temp"])
src.temp = null
if(href_list["temp"])
temp = null
attack_self(H)
return
+2 -1
View File
@@ -5,7 +5,8 @@
/datum/game_mode/wizard
name = "wizard"
config_tag = "wizard"
required_players = 20
required_players = 2
required_players_secret = 10
required_enemies = 1
recommended_enemies = 1
-7
View File
@@ -252,13 +252,6 @@ datum/hud/New(mob/owner)
if(ishuman(mymob))
human_hud(ui_style) // Pass the player the UI style chosen in preferences
if(RADAR in mymob.augmentations)
spawn()
if(mymob.radar_open)
mymob:start_radar()
else
mymob:place_radar_closed()
else if(ismonkey(mymob))
monkey_hud(ui_style)
+33 -17
View File
@@ -414,29 +414,45 @@
/proc/get_all_centcom_jobs()
return list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer","BlackOps Commander","Supreme Commander")
/obj/proc/GetJobName()
//gets the actual job rank (ignoring alt titles)
//this is used solely for sechuds
/obj/proc/GetJobRealName()
if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
return
var/jobName
var/realJobName
// hack for alt titles
if(istype(loc, /mob))
var/mob/M = loc
if(M.mind && M.mind.role_alt_title == jobName && M.mind.assigned_role in get_all_jobs())
return M.mind.assigned_role
var/rank
var/assignment
if(istype(src, /obj/item/device/pda))
if(src:id)
jobName = src:id:assignment
realJobName = src:id:assignment_real_title
if(istype(src, /obj/item/weapon/card/id))
jobName = src:assignment
realJobName = src:assignment_real_title
rank = src:id:rank
assignment = src:id:assignment
else if(istype(src, /obj/item/weapon/card/id))
rank = src:rank
assignment = src:assignment
if( (realJobName in get_all_jobs()) || (jobName in get_all_jobs()) )
return jobName
if( rank in get_all_jobs() )
return rank
if( assignment in get_all_jobs() )
return assignment
return "Unknown"
//gets the alt title, failing that the actual job rank
//this is unused
/obj/proc/sdsdsd() //GetJobDisplayName
if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
return
var/assignment
if(istype(src, /obj/item/device/pda))
if(src:id)
assignment = src:id:assignment
else if(istype(src, /obj/item/weapon/card/id))
assignment = src:assignment
if(assignment)
return assignment
return "Unknown"
+2 -3
View File
@@ -12,8 +12,7 @@
access = list() //See get_access()
minimal_access = list() //See get_access()
alt_titles = list("Administrator")
minimal_player_age = 14
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_ears)
@@ -56,7 +55,7 @@
selection_color = "#ddddff"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
alt_titles = list("Human resources director","Executive Officer")
minimal_player_age = 10
access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
+16 -17
View File
@@ -8,9 +8,9 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_bar)
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_bar)
alt_titles = list("Waiter","Waitress")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -50,9 +50,9 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_kitchen, access_morgue)
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue)
minimal_access = list(access_kitchen, access_morgue)
alt_titles = list("Gourmet chef","Cook")
alt_titles = list("Cook")
equip(var/mob/living/carbon/human/H)
@@ -79,10 +79,11 @@
spawn_positions = 2
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_hydroponics, access_morgue) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
access = list(access_hydroponics, access_bar, access_kitchen, access_morgue) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
minimal_access = list(access_hydroponics, access_morgue) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
alt_titles = list("Hydroponicist")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/hydroponics(H), slot_w_uniform)
@@ -111,7 +112,6 @@
selection_color = "#dddddd"
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
alt_titles = list("Supplies Officer","Logistics Officer")
equip(var/mob/living/carbon/human/H)
@@ -140,9 +140,8 @@
spawn_positions = 2
supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd"
access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
alt_titles = list("Supplies worker","Courier","Logistics worker")
equip(var/mob/living/carbon/human/H)
@@ -169,9 +168,9 @@
spawn_positions = 3
supervisors = "the quartermaster and the head of personnel"
selection_color = "#dddddd"
access = list(access_mining, access_mint, access_mining_station, access_mailsorting)
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
minimal_access = list(access_mining, access_mint, access_mining_station, access_mailsorting)
alt_titles = list("Deep space miner","NTCA Affiliate","Prospector")
alt_titles = list("Deep space miner")
equip(var/mob/living/carbon/human/H)
@@ -208,7 +207,7 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_clown, access_theatre)
access = list(access_clown, access_theatre, access_maint_tunnels)
minimal_access = list(access_clown, access_theatre)
@@ -240,7 +239,7 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_mime, access_theatre)
access = list(access_mime, access_theatre, access_maint_tunnels)
minimal_access = list(access_mime, access_theatre)
@@ -283,7 +282,7 @@
selection_color = "#dddddd"
access = list(access_janitor, access_maint_tunnels)
minimal_access = list(access_janitor, access_maint_tunnels)
alt_titles = list("Custodial officer","Hygiene supervisor","OHS assistant","Health and Safety worker")
alt_titles = list("Custodial officer")
equip(var/mob/living/carbon/human/H)
@@ -310,9 +309,9 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_library)
access = list(access_library, access_maint_tunnels)
minimal_access = list(access_library)
alt_titles = list("Journalist","Clerk","Record keeper")
alt_titles = list("Journalist")
equip(var/mob/living/carbon/human/H)
@@ -339,9 +338,9 @@ var/global/lawyer = 0//Checks for another lawyer
spawn_positions = 2
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_lawyer, access_court, access_sec_doors)
access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels)
minimal_access = list(access_lawyer, access_court, access_sec_doors)
alt_titles = list("Attourney","Barrister","Solicitor","Queen's Counsel","Paralegal")
alt_titles = list("Attourney", "IA Consultant")
equip(var/mob/living/carbon/human/H)
+2 -2
View File
@@ -8,9 +8,9 @@
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
access = list(access_morgue, access_chapel_office, access_crematorium)
access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels)
minimal_access = list(access_morgue, access_chapel_office, access_crematorium)
alt_titles = list("Counselor","Psychiatrist","Crew services adviser","Morale Officer")
alt_titles = list("Counselor")
equip(var/mob/living/carbon/human/H)
+3 -5
View File
@@ -9,7 +9,6 @@
selection_color = "#ffeeaa"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
alt_titles = list("Engineering supervisor")
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction, access_sec_doors,
@@ -18,6 +17,7 @@
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction, access_sec_doors,
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat)
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
@@ -50,12 +50,11 @@
spawn_positions = 5
supervisors = "the chief engineer"
selection_color = "#fff5cc"
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction)
access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_atmospherics)
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction)
alt_titles = list("Technician","Maintenance technician","Engine technician","EVA technician","Electrician","Construction specialist")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_eng(H), slot_ears)
@@ -86,9 +85,8 @@
spawn_positions = 2
supervisors = "the chief engineer"
selection_color = "#fff5cc"
access = list(access_atmospherics, access_maint_tunnels, access_emergency_storage, access_construction)
access = list(access_eva, access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction, access_atmospherics)
minimal_access = list(access_atmospherics, access_maint_tunnels, access_emergency_storage, access_construction)
alt_titles = list("Pipeworker","Gas supervisor","Firefighter")
equip(var/mob/living/carbon/human/H)
+23 -1
View File
@@ -38,6 +38,9 @@
//If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect.
var/req_admin_notify
//If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
var/minimal_player_age = 0
/datum/job/proc/equip(var/mob/living/carbon/human/H)
return 1
@@ -48,4 +51,23 @@
if(config.jobs_have_minimal_access)
return src.minimal_access
else
return src.access
return src.access
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
/datum/job/proc/player_old_enough(client/C)
if(available_in_days(C) == 0)
return 1 //Available in 0 days = available right now = player is old enough to play.
return 0
/datum/job/proc/available_in_days(client/C)
if(!C)
return 0
if(!config.use_age_restriction_for_jobs)
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
if(!isnum(minimal_player_age))
return 0
return max(0, minimal_player_age - C.player_age)
+5 -7
View File
@@ -15,7 +15,7 @@
minimal_access = list(access_medical, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
access_keycard_auth, access_sec_doors)
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -47,8 +47,7 @@
spawn_positions = 3
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
access = list(access_medical, access_morgue, access_surgery)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
minimal_access = list(access_medical, access_morgue, access_surgery)
alt_titles = list("Surgeon","Emergency Physician","Nurse","Orderly")
@@ -100,7 +99,7 @@
spawn_positions = 2
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
access = list(access_medical, access_chemistry)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
minimal_access = list(access_medical, access_chemistry)
alt_titles = list("Pharmacist")
@@ -129,9 +128,8 @@
spawn_positions = 2
supervisors = "the chief medical officer and research director"
selection_color = "#ffeef0"
access = list(access_medical, access_morgue, access_genetics, access_research)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_research)
minimal_access = list(access_medical, access_morgue, access_genetics, access_research)
alt_titles = list("Sequencer")
equip(var/mob/living/carbon/human/H)
@@ -157,7 +155,7 @@
spawn_positions = 1
supervisors = "the chief medical officer"
selection_color = "#ffeef0"
access = list(access_medical, access_virology)
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
minimal_access = list(access_medical, access_virology)
alt_titles = list("Pathologist","Microbiologist")
+4 -5
View File
@@ -17,7 +17,7 @@
access_tox_storage, access_teleporter, access_sec_doors,
access_research, access_robotics, access_xenobiology, access_ai_upload,
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway)
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -44,10 +44,9 @@
spawn_positions = 3
supervisors = "the research director"
selection_color = "#ffeeff"
access = list(access_tox, access_tox_storage, access_research, access_xenobiology)
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology)
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenobiology)
alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist","High Energy Materials Researcher")
alt_titles = list("Xenoarcheologist", "Anomalist", "Plasma Researcher", "Xenobiologist")
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -73,7 +72,7 @@
spawn_positions = 1
supervisors = "research director"
selection_color = "#ffeeff"
access = list(access_robotics, access_tech_storage, access_morgue, access_research) //As a job that handles so many corpses, it makes sense for them to have morgue access.
access = list(access_robotics, access_tox, access_tox_storage, access_tech_storage, access_morgue, access_research) //As a job that handles so many corpses, it makes sense for them to have morgue access.
minimal_access = list(access_robotics, access_tech_storage, access_morgue, access_research) //As a job that handles so many corpses, it makes sense for them to have morgue access.
alt_titles = list("Biomedical engineer","Mechatronic engineer")
+8 -11
View File
@@ -9,7 +9,6 @@
selection_color = "#ffdddd"
idtype = /obj/item/weapon/card/id/silver
req_admin_notify = 1
alt_titles = list("Commander","Commissioner")
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
@@ -18,7 +17,7 @@
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway)
minimal_player_age = 14
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -56,10 +55,9 @@
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
alt_titles = list("Arsenal clerk","Brig supervisor","Superintendant")
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court)
access = list(access_security, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue)
minimal_access = list(access_security, access_sec_doors, access_brig, access_armory, access_court)
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -94,11 +92,12 @@
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#ffeeee"
alt_titles = list("Forensic Technician")
access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
minimal_access = list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
alt_titles = list("Forensic Technician","Investigator")
alt_titles = list("Forensic Technician")
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
@@ -142,11 +141,9 @@
spawn_positions = 5
supervisors = "the head of security"
selection_color = "#ffeeee"
access = list(access_security, access_sec_doors, access_brig, access_court)
access = list(access_security, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue)
minimal_access = list(access_security, access_sec_doors, access_brig, access_court)
alt_titles = list("OHS marshal","Enforcer")
minimal_player_age = 7
equip(var/mob/living/carbon/human/H)
if(!H) return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
+2 -1
View File
@@ -8,7 +8,7 @@
selection_color = "#ccffcc"
supervisors = "your laws"
req_admin_notify = 1
minimal_player_age = 30
equip(var/mob/living/carbon/human/H)
if(!H) return 0
@@ -25,6 +25,7 @@
spawn_positions = 2
supervisors = "your laws and the AI" //Nodrak
selection_color = "#ddffdd"
minimal_player_age = 21
equip(var/mob/living/carbon/human/H)
if(!H) return 0
+29 -18
View File
@@ -38,8 +38,8 @@ var/global/datum/controller/occupations/job_master
if(J.title == rank) return J
return null
proc/GetAltTitle(mob/new_player/player, rank)
return player.client.prefs.GetAltTitle(GetJob(rank))
proc/GetPlayerAltTitle(mob/new_player/player, rank)
return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0)
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
@@ -47,13 +47,14 @@ var/global/datum/controller/occupations/job_master
var/datum/job/job = GetJob(rank)
if(!job) return 0
if(jobban_isbanned(player, rank)) return 0
if(!job.player_old_enough(player.client)) return 0
var/position_limit = job.total_positions
if(!latejoin)
position_limit = job.spawn_positions
if((job.current_positions < position_limit) || position_limit == -1)
Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
player.mind.assigned_role = rank
player.mind.role_alt_title = GetAltTitle(player, rank)
player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
unassigned -= player
job.current_positions++
return 1
@@ -74,6 +75,9 @@ var/global/datum/controller/occupations/job_master
if(jobban_isbanned(player, job.title))
Debug("FOC isbanned failed, Player: [player]")
continue
if(!job.player_old_enough(player.client))
Debug("FOC player not old enough, Player: [player]")
continue
if(flag && (!player.client.prefs.be_special & flag))
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
@@ -83,7 +87,7 @@ var/global/datum/controller/occupations/job_master
return candidates
proc/GiveRandomJob(var/mob/new_player/player)
Debug("FOC Giving random job, Player: [player]")
Debug("GRJ Giving random job, Player: [player]")
for(var/datum/job/job in shuffle(occupations))
if(!job)
continue
@@ -95,11 +99,15 @@ var/global/datum/controller/occupations/job_master
continue
if(jobban_isbanned(player, job.title))
Debug("FOC isbanned failed, Player: [player], Job: [job.title]")
Debug("GRJ isbanned failed, Player: [player], Job: [job.title]")
continue
if(!job.player_old_enough(player.client))
Debug("GRJ player not old enough, Player: [player]")
continue
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
Debug("FOC Random job given, Player: [player], Job: [job]")
Debug("GRJ Random job given, Player: [player], Job: [job]")
AssignRole(player, job.title)
unassigned -= player
break
@@ -242,7 +250,11 @@ var/global/datum/controller/occupations/job_master
continue
if(jobban_isbanned(player, job.title))
Debug("FOC isbanned failed, Player: [player], Job:[job.title]")
Debug("DO isbanned failed, Player: [player], Job:[job.title]")
continue
if(!job.player_old_enough(player.client))
Debug("DO player not old enough, Player: [player], Job:[job.title]")
continue
// If the player wants that job on this level, then try give it to him.
@@ -250,7 +262,7 @@ var/global/datum/controller/occupations/job_master
// If the job isn't filled
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
Debug("FOC pass, Player: [player], Level:[level], Job:[job.title]")
Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
AssignRole(player, job.title)
unassigned -= player
break
@@ -299,9 +311,6 @@ var/global/datum/controller/occupations/job_master
H << "Your job is [rank] and the game just can't handle it! Please report this bug to an administrator."
H.job = rank
if(H.mind && H.mind.assigned_role != rank)
H.mind.assigned_role = rank
H.mind.role_alt_title = null
if(!joined_late)
var/obj/S = null
@@ -319,6 +328,7 @@ var/global/datum/controller/occupations/job_master
if(H.mind)
H.mind.assigned_role = rank
H.mind.role_alt_title = null
switch(rank)
if("Cyborg")
@@ -347,10 +357,7 @@ var/global/datum/controller/occupations/job_master
if(job.req_admin_notify)
H << "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>"
if(H.mind.assigned_role == rank && H.mind.role_alt_title)
spawnId(H, rank, H.mind.role_alt_title)
else
spawnId(H,rank)
spawnId(H, rank, H.mind.role_alt_title)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_ears)
// H.update_icons()
return 1
@@ -358,7 +365,6 @@ var/global/datum/controller/occupations/job_master
proc/spawnId(var/mob/living/carbon/human/H, rank, title)
if(!H) return 0
if(!title) title = rank
var/obj/item/weapon/card/id/C = null
var/datum/job/job = null
@@ -377,7 +383,8 @@ var/global/datum/controller/occupations/job_master
C = new /obj/item/weapon/card/id(H)
if(C)
C.registered_name = H.real_name
C.assignment = title
C.rank = rank
C.assignment = title ? title : rank
C.name = "[C.registered_name]'s ID Card ([C.assignment])"
H.equip_to_slot_or_del(C, slot_wear_id)
H.equip_to_slot_or_del(new /obj/item/device/pda(H), slot_belt)
@@ -433,12 +440,16 @@ var/global/datum/controller/occupations/job_master
var/level3 = 0 //low
var/level4 = 0 //never
var/level5 = 0 //banned
var/level6 = 0 //account too young
for(var/mob/new_player/player in player_list)
if(!(player.ready && player.mind && !player.mind.assigned_role))
continue //This player is not ready
if(jobban_isbanned(player, job.title))
level5++
continue
if(!job.player_old_enough(player.client))
level6++
continue
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
level1++
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
@@ -447,5 +458,5 @@ var/global/datum/controller/occupations/job_master
level3++
else level4++ //not selected
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|-"
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|-|YOUNG=[level6]|-"
feedback_add_details("job_preferences",tmp_str)
+1 -1
View File
@@ -63,4 +63,4 @@
H << "You'll have to wait if you want to atone for your sins."
spawn(3000)
H.miming = 1
return
return
+1 -1
View File
@@ -63,7 +63,7 @@
return
/obj/machinery/optable/attack_hand(mob/user as mob)
if ((HULK in usr.mutations) || (SUPRSTR in usr.augmentations))
if (HULK in usr.mutations)
usr << text("\blue You destroy the table.")
visible_message("\red [usr] destroys the operating table!")
src.density = 0
+2 -2
View File
@@ -665,7 +665,7 @@ Auto Patrol: []"},
if(src.emagged == 2) return 10 //Everyone is a criminal!
if((src.idcheck) || (isnull(perp:wear_id)) || (istype(perp:wear_id, /obj/item/weapon/card/id/syndicate)))
if((src.idcheck) || (isnull(perp:wear_id)) || (istype(perp:wear_id.GetID(), /obj/item/weapon/card/id/syndicate)))
if((istype(perp.l_hand, /obj/item/weapon/gun) && !istype(perp.l_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.l_hand, /obj/item/weapon/melee/baton))
if(!istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/bluetag) \
@@ -692,7 +692,7 @@ Auto Patrol: []"},
threatcount += 2
//Agent cards lower threatlevel when normal idchecking is off.
if((istype(perp:wear_id, /obj/item/weapon/card/id/syndicate)) && src.idcheck)
if((perp.wear_id && istype(perp:wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) && src.idcheck)
threatcount -= 2
if(src.lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
+1 -1
View File
@@ -623,7 +623,7 @@ Auto Patrol: []"},
threatcount += 2
//Agent cards lower threatlevel.
if(istype(perp:wear_id, /obj/item/weapon/card/id/syndicate))
if(perp.wear_id && istype(perp:wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
threatcount -= 2
if(src.check_records)
+9 -3
View File
@@ -8,7 +8,8 @@
active_power_usage = 10
layer = 5
var/network = "SS13"
var/list/network = list("SS13")
var/network_multi = "" //This is for when you want to place a camera on the map. Input them as a string seperated by commas "SS13,RD,SomeOtherNetwork"
var/c_tag = null
var/c_tag_order = 999
var/status = 1.0
@@ -40,17 +41,22 @@
assembly.state = 4
/* // Use this to look for cameras that have the same c_tag.
for(var/obj/machinery/camera/C in cameranet.cameras)
if(C != src && C.c_tag == src.c_tag && C.network == src.network)
var/list/tempnetwork = C.network&src.network
if(C != src && C.c_tag == src.c_tag && tempnetwork.len)
world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]"
*/
..()
/obj/machinery/camera/initialize() //Lists dont work in the map editor so we have to translate a string into a list when the map initializes
if(network_multi)
network = text2list(network_multi,",")
/obj/machinery/camera/emp_act(severity)
if(!isEmpProof())
if(prob(100/severity))
icon_state = "[initial(icon_state)]emp"
network = null //Not the best way but it will do. I think.
for(var/i in network)
network.Remove(i) //Not the best way but it will do. I think.
cameranet.removeCamera(src)
stat |= EMPED
SetLuminosity(0)
+12 -2
View File
@@ -76,6 +76,17 @@
// State 3
if(isscrewdriver(W))
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13"))
if(!input)
usr << "No input found please hang up and try your call again."
return
var/list/tempnetwork = text2list(input, ",")
if(tempnetwork.len < 1)
usr << "No network found please hang up and try your call again."
return
state = 4
var/obj/machinery/camera/C = new(src.loc)
src.loc = C
@@ -83,8 +94,7 @@
C.auto_turn()
C.network = "SS13"
C.network = input(usr, "Which network would you like to connect this camera to?", "Set Network", "SS13")
C.network = tempnetwork
C.c_tag = "[get_area_name(src)] ([rand(1, 999)]"
+7 -5
View File
@@ -12,7 +12,8 @@
var/list/T = list()
T["Cancel"] = "Cancel"
for (var/obj/machinery/camera/C in L)
if (C.network == src.network)
var/list/tempnetwork = C.network&src.network
if (tempnetwork.len)
T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
track = new()
@@ -74,7 +75,7 @@
human = 1
var/mob/living/carbon/human/H = M
//Cameras can't track people wearing an agent card or a ninja hood.
if(istype(H.wear_id, /obj/item/weapon/card/id/syndicate))
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
continue
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
var/obj/item/clothing/head/helmet/space/space_ninja/hood = H.head
@@ -131,15 +132,16 @@
if (U.cameraFollow == null)
return
if (istype(target, /mob/living/carbon/human))
if(istype(target:wear_id, /obj/item/weapon/card/id/syndicate))
var/mob/living/carbon/human/H = target
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(istype(target:head, /obj/item/clothing/head/helmet/space/space_ninja) && !target:head:canremove)
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && !H.head.canremove)
U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(target.digitalcamo)
if(H.digitalcamo)
U << "Follow camera mode terminated."
U.cameraFollow = null
return
@@ -40,6 +40,7 @@
/obj/item/weapon/circuitboard/aicore
name = "Circuit board (AI core)"
origin_tech = "programming=4;biotech=2"
board_type = "other"
/obj/item/weapon/circuitboard/aiupload
name = "Circuit board (AI Upload)"
build_path = "/obj/machinery/computer/aiupload"
+6 -5
View File
@@ -8,7 +8,7 @@
circuit = "/obj/item/weapon/circuitboard/security"
var/obj/machinery/camera/current = null
var/last_pic = 1.0
var/network = "SS13"
var/list/network = list("SS13")
var/mapping = 0//For the overview file, interesting bit of code.
@@ -45,7 +45,8 @@
var/list/D = list()
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(C.network == network)
var/list/tempnetwork = C.network&network
if(tempnetwork.len)
D[text("[][]", C.c_tag, (C.status ? null : " (Deactivated)"))] = C
var/t = input(user, "Which camera should you change to?") as null|anything in D
@@ -84,7 +85,7 @@
desc = "Used for watching an empty arena."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "telescreen"
network = "thunder"
network = list("thunder")
density = 0
circuit = null
@@ -99,7 +100,7 @@
desc = "Damn, they better have /tg/thechannel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
network = "thunder"
network = list("thunder")
density = 0
circuit = null
@@ -114,5 +115,5 @@
name = "Outpost Cameras"
desc = "Used to access the various cameras on the outpost."
icon_state = "miningcameras"
network = "MINE"
network = list("MINE")
circuit = "/obj/item/weapon/circuitboard/mining"
+6 -4
View File
@@ -232,8 +232,9 @@
var/t1 = href_list["assign_target"]
if(t1 == "Custom")
var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,MAX_MESSAGE_LEN)
if(temp_t)
t1 = temp_t
//let custom jobs function as an impromptu alt title, mainly for sechuds
if(temp_t && modify)
modify.assignment = temp_t
else
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
@@ -246,8 +247,9 @@
return
modify.access = ( istype(src,/obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() )
if (modify)
modify.assignment = t1
if (modify)
modify.assignment = t1
modify.rank = t1
if ("reg")
if (authenticated)
var/t2 = modify
+11 -7
View File
@@ -289,11 +289,15 @@
else if (href_list["view_rec"])
src.active_record = locate(href_list["view_rec"])
if ((isnull(src.active_record.fields["ckey"])) || (src.active_record.fields["ckey"] == ""))
del(src.active_record)
src.temp = "ERROR: Record Corrupt"
if(istype(src.active_record,/datum/data/record))
if ((isnull(src.active_record.fields["ckey"])) || (src.active_record.fields["ckey"] == ""))
del(src.active_record)
src.temp = "ERROR: Record Corrupt"
else
src.menu = 3
else
src.menu = 3
src.active_record = null
src.temp = "Record missing."
else if (href_list["del_rec"])
if ((!src.active_record) || (src.menu < 3))
@@ -416,9 +420,9 @@
if (subject.suiciding == 1)
scantemp = "Error: Subject's brain is not responding to scanning stimuli."
return
// if ((!subject.ckey) || (!subject.client))
// scantemp = "Error: Mental interface failure."
// return
if ((!subject.ckey) || (!subject.client))
scantemp = "Error: Mental interface failure."
return
if (NOCLONE in subject.mutations)
scantemp = "Error: Mental interface failure."
return
+1 -1
View File
@@ -52,7 +52,7 @@
world << text("\blue <B>Alert: [] authorizations needed until shuttle is launched early</B>", src.auth_need - src.authorized.len)
if("Abort")
world << "\blue <B>All authorizations to shorting time for shuttle launch have been revoked!</B>"
world << "\blue <B>All authorizations to shortening time for shuttle launch have been revoked!</B>"
src.authorized.len = 0
src.authorized = list( )
+5 -3
View File
@@ -4,7 +4,7 @@
icon_state = "cell-off"
density = 1
anchored = 1.0
layer = 5
layer = 2.8
var/on = 0
var/temperature_archived
@@ -100,8 +100,10 @@
on = !on
update_icon()
if(href_list["eject"])
beaker:loc = loc
beaker = null
if (beaker)
var/obj/item/weapon/reagent_containers/glass/B = beaker
B.loc = get_step(loc, SOUTH)
beaker = null
updateUsrDialog()
add_fingerprint(usr)
-8
View File
@@ -92,7 +92,6 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
normalspeed = 1
var/obj/item/weapon/airlock_electronics/electronics = null
var/hasShocked = 0 //Prevents multiple shocks from happening
var/heat_proof = 0 // For glass airlocks
/obj/machinery/door/airlock/command
name = "Airlock"
@@ -632,13 +631,6 @@ About the new airlock wires panel:
return 0
/obj/machinery/door/airlock/update_heat_protection(var/turf/simulated/source)
if(istype(source))
if(src.density && (src.opacity || src.heat_proof))
source.thermal_conductivity = DOOR_HEAT_TRANSFER_COEFFICIENT
else
source.thermal_conductivity = initial(source.thermal_conductivity)
/obj/machinery/door/airlock/update_icon()
if(overlays) overlays.Cut()
if(density)
+2 -1
View File
@@ -17,6 +17,7 @@
var/autoclose = 0
var/glass = 0
var/normalspeed = 1
var/heat_proof = 0 // For glass airlocks/opacity firedoors
/obj/machinery/door/New()
..()
@@ -253,7 +254,7 @@
/obj/machinery/door/proc/update_heat_protection(var/turf/simulated/source)
if(istype(source))
if(src.density && src.opacity)
if(src.density && (src.opacity || src.heat_proof))
source.thermal_conductivity = DOOR_HEAT_TRANSFER_COEFFICIENT
else
source.thermal_conductivity = initial(source.thermal_conductivity)
+2 -1
View File
@@ -123,7 +123,7 @@
else
spawn(0)
close()
return
var/access_granted = 0
var/users_name
if(!istype(C, /obj)) //If someone hit it with their hand. We need to see if they are allowed.
@@ -226,6 +226,7 @@
icon = 'icons/obj/doors/edge_Doorfire.dmi'
glass = 1 //There is a glass window so you can see through the door
//This is needed due to BYOND limitations in controlling visibility
heat_proof = 1
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover) && mover.checkpass(PASSGLASS))
+24 -19
View File
@@ -1,3 +1,5 @@
#define SPEED_MULTIPLIER 0.5
/obj/machinery/hydroponics
name = "hydroponics tray"
icon = 'icons/obj/hydroponics.dmi'
@@ -45,42 +47,42 @@ obj/machinery/hydroponics/process()
lastcycle = world.time
if(planted && !dead)
// Advance age
age++
age += 1 * SPEED_MULTIPLIER
//Nutrients//////////////////////////////////////////////////////////////
// Nutrients deplete slowly
if(nutrilevel > 0)
if(prob(50))
nutrilevel -= 1
nutrilevel -= 1 * SPEED_MULTIPLIER
// Lack of nutrients hurts non-weeds
if(nutrilevel <= 0 && myseed.plant_type != 1)
health -= rand(1,3)
health -= rand(1,3) * SPEED_MULTIPLIER
//Water//////////////////////////////////////////////////////////////////
// Drink random amount of water
waterlevel = max(waterlevel - rand(1,6), 0)
waterlevel = max(waterlevel - rand(1,6) * SPEED_MULTIPLIER, 0)
// If the plant is dry, it loses health pretty fast, unless mushroom
if(waterlevel <= 10 && myseed.plant_type != 2)
health -= rand(0,1)
health -= rand(0,1) * SPEED_MULTIPLIER
if(waterlevel <= 0)
health -= rand(0,2)
health -= rand(0,2) * SPEED_MULTIPLIER
// Sufficient water level and nutrient level = plant healthy
else if(waterlevel > 10 && nutrilevel > 0)
health += rand(1,2)
health += rand(1,2) * SPEED_MULTIPLIER
if(prob(5)) //5 percent chance the weed population will increase
weedlevel += 1
weedlevel += 1 * SPEED_MULTIPLIER
//Toxins/////////////////////////////////////////////////////////////////
// Too much toxins cause harm, but when the plant drinks the contaiminated water, the toxins disappear slowly
if(toxic >= 40 && toxic < 80)
health -= 1
toxic -= rand(1,10)
health -= 1 * SPEED_MULTIPLIER
toxic -= rand(1,10) * SPEED_MULTIPLIER
else if(toxic >= 80) // I don't think it ever gets here tbh unless above is commented out
health -= 3
toxic -= rand(1,10)
health -= 3 * SPEED_MULTIPLIER
toxic -= rand(1,10) * SPEED_MULTIPLIER
else if(toxic < 0) // Make sure it won't go overoboard
toxic = 0
@@ -91,11 +93,11 @@ obj/machinery/hydroponics/process()
pestlevel = 10
else if(pestlevel >= 5)
health -= 1
health -= 1 * SPEED_MULTIPLIER
// If it's a weed, it doesn't stunt the growth
if(weedlevel >= 5 && myseed.plant_type != 1 )
health -= 1
health -= 1 * SPEED_MULTIPLIER
//Health & Age///////////////////////////////////////////////////////////
@@ -107,12 +109,12 @@ obj/machinery/hydroponics/process()
else if(health <= 0)
dead = 1
harvest = 0
weedlevel += 1 // Weeds flourish
weedlevel += 1 * SPEED_MULTIPLIER // Weeds flourish
pestlevel = 0 // Pests die
// If the plant is too old, lose health fast
if(age > myseed.lifespan)
health -= rand(1,5)
health -= rand(1,5) * SPEED_MULTIPLIER
// Harvest code
if(age > myseed.production && (age - lastproduce) > myseed.production && (!harvest && !dead))
@@ -129,10 +131,10 @@ obj/machinery/hydroponics/process()
else
lastproduce = age
if(prob(5)) // On each tick, there's a 5 percent chance the pest population will increase
pestlevel += 1
pestlevel += 1 * SPEED_MULTIPLIER
else
if(waterlevel > 10 && nutrilevel > 0 && prob(10)) // If there's no plant, the percentage chance is 10%
weedlevel += 1
weedlevel += 1 * SPEED_MULTIPLIER
if(weedlevel > 10)
weedlevel = 10
@@ -712,6 +714,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the [src].")
weedlevel = 0
updateicon()
src.updateicon()
else
user << "\red This plot is completely devoid of weeds. It doesn't need uprooting."
@@ -1037,4 +1040,6 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
SetLuminosity(round(myseed.potency/10))
else
SetLuminosity(0)
return
return
#undef SPEED_MULTIPLIER
+10 -14
View File
@@ -558,7 +558,7 @@ Status: []<BR>"},
return 10
if(auth_weapons) // check for weapon authorization
if((isnull(perp:wear_id)) || (istype(perp:wear_id, /obj/item/weapon/card/id/syndicate)))
if((isnull(perp.wear_id)) || (istype(perp.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)))
if((src.allowed(perp)) && !(src.lasercolor)) // if the perp has security access, return 0
return 0
@@ -569,40 +569,36 @@ Status: []<BR>"},
if((istype(perp.r_hand, /obj/item/weapon/gun) && !istype(perp.r_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.r_hand, /obj/item/weapon/melee/baton))
threatcount += 4
if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee/baton))
if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee/baton))
threatcount += 2
if((src.lasercolor) == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
threatcount = 0//But does not target anyone else
if(istype(perp.wear_suit, /obj/item/clothing/suit/redtag))
threatcount += 4
if((istype(perp:r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(perp:l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
if((istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
threatcount += 4
if(istype(perp:belt, /obj/item/weapon/gun/energy/laser/redtag))
if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/redtag))
threatcount += 2
if((src.lasercolor) == "r")
threatcount = 0
if(istype(perp.wear_suit, /obj/item/clothing/suit/bluetag))
threatcount += 4
if((istype(perp:r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(perp:l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
if((istype(perp.r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(perp.l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
threatcount += 4
if(istype(perp:belt, /obj/item/weapon/gun/energy/laser/bluetag))
if(istype(perp.belt, /obj/item/weapon/gun/energy/laser/bluetag))
threatcount += 2
if (src.check_records) // if the turret can check the records, check if they are set to *Arrest* on records
for (var/datum/data/record/E in data_core.general)
var/perpname = perp.name
if (perp:wear_id)
var/obj/item/weapon/card/id/id = perp:wear_id
if(istype(perp:wear_id, /obj/item/device/pda))
var/obj/item/device/pda/pda = perp:wear_id
id = pda.id
if (perp.wear_id)
var/obj/item/weapon/card/id/id = perp.wear_id.GetID()
if (id)
perpname = id.registered_name
else
var/obj/item/device/pda/pda = perp:wear_id
perpname = pda.owner
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.security)
if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*"))
+139 -180
View File
@@ -17,14 +17,14 @@
var/active = 1 //No sales pitches if off!
var/vend_ready = 1 //Are we ready to vend?? Is it time??
var/vend_delay = 10 //How long does it take to vend?
var/product_paths = "" //String of product paths separated by semicolons. No spaces!
var/product_amounts = "" //String of product amounts separated by semicolons, must have amount for every path in product_paths
// To be filled out at compile time
var/list/products = list() // For each, use the following pattern:
var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
var/list/premium = list() // No specified amount = only one in stock
var/product_slogans = "" //String of slogans separated by semicolons, optional
var/product_ads = "" //String of small ad messages in the vending screen - random chance
var/product_hidden = "" //String of products that are hidden unless hacked.
var/product_hideamt = "" //String of hidden product amounts, separated by semicolons. Exact same as amounts. Must be left blank if hidden is.
var/product_coin = ""
var/product_coin_amt = ""
var/list/product_records = list()
var/list/hidden_records = list()
var/list/coin_records = list()
@@ -53,25 +53,16 @@
..()
spawn(4)
src.slogan_list = text2list(src.product_slogans, ";")
var/list/temp_paths = text2list(src.product_paths, ";")
var/list/temp_amounts = text2list(src.product_amounts, ";")
var/list/temp_hidden = text2list(src.product_hidden, ";")
var/list/temp_hideamt = text2list(src.product_hideamt, ";")
var/list/temp_coin = text2list(src.product_coin, ";")
var/list/temp_coin_amt = text2list(src.product_coin_amt, ";")
src.last_slogan = world.time + rand(0, slogan_delay) //So not all machines speak at the exact same time. The first time this machine says something will be at slogantime + this random value, so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
// So not all machines speak at the exact same time.
// The first time this machine says something will be at slogantime + this random value,
// so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
src.last_slogan = world.time + rand(0, slogan_delay)
//Little sanity check here
if ((isnull(temp_paths)) || (isnull(temp_amounts)) || (temp_paths.len != temp_amounts.len) || (temp_hidden.len != temp_hideamt.len))
stat |= BROKEN
power_change()
return
src.build_inventory(temp_paths,temp_amounts)
src.build_inventory(products)
//Add hidden inventory
src.build_inventory(temp_hidden,temp_hideamt, 1)
src.build_inventory(temp_coin,temp_coin_amt, 0, 1)
src.build_inventory(contraband, 1)
src.build_inventory(premium, 0, 1)
power_change()
return
@@ -104,35 +95,25 @@
return
/obj/machinery/vending/proc/build_inventory(var/list/path_list,var/list/amt_list,hidden=0,req_coin=0)
/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0)
for(var/typepath in productlist)
var/amount = productlist[typepath]
if(isnull(amount)) amount = 1
for(var/p=1, p <= path_list.len ,p++)
var/checkpath = text2path(path_list[p])
if (!checkpath)
continue
var/obj/temp = new checkpath(src)
var/datum/data/vending_product/R = new /datum/data/vending_product( )
R.product_name = capitalize(temp.name)
R.product_path = path_list[p]
var/atom/temp = new typepath(null)
var/datum/data/vending_product/R = new /datum/data/vending_product()
R.product_name = temp.name
R.product_path = typepath
R.amount = amount
R.display_color = pick("red","blue","green")
// R. = text2num(amt_list[p])
// src.product_records += R
if(hidden)
R.amount = text2num(amt_list[p])
src.hidden_records += R
hidden_records += R
else if(req_coin)
R.amount = text2num(amt_list[p])
src.coin_records += R
coin_records += R
else
R.amount = text2num(amt_list[p])
src.product_records += R
del(temp)
// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]"
continue
product_records += R
// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]"
return
/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -152,7 +133,7 @@
if(src.panel_open)
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin) && product_coin != "")
else if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
user.drop_item()
W.loc = src
coin = W
@@ -180,7 +161,7 @@
var/dat = "<TT><center><b>[vendorname]</b></center><hr /><br>" //display the name, and added a horizontal rule
dat += "<b>Select an item: </b><br><br>" //the rest is just general spacing and bolding
if (product_coin != "")
if (premium.len > 0)
dat += "<b>Coin slot:</b> [coin ? coin : "No coin inserted"] (<a href='byond://?src=\ref[src];remove_coin=1'>Remove</A>)<br><br>"
if (src.product_records.len == 0)
@@ -276,15 +257,7 @@
src.vend_ready = 0 //One thing at a time!!
var/datum/data/vending_product/R = locate(href_list["vend"])
if (!R || !istype(R))
src.vend_ready = 1
return
var/product_path = text2path(R.product_path)
if (!product_path)
src.vend_ready = 1
return
if (R.amount <= 0)
if (!R || !istype(R) || !R.product_path || R.amount <= 0)
src.vend_ready = 1
return
@@ -312,7 +285,7 @@
if (src.icon_vend) //Show the vending animation if needed
flick(src.icon_vend,src)
spawn(src.vend_delay)
new product_path(get_turf(src))
new R.product_path(get_turf(src))
src.vend_ready = 1
return
@@ -399,7 +372,7 @@
for(var/datum/data/vending_product/R in src.product_records)
if (R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = text2path(R.product_path)
var/dump_path = R.product_path
if (!dump_path)
continue
@@ -422,7 +395,7 @@
for(var/datum/data/vending_product/R in src.product_records)
if (R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = text2path(R.product_path)
var/dump_path = R.product_path
if (!dump_path)
continue
@@ -505,13 +478,10 @@
desc = ""
icon = ''
icon_state = ""
product_paths = ""
product_amounts = ""
vend_delay = 15
product_hidden = ""
product_hideamt = ""
product_slogans = ""
product_ads = ""
products = list()
contraband = list()
premium = list()
*/
@@ -531,120 +501,119 @@
desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one."
icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles
icon_deny = "boozeomat-deny"
product_paths = "/obj/item/weapon/reagent_containers/food/drinks/bottle/gin;/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey;/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla;/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka;/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth;/obj/item/weapon/reagent_containers/food/drinks/bottle/rum;/obj/item/weapon/reagent_containers/food/drinks/bottle/wine;/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac;/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua;/obj/item/weapon/reagent_containers/food/drinks/beer;/obj/item/weapon/reagent_containers/food/drinks/ale;/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/cream;/obj/item/weapon/reagent_containers/food/drinks/tonic;/obj/item/weapon/reagent_containers/food/drinks/cola;/obj/item/weapon/reagent_containers/food/drinks/sodawater;/obj/item/weapon/reagent_containers/food/drinks/drinkingglass;/obj/item/weapon/reagent_containers/food/drinks/ice"
product_amounts = "5;5;5;5;5;5;5;5;5;6;6;4;4;4;4;8;8;15;30;9"
products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5,/obj/item/weapon/reagent_containers/food/drinks/beer = 6,
/obj/item/weapon/reagent_containers/food/drinks/ale = 6,/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 4,
/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4,
/obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/tonic = 8,
/obj/item/weapon/reagent_containers/food/drinks/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/sodawater = 15,
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10)
vend_delay = 15
product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/tea"
product_hideamt = "10"
product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?"
product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!"
req_access_txt = "25"
/obj/machinery/vending/assist
product_amounts = "5;3;4;1;4"
product_hidden = "/obj/item/device/flashlight;obj/item/device/assembly/timer"
product_paths = "/obj/item/device/assembly/prox_sensor;/obj/item/device/assembly/igniter;/obj/item/device/assembly/signaler;/obj/item/weapon/wirecutters;/obj/item/weapon/cartridge/signal"
product_hideamt = "5;2"
products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4,
/obj/item/weapon/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4)
contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2)
product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!"
/obj/machinery/vending/coffee
name = "Hot Drinks machine"
desc = "A vending machine which dispenses hot drinks."
product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies"
icon_state = "coffee"
icon_vend = "coffee-vend"
product_paths = "/obj/item/weapon/reagent_containers/food/drinks/coffee;/obj/item/weapon/reagent_containers/food/drinks/tea;/obj/item/weapon/reagent_containers/food/drinks/h_chocolate"
product_amounts = "25;25;25"
vend_delay = 34
product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/ice"
product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies"
product_hideamt = "10"
products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10)
/obj/machinery/vending/snack
name = "Getmore Chocolate Corp"
desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars"
icon_state = "snack"
product_paths = "/obj/item/weapon/reagent_containers/food/snacks/candy;/obj/item/weapon/reagent_containers/food/drinks/dry_ramen;/obj/item/weapon/reagent_containers/food/snacks/chips;/obj/item/weapon/reagent_containers/food/snacks/sosjerky;/obj/item/weapon/reagent_containers/food/snacks/no_raisin;/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie;/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers"
product_amounts = "6;6;6;6;6;6;6"
product_slogans = "Try our new nougat bar!;Twice the calories for half the price!"
product_hidden = "/obj/item/weapon/reagent_containers/food/snacks/syndicake"
product_hideamt = "6"
product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!"
icon_state = "snack"
products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6,
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6)
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
/obj/machinery/vending/cola
name = "Robust Softdrinks"
desc = "A softdrink vendor provided by Robust Industries, LLC."
icon_state = "Cola_Machine"
product_paths = "/obj/item/weapon/reagent_containers/food/drinks/cola;/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind;/obj/item/weapon/reagent_containers/food/drinks/dr_gibb;/obj/item/weapon/reagent_containers/food/drinks/starkist;/obj/item/weapon/reagent_containers/food/drinks/space_up"
product_amounts = "10;10;10;10;10"
product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!"
product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/thirteenloko"
product_hideamt = "5"
product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
products = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 10,
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10,
/obj/item/weapon/reagent_containers/food/drinks/space_up = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5)
//This one's from bay12
/obj/machinery/vending/cart
name = "PTech"
desc = "Cartridges for PDAs"
product_slogans = "Carts to go!"
icon_state = "cart"
icon_deny = "cart-deny"
product_paths = "/obj/item/weapon/cartridge/medical;/obj/item/weapon/cartridge/engineering;/obj/item/weapon/cartridge/security;/obj/item/weapon/cartridge/janitor;/obj/item/weapon/cartridge/signal/toxins;/obj/item/device/pda/heads;/obj/item/weapon/cartridge/captain;/obj/item/weapon/cartridge/quartermaster"
product_amounts = "10;10;10;10;10;10;3;10"
product_slogans = "Carts to go!"
product_hidden = ""
product_hideamt = ""
product_coin = ""
product_coin_amt = ""
products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10,
/obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/toxins = 10,/obj/item/device/pda/heads = 10,
/obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10)
/obj/machinery/vending/cigarette
name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating
desc = "If you want to get cancer, might as well do it in style"
icon_state = "cigs"
product_paths = "/obj/item/weapon/storage/fancy/cigarettes;/obj/item/weapon/storage/box/matches;/obj/item/weapon/lighter/random"
product_amounts = "10;10;4"
product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!"
vend_delay = 34
product_hidden = "/obj/item/weapon/lighter/zippo"
product_hideamt = "4"
product_coin = "/obj/item/clothing/mask/cigarette/cigar/havana"
product_coin_amt = "2"
product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs."
vend_delay = 34
icon_state = "cigs"
products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4)
contraband = list(/obj/item/weapon/lighter/zippo = 4)
premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2)
/obj/machinery/vending/medical
name = "NanoMed Plus"
desc = "Medical drug dispenser."
icon_state = "med"
icon_deny = "med-deny"
req_access_txt = "5"
product_paths = "/obj/item/weapon/reagent_containers/glass/bottle/antitoxin;/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline;/obj/item/weapon/reagent_containers/glass/bottle/stoxin;/obj/item/weapon/reagent_containers/glass/bottle/toxin;/obj/item/weapon/reagent_containers/syringe/antiviral;/obj/item/weapon/reagent_containers/syringe;/obj/item/device/healthanalyzer;/obj/item/weapon/reagent_containers/glass/beaker;/obj/item/weapon/reagent_containers/dropper"
product_amounts = "4;4;4;4;4;12;5;4;2"
product_hidden = "/obj/item/weapon/reagent_containers/pill/tox;/obj/item/weapon/reagent_containers/pill/stox;/obj/item/weapon/reagent_containers/pill/antitox"
product_hideamt = "3;4;6"
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!"
req_access_txt = "5"
products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4,
/obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4,
/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12,
/obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2)
contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6)
//This one's from bay12
/obj/machinery/vending/plasmaresearch
name = "Toximate 3000"
desc = "All the fine parts you need in one vending machine!"
product_paths = "/obj/item/clothing/under/rank/scientist;/obj/item/clothing/suit/bio_suit;/obj/item/clothing/head/bio_hood;/obj/item/device/transfer_valve;/obj/item/device/assembly/signaler;/obj/item/device/assembly/prox_sensor;/obj/item/device/assembly/igniter;/obj/item/device/assembly/timer"
product_amounts = "6;6;6;6;6"
product_hidden = ""
product_hideamt = ""
product_coin = ""
product_coin_amt = ""
products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6,
/obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6,
/obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6)
/obj/machinery/vending/wallmed1
name = "NanoMed"
desc = "Wall-mounted Medical Equipment dispenser."
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?"
icon_state = "wallmed"
icon_deny = "wallmed-deny"
req_access_txt = "5"
product_paths = "/obj/item/stack/medical/bruise_pack;/obj/item/stack/medical/ointment;/obj/item/weapon/reagent_containers/syringe/inaprovaline;/obj/item/device/healthanalyzer"
product_amounts = "2;2;4;1"
product_hidden = "/obj/item/weapon/reagent_containers/syringe/antitoxin;/obj/item/weapon/reagent_containers/syringe/antiviral;/obj/item/weapon/reagent_containers/pill/tox"
product_hideamt = "4;4;1"
density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?"
products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/syringe/inaprovaline = 4,/obj/item/device/healthanalyzer = 1)
contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1)
/obj/machinery/vending/wallmed2
name = "NanoMed"
@@ -652,84 +621,76 @@
icon_state = "wallmed"
icon_deny = "wallmed-deny"
req_access_txt = "5"
product_paths = "/obj/item/weapon/reagent_containers/syringe/inaprovaline;/obj/item/weapon/reagent_containers/syringe/antitoxin;/obj/item/stack/medical/bruise_pack;/obj/item/stack/medical/ointment;/obj/item/device/healthanalyzer"
product_amounts = "5;3;3;3;3"
product_hidden = "/obj/item/weapon/reagent_containers/pill/tox"
product_hideamt = "3"
density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude
products = list(/obj/item/weapon/reagent_containers/syringe/inaprovaline = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3,
/obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3)
contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3)
/obj/machinery/vending/security
name = "SecTech"
desc = "A security equipment vendor"
product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?"
icon_state = "sec"
icon_deny = "sec-deny"
req_access_txt = "1"
product_paths = "/obj/item/weapon/handcuffs;/obj/item/weapon/grenade/flashbang;/obj/item/device/flash;/obj/item/weapon/reagent_containers/food/snacks/donut/normal;/obj/item/weapon/storage/box/evidence"
product_amounts = "8;4;5;12;6"
product_hidden = "/obj/item/clothing/glasses/sunglasses;/obj/item/weapon/storage/fancy/donut_box"
product_hideamt = "2;2"
product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?"
products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5,
/obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6)
contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2)
/obj/machinery/vending/hydronutrients
name = "NutriMax"
desc = "A plant nutrients vendor"
product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!"
product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..."
icon_state = "nutri"
icon_deny = "nutri-deny"
product_paths = "/obj/item/nutrient/ez;/obj/item/nutrient/l4z;/obj/item/nutrient/rh;/obj/item/weapon/pestspray;/obj/item/weapon/reagent_containers/syringe;/obj/item/weapon/storage/bag/plants"
product_amounts = "35;25;15;20;5;5"
product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!"
product_hidden = "/obj/item/weapon/reagent_containers/glass/bottle/ammonia;/obj/item/weapon/reagent_containers/glass/bottle/diethylamine"
product_hideamt = "10;5"
product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..."
products = list(/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20,
/obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5)
contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
/obj/machinery/vending/hydroseeds
name = "MegaSeed Servitor"
desc = "When you need seeds fast!"
icon_state = "seeds"
product_paths = "/obj/item/seeds/bananaseed;/obj/item/seeds/berryseed;/obj/item/seeds/carrotseed;/obj/item/seeds/chantermycelium;/obj/item/seeds/chiliseed;/obj/item/seeds/cornseed;/obj/item/seeds/eggplantseed;/obj/item/seeds/potatoseed;/obj/item/seeds/replicapod;/obj/item/seeds/soyaseed;/obj/item/seeds/sunflowerseed;/obj/item/seeds/tomatoseed;/obj/item/seeds/towermycelium;/obj/item/seeds/wheatseed;/obj/item/seeds/appleseed;/obj/item/seeds/poppyseed;/obj/item/seeds/ambrosiavulgarisseed;/obj/item/seeds/whitebeetseed;/obj/item/seeds/watermelonseed;/obj/item/seeds/limeseed;/obj/item/seeds/lemonseed;/obj/item/seeds/orangeseed;/obj/item/seeds/grassseed;/obj/item/seeds/cocoapodseed;/obj/item/seeds/cabbageseed;/obj/item/seeds/grapeseed;/obj/item/seeds/pumpkinseed;/obj/item/seeds/cherryseed"
product_amounts = "3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3"
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
product_hidden = "/obj/item/seeds/amanitamycelium;/obj/item/seeds/glowshroom;/obj/item/seeds/libertymycelium;/obj/item/seeds/nettleseed;/obj/item/seeds/plumpmycelium;/obj/item/seeds/reishimycelium"
product_hideamt = "2;2;2;2;2;2"
product_coin = "/obj/item/toy/waterflower"
product_coin_amt = "1"
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3,
/obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3,
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
/obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
premium = list(/obj/item/toy/waterflower = 1)
/obj/machinery/vending/magivend
name = "MagiVend"
desc = "A magic vending machine."
icon_state = "MagiVend"
product_amounts = "1;1;1;1;1;2"
product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!"
product_paths = "/obj/item/clothing/head/wizard;/obj/item/clothing/suit/wizrobe;/obj/item/clothing/head/wizard/red;/obj/item/clothing/suit/wizrobe/red;/obj/item/clothing/shoes/sandal;/obj/item/weapon/staff"
vend_delay = 15
vend_reply = "Have an enchanted evening!"
product_hidden = "/obj/item/weapon/reagent_containers/glass/bottle/wizarditis" //No one can get to the machine to hack it anyways
product_hideamt = "1" //Just one, for the lulz, not like anyone can get it - Microwave
product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!"
products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2)
contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave
/obj/machinery/vending/dinnerware
name = "Dinnerware"
desc = "A kitchen and restaurant equipment vendor"
icon_state = "dinnerware"
product_paths = "/obj/item/weapon/tray;/obj/item/weapon/kitchen/utensil/fork;/obj/item/weapon/kitchenknife;/obj/item/weapon/reagent_containers/food/drinks/drinkingglass;/obj/item/clothing/suit/chef/classic"
product_amounts = "8;6;3;8;2"
//product_amounts = "8;5;4" Old totals
product_hidden = "/obj/item/weapon/kitchen/utensil/spoon;/obj/item/weapon/kitchen/utensil/knife;/obj/item/weapon/kitchen/rollingpin;/obj/item/weapon/butch"
product_hideamt = "2;2;2;2"
product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..."
icon_state = "dinnerware"
products = list(/obj/item/weapon/tray = 8,/obj/item/weapon/kitchen/utensil/fork = 6,/obj/item/weapon/kitchenknife = 3,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 8,/obj/item/clothing/suit/chef/classic = 2)
contraband = list(/obj/item/weapon/kitchen/utensil/spoon = 2,/obj/item/weapon/kitchen/utensil/knife = 2,/obj/item/weapon/kitchen/rollingpin = 2, /obj/item/weapon/butch = 2)
/obj/machinery/vending/sovietsoda
name = "BODA"
desc = "Old sweet water vending machine"
icon_state = "sovietsoda"
product_paths = "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda"
product_amounts = "30"
//product_amounts = "8;5;4" Old totals
product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cola"
product_hideamt = "20"
product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem."
products = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/soda = 30)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/cola = 20)
/obj/machinery/vending/tool
name = "YouTool"
@@ -737,12 +698,10 @@
icon_state = "tool"
icon_deny = "tool-deny"
//req_access_txt = "12" //Maintenance access
product_paths = "/obj/item/weapon/cable_coil/random;/obj/item/weapon/crowbar;/obj/item/weapon/weldingtool;/obj/item/weapon/wirecutters;/obj/item/weapon/wrench;/obj/item/device/analyzer;/obj/item/device/t_scanner;/obj/item/weapon/screwdriver"
product_amounts = "10;5;3;5;5;5;5;5"
product_hidden = "/obj/item/weapon/weldingtool/hugeetank;/obj/item/clothing/gloves/fyellow"
product_hideamt = "2;2"
product_coin = "/obj/item/clothing/gloves/yellow"
product_coin_amt = "1"
products = list(/obj/item/weapon/cable_coil/random = 10,/obj/item/weapon/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/wirecutters = 5,
/obj/item/weapon/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/screwdriver = 5)
contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2)
premium = list(/obj/item/clothing/gloves/yellow = 1)
/obj/machinery/vending/engivend
name = "Engi-Vend"
@@ -750,12 +709,9 @@
icon_state = "engivend"
icon_deny = "engivend-deny"
req_access_txt = "11" //Engineering Equipment access
product_paths = "/obj/item/clothing/glasses/meson;/obj/item/device/multitool;/obj/item/weapon/airlock_electronics;/obj/item/weapon/module/power_control;/obj/item/weapon/cell/high"
product_amounts = "2;4;10;10;10"
product_hidden = "/obj/item/weapon/cell/potato"
product_hideamt = "3"
product_coin = "/obj/item/weapon/storage/belt/utility"
product_coin_amt = "3"
products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/cell/high = 10)
contraband = list(/obj/item/weapon/cell/potato = 3)
premium = list(/obj/item/weapon/storage/belt/utility = 3)
//This one's from bay12
/obj/machinery/vending/engineering
@@ -764,12 +720,15 @@
icon_state = "engi"
icon_deny = "engi-deny"
req_access_txt = "11"
product_paths = "/obj/item/clothing/under/rank/chief_engineer;/obj/item/clothing/under/rank/engineer;/obj/item/clothing/shoes/orange;/obj/item/clothing/head/helmet/hardhat;/obj/item/weapon/storage/belt/utility;/obj/item/clothing/glasses/meson;/obj/item/clothing/gloves/yellow;/obj/item/weapon/screwdriver;/obj/item/weapon/crowbar;/obj/item/weapon/wirecutters;/obj/item/device/multitool;/obj/item/weapon/wrench;/obj/item/device/t_scanner;/obj/item/weapon/CableCoil/power;/obj/item/weapon/circuitry;/obj/item/weapon/cell;/obj/item/weapon/weldingtool;/obj/item/clothing/head/helmet/welding;/obj/item/weapon/light/tube;/obj/item/clothing/suit/fire;/obj/item/weapon/stock_parts/scanning_module;/obj/item/weapon/stock_parts/micro_laser;/obj/item/weapon/stock_parts/matter_bin;/obj/item/weapon/stock_parts/manipulator;/obj/item/weapon/stock_parts/console_screen"
// product_amounts = "4;4;4;4;4;4;4;12;12;12;12;12;12;8;4;8;8;8;10;4"
product_hidden = ""
product_hideamt = ""
product_coin = ""
product_coin_amt = ""
products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4,
/obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/screwdriver = 12,
/obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12,
/obj/item/weapon/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8,
/obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5,
/obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5)
// There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty.
// Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it.
// The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu
//This one's from bay12
/obj/machinery/vending/robotics
@@ -778,9 +737,9 @@
icon_state = "robotics"
icon_deny = "robotics-deny"
req_access_txt = "29"
product_paths = "/obj/item/clothing/suit/storage/labcoat;/obj/item/clothing/under/rank/roboticist;/obj/item/weapon/cable_coil;/obj/item/device/flash;/obj/item/weapon/cell/high;/obj/item/device/assembly/prox_sensor;/obj/item/device/assembly/signaler;/obj/item/device/healthanalyzer;/obj/item/weapon/scalpel;/obj/item/weapon/circular_saw;/obj/item/weapon/tank/anesthetic;/obj/item/clothing/mask/medical;/obj/item/weapon/screwdriver;/obj/item/weapon/crowbar"
product_amounts = "4;4;4;4;12"
product_hidden = ""
product_hideamt = ""
product_coin = ""
product_coin_amt = ""
products = list(/obj/item/clothing/suit/storage/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/weapon/cable_coil = 4,/obj/item/device/flash = 4,
/obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3,
/obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5,
/obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5)
//everything after the power cell had no amounts, I improvised. -Sayu
@@ -193,9 +193,9 @@
return 0
var/to_inject = min(R.volume, inject_amount)
if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
occupant_message("Injecting [occupant] with [to_inject] units of [R.name].")
log_message("Injecting [occupant] with [to_inject] units of [R.name].")
SG.reagents.trans_id_to(occupant,R.id,to_inject)
occupant_message("[occupant] injected with [to_inject] units of [R.name].")
log_message("[occupant] injected with [to_inject] units of [R.name].")
update_equip_info()
return
+3 -3
View File
@@ -27,7 +27,7 @@
set_ready_state(0)
playsound(chassis, fire_sound, 50, 1)
var/obj/item/projectile/A = new projectile(curloc)
A.original = targloc
A.original = target
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
@@ -209,7 +209,7 @@
playsound(chassis, fire_sound, 80, 1)
var/obj/item/projectile/A = new projectile(curloc)
src.projectiles--
A.original = targloc
A.original = target
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
@@ -251,7 +251,7 @@
playsound(chassis, fire_sound, 50, 1)
var/obj/item/projectile/A = new projectile(curloc)
src.projectiles--
A.original = targloc
A.original = target
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
+1 -1
View File
@@ -421,7 +421,7 @@
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MECHA",src,user:wear_suit)
return
if ( ((HULK in user.mutations) || (SUPRSTR in user.augmentations)) && !prob(src.deflect_chance))
if ((HULK in user.mutations) && !prob(src.deflect_chance))
src.take_damage(15)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
user.visible_message("<font color='red'><b>[user] hits [src.name], doing some damage.</b></font>", "<font color='red'><b>You hit [src.name] with all your might. The metal creaks and bends.</b></font>")
+1
View File
@@ -402,6 +402,7 @@
icon = 'icons/obj/module.dmi'
icon_state = "std_mod"
item_state = "electronic"
board_type = "other"
flags = FPRINT | TABLEPASS | CONDUCT
force = 5.0
w_class = 2.0
+16 -18
View File
@@ -105,7 +105,7 @@
return
/obj/effect/alien/resin/attack_hand()
if ((HULK in usr.mutations) || (SUPRSTR in usr.augmentations))
if (HULK in usr.mutations)
usr << "\blue You easily destroy the [name]."
for(var/mob/O in oviewers(src))
O.show_message("\red [usr] destroys the [name]!", 1)
@@ -414,23 +414,21 @@ Alien plants should do something if theres a lot of poison
return
proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
icon_state = "egg_hatched"
flick("egg_opening", src)
status = BURSTING
spawn(15)
status = BURST
loc.contents += child//need to write the code for giving it to the alien later
if(kill && istype(child))
child.Die()
else
for(var/mob/M in range(1,src))
if(CanHug(M))
child.Attach(M)
break
return
if(status == GROWN || status == GROWING)
var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
icon_state = "egg_hatched"
flick("egg_opening", src)
status = BURSTING
spawn(15)
status = BURST
loc.contents += child//need to write the code for giving it to the alien later
if(kill && istype(child))
child.Die()
else
for(var/mob/M in range(1,src))
if(CanHug(M))
child.Attach(M)
break
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
+3 -1
View File
@@ -1,3 +1,4 @@
/*
/obj/effect/biomass
icon = 'icons/obj/biomass.dmi'
icon_state = "stage1"
@@ -121,4 +122,5 @@
return 0
if(location.density)
return 0
return 1
return 1
*/
@@ -67,7 +67,7 @@
obj/structure/sign/poster
name = "poster"
desc = "A large piece of space-resistant printed paper. It's considered contraband."
desc = "A large piece of space-resistant printed paper. "
icon = 'icons/obj/contraband.dmi'
anchored = 1
var/serial_number //Will hold the value of src.loc if nobody initialises it

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