Merge branch 'master' into revenant_TK
This commit is contained in:
@@ -45,6 +45,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
|
||||
considered_hull_exterior = TRUE
|
||||
sound_environment = SOUND_AREA_SPACE
|
||||
|
||||
/area/space/nearstation
|
||||
icon_state = "space_near"
|
||||
@@ -70,6 +71,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station.
|
||||
valid_territory = FALSE
|
||||
ambientsounds = MINING
|
||||
sound_environment = SOUND_AREA_ASTEROID
|
||||
|
||||
/area/asteroid/nearstation
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
@@ -107,7 +109,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/maintenance
|
||||
ambientsounds = MAINTENANCE
|
||||
valid_territory = FALSE
|
||||
|
||||
sound_environment = SOUND_AREA_TUNNEL_ENCLOSED
|
||||
|
||||
//Departments
|
||||
|
||||
@@ -122,6 +124,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/maintenance/department/crew_quarters/bar
|
||||
name = "Bar Maintenance"
|
||||
icon_state = "maint_bar"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/maintenance/department/crew_quarters/dorms
|
||||
name = "Dormitory Maintenance"
|
||||
@@ -265,6 +268,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/hallway
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_PUBLIC
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/hallway/primary/aft
|
||||
name = "Aft Primary Hallway"
|
||||
@@ -333,30 +337,36 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Bridge"
|
||||
icon_state = "bridge"
|
||||
music = "signal"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/bridge/meeting_room
|
||||
name = "Heads of Staff Meeting Room"
|
||||
icon_state = "meeting"
|
||||
music = null
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/bridge/meeting_room/council
|
||||
name = "Council Chamber"
|
||||
icon_state = "meeting"
|
||||
music = null
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/bridge/showroom/corporate
|
||||
name = "Corporate Showroom"
|
||||
icon_state = "showroom"
|
||||
music = null
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/crew_quarters/heads/captain
|
||||
name = "Captain's Office"
|
||||
icon_state = "captain"
|
||||
clockwork_warp_allowed = FALSE
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/heads/captain/private
|
||||
name = "Captain's Quarters"
|
||||
icon_state = "captain"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/heads/chief
|
||||
name = "Chief Engineer's Office"
|
||||
@@ -401,10 +411,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/comms
|
||||
name = "Communications Relay"
|
||||
icon_state = "tcomsatcham"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/server
|
||||
name = "Messaging Server Room"
|
||||
icon_state = "server"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
//Crew
|
||||
|
||||
@@ -413,6 +425,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "Sleep"
|
||||
safe = TRUE
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/crew_quarters/dorms/male
|
||||
name = "Male Dorm"
|
||||
@@ -431,6 +444,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/toilet
|
||||
name = "Dormitory Toilets"
|
||||
icon_state = "toilet"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/crew_quarters/toilet/auxiliary
|
||||
name = "Auxiliary Restrooms"
|
||||
@@ -465,6 +479,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Lounge"
|
||||
icon_state = "yellow"
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
/area/crew_quarters/arcade
|
||||
name = "Arcade"
|
||||
@@ -502,15 +517,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/kitchen/backroom
|
||||
name = "Kitchen Coldroom"
|
||||
icon_state = "kitchen"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/crew_quarters/bar
|
||||
name = "Bar"
|
||||
icon_state = "bar"
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/bar/atrium
|
||||
name = "Atrium"
|
||||
icon_state = "bar"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/electronic_marketing_den
|
||||
name = "Electronic Marketing Den"
|
||||
@@ -526,6 +544,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/theatre
|
||||
name = "Theatre"
|
||||
icon_state = "Theatre"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/theatre/abandoned
|
||||
name = "Abandoned Theatre"
|
||||
@@ -546,10 +565,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "library"
|
||||
flags_1 = NONE
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_LARGE_SOFTFLOOR
|
||||
|
||||
/area/library/lounge
|
||||
name = "Library Lounge"
|
||||
icon_state = "library"
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
/area/library/abandoned
|
||||
name = "Abandoned Library"
|
||||
@@ -564,6 +585,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
clockwork_warp_allowed = FALSE
|
||||
clockwork_warp_fail = "The consecration here prevents you from warping in."
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/chapel/main
|
||||
name = "Chapel"
|
||||
@@ -579,6 +601,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/chapel/asteroid
|
||||
name = "Chapel Asteroid"
|
||||
icon_state = "explored"
|
||||
sound_environment = SOUND_AREA_ASTEROID
|
||||
|
||||
/area/chapel/asteroid/monastery
|
||||
name = "Monastery Asteroid"
|
||||
@@ -590,12 +613,14 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/lawoffice
|
||||
name = "Law Office"
|
||||
icon_state = "law"
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
|
||||
//Engineering
|
||||
|
||||
/area/engine
|
||||
ambientsounds = ENGINEERING
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/engine/engine_smes
|
||||
name = "Engineering SMES"
|
||||
@@ -613,14 +638,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engine/atmospherics_engine
|
||||
name = "Atmospherics Engine"
|
||||
icon_state = "atmos_engine"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/engine/supermatter
|
||||
name = "Supermatter Engine"
|
||||
icon_state = "engine_sm"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engine/break_room
|
||||
name = "Engineering Foyer"
|
||||
icon_state = "engine_foyer"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engine/gravity_generator
|
||||
name = "Gravity Generator Room"
|
||||
@@ -635,6 +663,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engine/storage
|
||||
name = "Engineering Storage"
|
||||
icon_state = "engi_storage"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engine/storage_shared
|
||||
name = "Shared Engineering Storage"
|
||||
@@ -654,10 +683,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
blob_allowed = FALSE
|
||||
flags_1 = NONE
|
||||
ambientsounds = ENGINEERING
|
||||
sound_environment = SOUND_AREA_SPACE
|
||||
|
||||
/area/solar/fore
|
||||
name = "Fore Solar Array"
|
||||
icon_state = "yellow"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/solar/aft
|
||||
name = "Aft Solar Array"
|
||||
@@ -763,6 +794,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "gateway"
|
||||
music = "signal"
|
||||
ambientsounds = ENGINEERING
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
//MedBay
|
||||
|
||||
@@ -770,6 +802,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Medical"
|
||||
icon_state = "medbay3"
|
||||
ambientsounds = MEDICAL
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/medical/clinic
|
||||
name = "Clinic"
|
||||
@@ -780,6 +813,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Abandoned Medbay"
|
||||
icon_state = "medbay3"
|
||||
music = 'sound/ambience/signal.ogg'
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/medical/medbay/central
|
||||
name = "Medbay Central"
|
||||
@@ -821,6 +855,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/medical/patients_rooms
|
||||
name = "Patients' Rooms"
|
||||
icon_state = "patients"
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
/area/medical/patients_rooms/room_a
|
||||
name = "Patient Room A"
|
||||
@@ -839,6 +874,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Morgue"
|
||||
icon_state = "morgue"
|
||||
ambientsounds = SPOOKY
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/medical/chemistry
|
||||
name = "Chemistry"
|
||||
@@ -879,6 +915,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Security"
|
||||
icon_state = "security"
|
||||
ambientsounds = HIGHSEC
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/security/main
|
||||
name = "Security Office"
|
||||
@@ -891,6 +928,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/courtroom
|
||||
name = "Courtroom"
|
||||
icon_state = "courtroom"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/security/prison
|
||||
name = "Prison Wing"
|
||||
@@ -903,10 +941,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/processing/cremation
|
||||
name = "Security Crematorium"
|
||||
icon_state = "sec_prison"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/security/warden
|
||||
name = "Brig Control"
|
||||
icon_state = "Warden"
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
/area/security/armory
|
||||
name = "Armory"
|
||||
@@ -920,6 +960,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/detectives_office/private_investigators_office
|
||||
name = "Private Investigator's Office"
|
||||
icon_state = "detective"
|
||||
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
|
||||
|
||||
/area/security/range
|
||||
name = "Firing Range"
|
||||
@@ -997,18 +1038,17 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/quartermaster
|
||||
name = "Quartermasters"
|
||||
icon_state = "quart"
|
||||
|
||||
///////////WORK IN PROGRESS//////////
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/quartermaster/sorting
|
||||
name = "Delivery Office"
|
||||
icon_state = "cargo_delivery"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/quartermaster/warehouse
|
||||
name = "Warehouse"
|
||||
icon_state = "cargo_warehouse"
|
||||
|
||||
////////////WORK IN PROGRESS//////////
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/quartermaster/office
|
||||
name = "Cargo Office"
|
||||
@@ -1017,6 +1057,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/quartermaster/storage
|
||||
name = "Cargo Bay"
|
||||
icon_state = "cargo_bay"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/quartermaster/qm
|
||||
name = "Quartermaster's Office"
|
||||
@@ -1046,6 +1087,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Custodial Closet"
|
||||
icon_state = "janitor"
|
||||
flags_1 = NONE
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/janitor/aux
|
||||
name = "Auxiliary Custodial Closet"
|
||||
@@ -1055,6 +1097,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/hydroponics
|
||||
name = "Hydroponics"
|
||||
icon_state = "hydro"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/hydroponics/lobby
|
||||
name = "Hydroponics Lobby"
|
||||
@@ -1067,6 +1110,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/hydroponics/garden/abandoned
|
||||
name = "Abandoned Garden"
|
||||
icon_state = "abandoned_garden"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/hydroponics/garden/monastery
|
||||
name = "Monastery Garden"
|
||||
@@ -1077,6 +1121,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/science
|
||||
name = "Science Division"
|
||||
icon_state = "toxlab"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/science/observatory
|
||||
name = "Research Observatory"
|
||||
@@ -1167,12 +1212,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/science/research/abandoned
|
||||
name = "Abandoned Research Lab"
|
||||
icon_state = "medresearch"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/science/nanite
|
||||
name = "Nanite Lab"
|
||||
icon_state = "toxmisc"
|
||||
|
||||
//Storage
|
||||
/area/storage
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/storage/tools
|
||||
name = "Auxiliary Tool Storage"
|
||||
@@ -1242,6 +1290,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Construction Area"
|
||||
icon_state = "yellow"
|
||||
ambientsounds = ENGINEERING
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/construction/minisat_exterior
|
||||
name = "Minisat Exterior"
|
||||
@@ -1250,6 +1299,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/construction/mining/aux_base
|
||||
name = "Auxiliary Base Construction"
|
||||
icon_state = "yellow"
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/construction/mining/aux_base/closet
|
||||
name = "Auxiliary Closet Construction"
|
||||
@@ -1305,6 +1355,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
|
||||
//AI
|
||||
/area/ai_monitored
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/ai_monitored/security/armory
|
||||
name = "Armory"
|
||||
@@ -1329,10 +1381,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/ai_monitored/turret_protected/ai_upload
|
||||
name = "AI Upload Chamber"
|
||||
icon_state = "ai_upload"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/ai_monitored/turret_protected/ai_upload_foyer
|
||||
name = "AI Upload Access"
|
||||
icon_state = "ai_foyer"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/ai_monitored/turret_protected/ai
|
||||
name = "AI Chamber"
|
||||
@@ -1341,6 +1395,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/ai_monitored/turret_protected/aisat
|
||||
name = "AI Satellite"
|
||||
icon_state = "ai"
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
/area/ai_monitored/turret_protected/aisat/atmos
|
||||
name = "AI Satellite Atmos"
|
||||
@@ -1365,6 +1420,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/ai_monitored/turret_protected/aisat_interior
|
||||
name = "AI Satellite Antechamber"
|
||||
icon_state = "ai"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/ai_monitored/turret_protected/AIsatextFP
|
||||
name = "AI Sat Ext"
|
||||
@@ -1418,6 +1474,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/tcommsat/computer
|
||||
name = "Telecomms Control Room"
|
||||
icon_state = "tcomsatcomp"
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/tcommsat/server
|
||||
name = "Telecomms Server Room"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
clockwork_warp_allowed = FALSE
|
||||
var/list/obj/machinery/camera/motioncameras = list()
|
||||
var/list/datum/weakref/motionTargets = list()
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
/area/ai_monitored/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
+157
-62
@@ -1,16 +1,72 @@
|
||||
// Areas.dm
|
||||
|
||||
|
||||
/**
|
||||
* # area
|
||||
*
|
||||
* A grouping of tiles into a logical space, mostly used by map editors
|
||||
*/
|
||||
/area
|
||||
level = null
|
||||
name = "Space"
|
||||
icon = 'icons/turf/areas.dmi'
|
||||
icon_state = "unknown"
|
||||
layer = AREA_LAYER
|
||||
plane = BLACKNESS_PLANE //Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE.
|
||||
//Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE.
|
||||
plane = BLACKNESS_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
|
||||
var/fire = null
|
||||
///Whether there is an atmos alarm in this area
|
||||
var/atmosalm = FALSE
|
||||
var/poweralm = FALSE
|
||||
var/lightswitch = TRUE
|
||||
|
||||
/// All beauty in this area combined, only includes indoor area.
|
||||
var/totalbeauty = 0
|
||||
/// Beauty average per open turf in the area
|
||||
var/beauty = 0
|
||||
/// If a room is too big it doesn't have beauty.
|
||||
var/beauty_threshold = 150
|
||||
|
||||
/// For space, the asteroid, lavaland, etc. Used with blueprints or with weather to determine if we are adding a new area (vs editing a station room)
|
||||
var/outdoors = FALSE
|
||||
|
||||
/// Size of the area in open turfs, only calculated for indoors areas.
|
||||
var/areasize = 0
|
||||
|
||||
/// Bonus mood for being in this area
|
||||
var/mood_bonus = 0
|
||||
/// Mood message for being here, only shows up if mood_bonus != 0
|
||||
var/mood_message = "<span class='nicegreen'>This area is pretty nice!\n</span>"
|
||||
|
||||
///Will objects this area be needing power?
|
||||
var/requires_power = TRUE
|
||||
/// This gets overridden to 1 for space in area/Initialize().
|
||||
var/always_unpowered = FALSE
|
||||
|
||||
var/power_equip = TRUE
|
||||
var/power_light = TRUE
|
||||
var/power_environ = TRUE
|
||||
|
||||
var/has_gravity = FALSE
|
||||
|
||||
var/parallax_movedir = 0
|
||||
|
||||
var/list/ambientsounds = GENERIC
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
|
||||
|
||||
///This datum, if set, allows terrain generation behavior to be ran on Initialize()
|
||||
// var/datum/map_generator/map_generator
|
||||
|
||||
///Used to decide what kind of reverb the area makes sound have
|
||||
var/sound_environment = SOUND_ENVIRONMENT_NONE
|
||||
|
||||
/// CIT SPECIFIC VARS
|
||||
|
||||
/// Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
|
||||
var/map_name
|
||||
|
||||
@@ -41,29 +97,8 @@
|
||||
/// Considered space for hull shielding
|
||||
var/considered_hull_exterior = FALSE
|
||||
|
||||
var/fire = null
|
||||
var/atmos = TRUE
|
||||
var/atmosalm = FALSE
|
||||
var/poweralm = TRUE
|
||||
var/lightswitch = TRUE
|
||||
|
||||
var/totalbeauty = 0 //All beauty in this area combined, only includes indoor area.
|
||||
var/beauty = 0 // Beauty average per open turf in the area
|
||||
var/beauty_threshold = 150 //If a room is too big it doesn't have beauty.
|
||||
|
||||
var/requires_power = TRUE
|
||||
/// This gets overridden to 1 for space in area/Initialize().
|
||||
var/always_unpowered = FALSE
|
||||
|
||||
/// For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room)
|
||||
var/outdoors = FALSE
|
||||
|
||||
/// Size of the area in open turfs, only calculated for indoors areas.
|
||||
var/areasize = 0
|
||||
|
||||
var/power_equip = TRUE
|
||||
var/power_light = TRUE
|
||||
var/power_environ = TRUE
|
||||
var/music = null
|
||||
var/used_equip = 0
|
||||
var/used_light = 0
|
||||
@@ -72,7 +107,6 @@
|
||||
var/static_light = 0
|
||||
var/static_environ
|
||||
|
||||
var/has_gravity = 0
|
||||
/// Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/noteleport = FALSE
|
||||
/// Hides area from player Teleport function.
|
||||
@@ -84,15 +118,6 @@
|
||||
|
||||
var/no_air = null
|
||||
|
||||
var/parallax_movedir = 0
|
||||
|
||||
var/list/ambientsounds = GENERIC
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
|
||||
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
|
||||
|
||||
@@ -111,10 +136,24 @@
|
||||
|
||||
var/nightshift_public_area = NIGHTSHIFT_AREA_NONE //considered a public area for nightshift
|
||||
|
||||
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
|
||||
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
|
||||
|
||||
/**
|
||||
* A list of teleport locations
|
||||
*
|
||||
* Adding a wizard area teleport list because motherfucking lag -- Urist
|
||||
* I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game
|
||||
*/
|
||||
GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
/**
|
||||
* Generate a list of turfs you can teleport to from the areas list
|
||||
*
|
||||
* Includes areas if they're not a shuttle or not not teleport or have no contents
|
||||
*
|
||||
* The chosen turf is the first item in the areas contents that is a station level
|
||||
*
|
||||
* The returned list of turfs is sorted by name
|
||||
*/
|
||||
/proc/process_teleport_locs()
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/AR = V
|
||||
@@ -128,11 +167,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if (picked && is_station_level(picked.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
|
||||
sortTim(GLOB.teleportlocs, /proc/cmp_text_dsc)
|
||||
|
||||
// ===
|
||||
sortTim(GLOB.teleportlocs, /proc/cmp_text_asc)
|
||||
|
||||
/**
|
||||
* Called when an area loads
|
||||
*
|
||||
* Adds the item to the GLOB.areas_by_type list based on area type
|
||||
*/
|
||||
/area/New()
|
||||
// This interacts with the map loader, so it needs to be set immediately
|
||||
// rather than waiting for atoms to initialize.
|
||||
if (unique)
|
||||
GLOB.areas_by_type[type] = src
|
||||
|
||||
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
|
||||
// generate one using the icon_state
|
||||
if(icon_state && icon_state != "unknown")
|
||||
@@ -141,14 +188,18 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
minimap_color = I.GetPixel(1,1)
|
||||
else // no icon state? use random.
|
||||
minimap_color = rgb(rand(50,70),rand(50,70),rand(50,70)) // This interacts with the map loader, so it needs to be set immediately
|
||||
// rather than waiting for atoms to initialize.
|
||||
if (unique)
|
||||
GLOB.areas_by_type[type] = src
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Initalize this area
|
||||
*
|
||||
* intializes the dynamic area lighting and also registers the area with the z level via
|
||||
* reg_in_areas_in_z
|
||||
*
|
||||
* returns INITIALIZE_HINT_LATELOAD
|
||||
*/
|
||||
/area/Initialize()
|
||||
icon_state = ""
|
||||
layer = AREA_LAYER
|
||||
map_name = name // Save the initial (the name set in the map) name of the area.
|
||||
canSmoothWithAreas = typecacheof(canSmoothWithAreas)
|
||||
|
||||
@@ -202,29 +253,55 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/**
|
||||
* Sets machine power levels in the area
|
||||
*/
|
||||
/area/LateInitialize()
|
||||
if(!base_area) //we don't want to run it twice.
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
update_beauty()
|
||||
|
||||
/area/proc/reg_in_areas_in_z()
|
||||
if(contents.len)
|
||||
var/list/areas_in_z = SSmapping.areas_in_z
|
||||
var/z
|
||||
update_areasize()
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/thing = contents[i]
|
||||
if(!thing)
|
||||
continue
|
||||
z = thing.z
|
||||
break
|
||||
if(!z)
|
||||
WARNING("No z found for [src]")
|
||||
return
|
||||
if(!areas_in_z["[z]"])
|
||||
areas_in_z["[z]"] = list()
|
||||
areas_in_z["[z]"] += src
|
||||
/// Soon ™
|
||||
/area/proc/RunGeneration()
|
||||
// if(map_generator)
|
||||
// map_generator = new map_generator()
|
||||
// var/list/turfs = list()
|
||||
// for(var/turf/T in contents)
|
||||
// turfs += T
|
||||
// map_generator.generate_terrain(turfs)
|
||||
|
||||
/area/proc/test_gen()
|
||||
// if(map_generator)
|
||||
// var/list/turfs = list()
|
||||
// for(var/turf/T in contents)
|
||||
// turfs += T
|
||||
// map_generator.generate_terrain(turfs)
|
||||
|
||||
/**
|
||||
* Register this area as belonging to a z level
|
||||
*
|
||||
* Ensures the item is added to the SSmapping.areas_in_z list for this z
|
||||
*/
|
||||
/area/proc/reg_in_areas_in_z()
|
||||
if(!length(contents))
|
||||
return
|
||||
var/list/areas_in_z = SSmapping.areas_in_z
|
||||
update_areasize()
|
||||
if(!z)
|
||||
WARNING("No z found for [src]")
|
||||
return
|
||||
if(!areas_in_z["[z]"])
|
||||
areas_in_z["[z]"] = list()
|
||||
areas_in_z["[z]"] += src
|
||||
|
||||
/**
|
||||
* Destroy an area and clean it up
|
||||
*
|
||||
* Removes the area from GLOB.areas_by_type and also stops it processing on SSobj
|
||||
*
|
||||
* This is despite the fact that no code appears to put it on SSobj, but
|
||||
* who am I to argue with old coders
|
||||
*/
|
||||
/area/Destroy()
|
||||
if(GLOB.areas_by_type[type] == src)
|
||||
GLOB.areas_by_type[type] = null
|
||||
@@ -244,6 +321,11 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generate a power alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/poweralert(state, obj/source)
|
||||
if (state != poweralm)
|
||||
poweralm = state
|
||||
@@ -525,6 +607,13 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
used_environ += amount
|
||||
|
||||
|
||||
/**
|
||||
* Call back when an atom enters an area
|
||||
*
|
||||
* Sends signals COMSIG_AREA_ENTERED and COMSIG_ENTER_AREA (to the atom)
|
||||
*
|
||||
* If the area has ambience, then it plays some ambience music to the ambience channel
|
||||
*/
|
||||
/area/Entered(atom/movable/M, atom/OldLoc)
|
||||
set waitfor = FALSE
|
||||
SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M)
|
||||
@@ -567,6 +656,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
return FALSE //Too big
|
||||
beauty = totalbeauty / areasize
|
||||
|
||||
|
||||
/**
|
||||
* Called when an atom exits an area
|
||||
*
|
||||
* Sends signals COMSIG_AREA_EXITED and COMSIG_EXIT_AREA (to the atom)
|
||||
*/
|
||||
/area/Exited(atom/movable/M)
|
||||
SEND_SIGNAL(src, COMSIG_AREA_EXITED, M)
|
||||
SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area
|
||||
|
||||
@@ -9,6 +9,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
icon_state = "away"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
ambientsounds = AWAY_MISSION
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
/area/awaymission/beach
|
||||
name = "Beach"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
flags_1 = 0
|
||||
hidden = TRUE
|
||||
sound_environment = SOUND_ENVIRONMENT_PADDED_CELL
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
var/restricted = 0 // if true, program goes on emag list
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
flags_1 = NONE
|
||||
ambientsounds = MINING
|
||||
flora_allowed = FALSE
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/mine/unexplored
|
||||
name = "Mine"
|
||||
@@ -86,6 +87,7 @@
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
sound_environment = SOUND_AREA_LAVALAND
|
||||
|
||||
/area/lavaland/surface
|
||||
name = "Lavaland"
|
||||
@@ -139,6 +141,7 @@
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
blob_allowed = FALSE
|
||||
sound_environment = SOUND_AREA_ICEMOON
|
||||
|
||||
/area/icemoon/surface
|
||||
name = "Icemoon"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
hidden = TRUE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
ambientsounds = RUINS
|
||||
sound_environment = SOUND_ENVIRONMENT_STONEROOM
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
icon_state = "shuttle"
|
||||
// Loading the same shuttle map at a different time will produce distinct area instances.
|
||||
unique = FALSE
|
||||
sound_environment = SOUND_ENVIRONMENT_ROOM
|
||||
|
||||
/area/shuttle/Initialize()
|
||||
if(!canSmoothWithAreas)
|
||||
|
||||
+146
-27
@@ -1,12 +1,22 @@
|
||||
/**
|
||||
* The base type for nearly all physical objects in SS13
|
||||
|
||||
* Lots and lots of functionality lives here, although in general we are striving to move
|
||||
* as much as possible to the components/elements system
|
||||
*/
|
||||
/atom
|
||||
layer = TURF_LAYER
|
||||
plane = GAME_PLANE
|
||||
var/level = 2
|
||||
var/article // If non-null, overrides a/an/some in all cases
|
||||
appearance_flags = TILE_BOUND
|
||||
|
||||
var/level = 2
|
||||
///If non-null, overrides a/an/some in all cases
|
||||
var/article
|
||||
|
||||
///First atom flags var
|
||||
var/flags_1 = NONE
|
||||
///Intearaction flags
|
||||
var/interaction_flags_atom = NONE
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
var/flags_ricochet = NONE
|
||||
|
||||
@@ -15,35 +25,52 @@
|
||||
///When a projectile ricochets off this atom, it deals the normal damage * this modifier to this atom
|
||||
var/ricochet_damage_mod = 0.33
|
||||
|
||||
//This atom's HUD (med/sec, etc) images. Associative list.
|
||||
///Reagents holder
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
///This atom's HUD (med/sec, etc) images. Associative list.
|
||||
var/list/image/hud_list = null
|
||||
//HUD images that this atom can provide.
|
||||
///HUD images that this atom can provide.
|
||||
var/list/hud_possible
|
||||
|
||||
//Value used to increment ex_act() if reactionary_explosions is on
|
||||
///Value used to increment ex_act() if reactionary_explosions is on
|
||||
var/explosion_block = 0
|
||||
|
||||
var/list/atom_colours //used to store the different colors on an atom
|
||||
//its inherent color, the colored paint applied on it, special color effect etc...
|
||||
/**
|
||||
* used to store the different colors on an atom
|
||||
*
|
||||
* its inherent color, the colored paint applied on it, special color effect etc...
|
||||
*/
|
||||
var/list/atom_colours
|
||||
|
||||
var/list/remove_overlays // a very temporary list of overlays to remove
|
||||
var/list/add_overlays // a very temporary list of overlays to add
|
||||
|
||||
var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
||||
///overlays managed by update_overlays() to prevent removing overlays that weren't added by the same proc
|
||||
/// a very temporary list of overlays to remove
|
||||
var/list/remove_overlays
|
||||
/// a very temporary list of overlays to add
|
||||
var/list/add_overlays
|
||||
|
||||
///vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays
|
||||
var/list/managed_vis_overlays
|
||||
///overlays managed by [update_overlays][/atom/proc/update_overlays] to prevent removing overlays that weren't added by the same proc
|
||||
var/list/managed_overlays
|
||||
|
||||
///Proximity monitor associated with this atom
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
///Last fingerprints to touch this atom
|
||||
var/fingerprintslast
|
||||
|
||||
var/list/filter_data //For handling persistent filters
|
||||
|
||||
///Price of an item in a vending machine, overriding the base vending machine price. Define in terms of paycheck defines as opposed to raw numbers.
|
||||
var/custom_price
|
||||
///Price of an item in a vending machine, overriding the premium vending machine price. Define in terms of paycheck defines as opposed to raw numbers.
|
||||
var/custom_premium_price
|
||||
|
||||
//List of datums orbiting this atom
|
||||
var/datum/component/orbiter/orbiters
|
||||
|
||||
var/rad_flags = NONE // Will move to flags_1 when i can be arsed to
|
||||
/// Radiation insulation types
|
||||
var/rad_insulation = RAD_NO_INSULATION
|
||||
|
||||
///The custom materials this atom is made of, used by a lot of things like furniture, walls, and floors (if I finish the functionality, that is.)
|
||||
@@ -72,6 +99,16 @@
|
||||
///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
|
||||
var/list/targeted_by
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
* Not a lot happens here in SS13 code, as we offload most of the work to the
|
||||
* [Intialization][/atom/proc/Initialize] proc, mostly we run the preloader
|
||||
* if the preloader is being used and then call [InitAtom][/datum/controller/subsystem/atoms/proc/InitAtom] of which the ultimate
|
||||
* result is that the Intialize proc is called.
|
||||
*
|
||||
* We also generate a tag here if the DF_USE_TAG flag is set on the atom
|
||||
*/
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -87,24 +124,50 @@
|
||||
//we were deleted
|
||||
return
|
||||
|
||||
//Called after New if the map is being loaded. mapload = TRUE
|
||||
//Called from base of New if the map is not being loaded. mapload = FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE
|
||||
//must not sleep
|
||||
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
|
||||
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
||||
|
||||
//Note: the following functions don't call the base for optimization and must copypasta:
|
||||
// /turf/Initialize
|
||||
// /turf/open/space/Initialize
|
||||
|
||||
/**
|
||||
* The primary method that objects are setup in SS13 with
|
||||
*
|
||||
* we don't use New as we have better control over when this is called and we can choose
|
||||
* to delay calls or hook other logic in and so forth
|
||||
*
|
||||
* During roundstart map parsing, atoms are queued for intialization in the base atom/New(),
|
||||
* After the map has loaded, then Initalize is called on all atoms one by one. NB: this
|
||||
* is also true for loading map templates as well, so they don't Initalize until all objects
|
||||
* in the map file are parsed and present in the world
|
||||
*
|
||||
* If you're creating an object at any point after SSInit has run then this proc will be
|
||||
* immediately be called from New.
|
||||
*
|
||||
* mapload: This parameter is true if the atom being loaded is either being intialized during
|
||||
* the Atom subsystem intialization, or if the atom is being loaded from the map template.
|
||||
* If the item is being created at runtime any time after the Atom subsystem is intialized then
|
||||
* it's false.
|
||||
*
|
||||
* You must always call the parent of this proc, otherwise failures will occur as the item
|
||||
* will not be seen as initalized (this can lead to all sorts of strange behaviour, like
|
||||
* the item being completely unclickable)
|
||||
*
|
||||
* You must not sleep in this proc, or any subprocs
|
||||
*
|
||||
* Any parameters from new are passed through (excluding loc), naturally if you're loading from a map
|
||||
* there are no other arguments
|
||||
*
|
||||
* Must return an [initialization hint][INITIALIZE_HINT_NORMAL] or a runtime will occur.
|
||||
*
|
||||
* Note: the following functions don't call the base for optimization and must copypasta handling:
|
||||
* * [/turf/proc/Initialize]
|
||||
* * [/turf/open/space/proc/Initialize]
|
||||
*/
|
||||
/atom/proc/Initialize(mapload, ...)
|
||||
// SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
flags_1 |= INITIALIZED_1
|
||||
|
||||
if(loc)
|
||||
SEND_SIGNAL(loc, COMSIG_ATOM_CREATED, src) /// Sends a signal that the new atom `src`, has been created at `loc`
|
||||
|
||||
//atom color stuff
|
||||
if(color)
|
||||
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
|
||||
@@ -126,14 +189,34 @@
|
||||
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
/**
|
||||
* Late Intialization, for code that should run after all atoms have run Intialization
|
||||
*
|
||||
* To have your LateIntialize proc be called, your atoms [Initalization][/atom/proc/Initialize]
|
||||
* proc must return the hint
|
||||
* [INITIALIZE_HINT_LATELOAD] otherwise you will never be called.
|
||||
*
|
||||
* useful for doing things like finding other machines on GLOB.machines because you can guarantee
|
||||
* that all atoms will actually exist in the "WORLD" at this time and that all their Intialization
|
||||
* code has been run
|
||||
*/
|
||||
/atom/proc/LateInitialize()
|
||||
return
|
||||
set waitfor = FALSE
|
||||
|
||||
// Put your AddComponent() calls here
|
||||
/// Put your [AddComponent] calls here
|
||||
/atom/proc/ComponentInitialize()
|
||||
return
|
||||
|
||||
/**
|
||||
* Top level of the destroy chain for most atoms
|
||||
*
|
||||
* Cleans up the following:
|
||||
* * Removes alternate apperances from huds that see them
|
||||
* * qdels the reagent holder from atoms if it exists
|
||||
* * clears the orbiters list
|
||||
* * clears overlays and priority overlays
|
||||
* * clears the light object
|
||||
*/
|
||||
/atom/Destroy()
|
||||
if(alternate_appearances)
|
||||
for(var/K in alternate_appearances)
|
||||
@@ -143,6 +226,8 @@
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
|
||||
orbiters = null // The component is attached to us normaly and will be deleted elsewhere
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
|
||||
for(var/i in targeted_by)
|
||||
@@ -179,6 +264,16 @@
|
||||
/atom/proc/CanPass(atom/movable/mover, turf/target)
|
||||
return !density
|
||||
|
||||
/**
|
||||
* Is this atom currently located on centcom
|
||||
*
|
||||
* Specifically, is it on the z level and within the centcom areas
|
||||
*
|
||||
* You can also be in a shuttleshuttle during endgame transit
|
||||
*
|
||||
* Used in gamemode to identify mobs who have escaped and for some other areas of the code
|
||||
* who don't want atoms where they shouldn't be
|
||||
*/
|
||||
/atom/proc/onCentCom()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -209,6 +304,13 @@
|
||||
if(T in shuttle_area)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Is the atom in any of the centcom syndicate areas
|
||||
*
|
||||
* Either in the syndie base on centcom, or any of their shuttles
|
||||
*
|
||||
* Also used in gamemode code for win conditions
|
||||
*/
|
||||
/atom/proc/onSyndieBase()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -222,6 +324,23 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Is the atom in an away mission
|
||||
*
|
||||
* Must be in the away mission z-level to return TRUE
|
||||
*
|
||||
* Also used in gamemode code for win conditions
|
||||
*/
|
||||
/atom/proc/onAwayMission()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
|
||||
if(is_away_level(T.z))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
|
||||
if(does_attack_animation)
|
||||
@@ -415,7 +534,7 @@
|
||||
|
||||
/// Updates the overlays of the atom
|
||||
/atom/proc/update_overlays()
|
||||
SHOULD_CALL_PARENT(1)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
. = list()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)
|
||||
|
||||
|
||||
+199
-111
@@ -1,5 +1,7 @@
|
||||
/atom/movable
|
||||
layer = OBJ_LAYER
|
||||
glide_size = 8
|
||||
SET_APPEARANCE_FLAGS(TILE_BOUND | PIXEL_SCALE)
|
||||
var/last_move = null
|
||||
var/last_move_time = 0
|
||||
var/anchored = FALSE
|
||||
@@ -28,8 +30,6 @@
|
||||
var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before.
|
||||
var/list/client_mobs_in_contents // This contains all the client mobs within this container
|
||||
var/list/acted_explosions //for explosion dodging
|
||||
glide_size = 8
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
||||
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
|
||||
var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
|
||||
var/atom/movable/pulling
|
||||
@@ -59,6 +59,42 @@
|
||||
em_block = new(src, render_target)
|
||||
vis_contents += em_block
|
||||
|
||||
|
||||
/atom/movable/Destroy(force)
|
||||
QDEL_NULL(proximity_monitor)
|
||||
QDEL_NULL(language_holder)
|
||||
QDEL_NULL(em_block)
|
||||
|
||||
unbuckle_all_mobs(force = TRUE)
|
||||
|
||||
if(loc)
|
||||
//Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary)
|
||||
if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc))
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
loc.handle_atom_del(src)
|
||||
|
||||
// if(opacity)
|
||||
// RemoveElement(/datum/element/light_blocking)
|
||||
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(orbiting)
|
||||
orbiting.end_orbit(src)
|
||||
orbiting = null
|
||||
|
||||
. = ..()
|
||||
|
||||
for(var/movable_content in contents)
|
||||
qdel(movable_content)
|
||||
|
||||
LAZYCLEARLIST(client_mobs_in_contents)
|
||||
|
||||
moveToNullspace()
|
||||
|
||||
/atom/movable/proc/update_emissive_block()
|
||||
if(blocks_emissive != EMISSIVE_BLOCK_GENERIC)
|
||||
return
|
||||
@@ -113,40 +149,52 @@
|
||||
return FALSE
|
||||
return T.zPassOut(src, direction, destination) && destination.zPassIn(src, direction, T)
|
||||
|
||||
/atom/movable/vv_edit_var(var_name, var_value)
|
||||
var/static/list/banned_edits = list("step_x", "step_y", "step_size")
|
||||
var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height")
|
||||
if(var_name in banned_edits)
|
||||
/atom/movable/vv_edit_var(var_name, var_value, massedit)
|
||||
var/static/list/banned_edits = list("step_x" = TRUE, "step_y" = TRUE, "step_size" = TRUE, "bounds" = TRUE)
|
||||
var/static/list/careful_edits = list("bound_x" = TRUE, "bound_y" = TRUE, "bound_width" = TRUE, "bound_height" = TRUE)
|
||||
if(banned_edits[var_name])
|
||||
return FALSE //PLEASE no.
|
||||
if((var_name in careful_edits) && (var_value % world.icon_size) != 0)
|
||||
if((careful_edits[var_name]) && (var_value % world.icon_size) != 0)
|
||||
return FALSE
|
||||
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, x))
|
||||
var/turf/T = locate(var_value, y, z)
|
||||
if(T)
|
||||
forceMove(T)
|
||||
admin_teleport(T, !massedit)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(NAMEOF(src, y))
|
||||
var/turf/T = locate(x, var_value, z)
|
||||
if(T)
|
||||
forceMove(T)
|
||||
admin_teleport(T, !massedit)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(NAMEOF(src, z))
|
||||
var/turf/T = locate(x, y, var_value)
|
||||
if(T)
|
||||
forceMove(T)
|
||||
admin_teleport(T, !massedit)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(NAMEOF(src, loc))
|
||||
if(istype(var_value, /atom))
|
||||
forceMove(var_value)
|
||||
return TRUE
|
||||
else if(isnull(var_value))
|
||||
moveToNullspace()
|
||||
if(isatom(var_value) || isnull(var_value))
|
||||
admin_teleport(var_value, !massedit)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(NAMEOF(src, anchored))
|
||||
set_anchored(var_value)
|
||||
. = TRUE
|
||||
if(NAMEOF(src, pulledby))
|
||||
set_pulledby(var_value)
|
||||
. = TRUE
|
||||
if(NAMEOF(src, glide_size))
|
||||
set_glide_size(var_value)
|
||||
. = TRUE
|
||||
|
||||
if(!isnull(.))
|
||||
datum_flags |= DF_VAR_EDITED
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
@@ -168,48 +216,73 @@
|
||||
AMob.grabbedby(src)
|
||||
return TRUE
|
||||
stop_pulling()
|
||||
|
||||
// SEND_SIGNAL(src, COMSIG_ATOM_START_PULL, AM, state, force)
|
||||
|
||||
if(AM.pulledby)
|
||||
log_combat(AM, AM.pulledby, "pulled from", src)
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
AM.set_pulledby(src)
|
||||
setGrabState(state)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
log_combat(src, M, "grabbed", addition="passive grab")
|
||||
if(!supress_message)
|
||||
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
|
||||
M.visible_message("<span class='warning'>[src] grabs [M] passively.</span>", \
|
||||
"<span class='danger'>[src] grabs you passively.</span>")
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/stop_pulling()
|
||||
if(!pulling)
|
||||
return
|
||||
pulling.pulledby = null
|
||||
pulling.set_pulledby(null)
|
||||
var/mob/living/ex_pulled = pulling
|
||||
setGrabState(GRAB_PASSIVE)
|
||||
pulling = null
|
||||
setGrabState(0)
|
||||
if(isliving(ex_pulled))
|
||||
var/mob/living/L = ex_pulled
|
||||
L.update_mobility()// mob gets up if it was lyng down in a chokehold
|
||||
|
||||
///Reports the event of the change in value of the pulledby variable.
|
||||
/atom/movable/proc/set_pulledby(new_pulledby)
|
||||
if(new_pulledby == pulledby)
|
||||
return FALSE //null signals there was a change, be sure to return FALSE if none happened here.
|
||||
. = pulledby
|
||||
pulledby = new_pulledby
|
||||
|
||||
/atom/movable/proc/Move_Pulled(atom/A)
|
||||
if(!pulling)
|
||||
return
|
||||
return FALSE
|
||||
if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
|
||||
stop_pulling()
|
||||
return
|
||||
return FALSE
|
||||
if(isliving(pulling))
|
||||
var/mob/living/L = pulling
|
||||
if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it
|
||||
stop_pulling()
|
||||
return
|
||||
return FALSE
|
||||
if(A == loc && pulling.density)
|
||||
return
|
||||
if(!Process_Spacemove(get_dir(pulling.loc, A)))
|
||||
return
|
||||
step(pulling, get_dir(pulling.loc, A))
|
||||
return FALSE
|
||||
var/move_dir = get_dir(pulling.loc, A)
|
||||
if(!Process_Spacemove(move_dir))
|
||||
return FALSE
|
||||
pulling.Move(get_step(pulling.loc, move_dir), move_dir, glide_size)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Recursively set glide size for atom's pulled things
|
||||
*/
|
||||
/atom/movable/proc/recursive_pulled_glidesize_update()
|
||||
var/list/ran = list()
|
||||
var/atom/movable/updating = pulling
|
||||
while(updating)
|
||||
if(ran[updating])
|
||||
return
|
||||
updating.set_glide_size(glide_size, FALSE)
|
||||
ran[updating] = TRUE
|
||||
updating = updating.pulling
|
||||
|
||||
/atom/movable/proc/check_pulling()
|
||||
if(pulling)
|
||||
var/atom/movable/pullee = pulling
|
||||
@@ -229,54 +302,57 @@
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move.
|
||||
pulledby.stop_pulling()
|
||||
|
||||
/atom/movable/Destroy(force)
|
||||
QDEL_NULL(proximity_monitor)
|
||||
QDEL_NULL(language_holder)
|
||||
QDEL_NULL(em_block)
|
||||
/atom/movable/proc/set_glide_size(target = 8, recursive = TRUE)
|
||||
#ifdef SMOOTH_MOVEMENT
|
||||
// SEND_SIGNAL(src, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, target)
|
||||
glide_size = target
|
||||
|
||||
unbuckle_all_mobs(force=1)
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/buckled_mob = m
|
||||
buckled_mob.set_glide_size(target)
|
||||
|
||||
. = ..()
|
||||
if(recursive)
|
||||
recursive_pulled_glidesize_update()
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
if(loc)
|
||||
//Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary)
|
||||
if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc))
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
loc.handle_atom_del(src)
|
||||
for(var/atom/movable/AM in contents)
|
||||
qdel(AM)
|
||||
moveToNullspace()
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(orbiting)
|
||||
orbiting.end_orbit(src)
|
||||
orbiting = null
|
||||
///Sets the anchored var and returns if it was sucessfully changed or not.
|
||||
/atom/movable/proc/set_anchored(anchorvalue)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(anchored == anchorvalue)
|
||||
return
|
||||
. = anchored
|
||||
anchored = anchorvalue
|
||||
// SEND_SIGNAL(src, COMSIG_MOVABLE_SET_ANCHORED, anchorvalue)
|
||||
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
set waitfor = 0
|
||||
set waitfor = FALSE
|
||||
var/hitpush = TRUE
|
||||
var/impact_signal = SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
|
||||
if(impact_signal & COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH)
|
||||
hitpush = FALSE // hacky, tie this to something else or a proper workaround later
|
||||
|
||||
if(impact_signal & ~COMPONENT_MOVABLE_IMPACT_NEVERMIND) // in case a signal interceptor broke or deleted the thing before we could process our hit
|
||||
return hit_atom.hitby(src, throwingdatum = throwingdatum, hitpush = hitpush)
|
||||
if(!(impact_signal && (impact_signal & COMPONENT_MOVABLE_IMPACT_NEVERMIND))) // in case a signal interceptor broke or deleted the thing before we could process our hit
|
||||
return hit_atom.hitby(src, throwingdatum=throwingdatum, hitpush=hitpush)
|
||||
|
||||
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked, datum/thrownthing/throwingdatum)
|
||||
if(!anchored && hitpush && (!throwingdatum || (throwingdatum.force >= (move_resist * MOVE_FORCE_PUSH_RATIO))))
|
||||
step(src, AM.dir)
|
||||
..()
|
||||
|
||||
/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, messy_throw = TRUE)
|
||||
/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
|
||||
if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY))
|
||||
return
|
||||
return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, messy_throw)
|
||||
return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, gentle)
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, messy_throw = TRUE) //If this returns FALSE then callback will not be called.
|
||||
///If this returns FALSE then callback will not be called.
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE, quickstart = TRUE)
|
||||
. = FALSE
|
||||
|
||||
if(QDELETED(src))
|
||||
CRASH("Qdeleted thing being thrown around.")
|
||||
|
||||
if (!target || speed <= 0)
|
||||
return
|
||||
|
||||
@@ -288,7 +364,7 @@
|
||||
|
||||
//They are moving! Wouldn't it be cool if we calculated their momentum and added it to the throw?
|
||||
if (thrower && thrower.last_move && thrower.client && thrower.client.move_delay >= world.time + world.tick_lag*2)
|
||||
var/user_momentum = thrower.movement_delay()
|
||||
var/user_momentum = thrower.movement_delay() //cached_multiplicative_slowdown
|
||||
if (!user_momentum) //no movement_delay, this means they move once per byond tick, lets calculate from that instead.
|
||||
user_momentum = world.tick_lag
|
||||
|
||||
@@ -312,19 +388,13 @@
|
||||
|
||||
. = TRUE // No failure conditions past this point.
|
||||
|
||||
var/datum/thrownthing/TT = new()
|
||||
TT.thrownthing = src
|
||||
TT.target = target
|
||||
TT.target_turf = get_turf(target)
|
||||
TT.init_dir = get_dir(src, target)
|
||||
TT.maxrange = range
|
||||
TT.speed = speed
|
||||
TT.thrower = thrower
|
||||
TT.diagonals_first = diagonals_first
|
||||
TT.force = force
|
||||
TT.callback = callback
|
||||
if(!QDELETED(thrower))
|
||||
TT.target_zone = thrower.zone_selected
|
||||
var/target_zone
|
||||
if(QDELETED(thrower))
|
||||
thrower = null //Let's not pass a qdeleting reference if any.
|
||||
else
|
||||
target_zone = thrower.zone_selected
|
||||
|
||||
var/datum/thrownthing/TT = new(src, target, get_turf(target), get_dir(src, target), range, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
|
||||
|
||||
var/dist_x = abs(target.x - src.x)
|
||||
var/dist_y = abs(target.y - src.y)
|
||||
@@ -359,7 +429,8 @@
|
||||
SSthrowing.processing[src] = TT
|
||||
if (SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun))
|
||||
SSthrowing.currentrun[src] = TT
|
||||
TT.tick()
|
||||
if (quickstart)
|
||||
TT.tick()
|
||||
|
||||
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return FALSE
|
||||
@@ -382,13 +453,13 @@
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
|
||||
/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S)
|
||||
return
|
||||
/// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
|
||||
/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S) // rename S to master_storage
|
||||
// SEND_SIGNAL(src, COMSIG_STORAGE_EXITED, master_storage)
|
||||
|
||||
// called when this atom is added into a storage item, which is passed on as S. The loc variable is already set to the storage item.
|
||||
/// called when this atom is added into a storage item, which is passed on as S. The loc variable is already set to the storage item.
|
||||
/atom/movable/proc/on_enter_storage(datum/component/storage/concrete/S)
|
||||
return
|
||||
// SEND_SIGNAL(src, COMSIG_STORAGE_ENTERED, master_storage)
|
||||
|
||||
/atom/movable/proc/get_spacemove_backup()
|
||||
var/atom/movable/dense_object_backup
|
||||
@@ -422,24 +493,26 @@
|
||||
return //don't do an animation if attacking self
|
||||
var/pixel_x_diff = 0
|
||||
var/pixel_y_diff = 0
|
||||
var/turn_dir = 1
|
||||
|
||||
var/direction = get_dir(src, A)
|
||||
if(direction & NORTH)
|
||||
pixel_y_diff = 8
|
||||
turn_dir = prob(50) ? -1 : 1
|
||||
else if(direction & SOUTH)
|
||||
pixel_y_diff = -8
|
||||
turn_dir = prob(50) ? -1 : 1
|
||||
|
||||
if(direction & EAST)
|
||||
pixel_x_diff = 8
|
||||
else if(direction & WEST)
|
||||
pixel_x_diff = -8
|
||||
turn_dir = -1
|
||||
|
||||
var/matrix/OM = matrix(transform)
|
||||
var/matrix/M = matrix(transform)
|
||||
M.Turn(pixel_x_diff ? pixel_x_diff*2 : pick(-16, 16))
|
||||
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform = M, time = 2)
|
||||
animate(src, pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform = OM, time = 2)
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
var/matrix/rotated_transform = transform.Turn(15 * turn_dir)
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN)
|
||||
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING)
|
||||
|
||||
/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item)
|
||||
var/image/I
|
||||
@@ -450,21 +523,21 @@
|
||||
I.plane = GAME_PLANE
|
||||
|
||||
// Scale the icon.
|
||||
I.transform *= 0.75
|
||||
I.transform *= 0.4
|
||||
// The icon should not rotate.
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
|
||||
// Set the direction of the icon animation.
|
||||
var/direction = get_dir(src, A)
|
||||
if(direction & NORTH)
|
||||
I.pixel_y = -16
|
||||
I.pixel_y = -12
|
||||
else if(direction & SOUTH)
|
||||
I.pixel_y = 16
|
||||
I.pixel_y = 12
|
||||
|
||||
if(direction & EAST)
|
||||
I.pixel_x = -16
|
||||
I.pixel_x = -14
|
||||
else if(direction & WEST)
|
||||
I.pixel_x = 16
|
||||
I.pixel_x = 14
|
||||
|
||||
if(!direction) // Attacked self?!
|
||||
I.pixel_z = 16
|
||||
@@ -472,10 +545,12 @@
|
||||
if(!I)
|
||||
return
|
||||
|
||||
flick_overlay(I, GLOB.clients, 5) // 5 ticks/half a second
|
||||
flick_overlay(I, GLOB.clients, 10)
|
||||
|
||||
// And animate the attack!
|
||||
animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
|
||||
animate(I, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
|
||||
animate(time = 1)
|
||||
animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT)
|
||||
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
@@ -495,16 +570,14 @@
|
||||
/atom/movable/proc/float(on, throw_override)
|
||||
if(throwing || !throw_override)
|
||||
return
|
||||
if(on && (!(movement_type & FLOATING) || floating_need_update))
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
if(!(movement_type & FLOATING))
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if (!on && movement_type & FLOATING)
|
||||
if(on && !(movement_type & FLOATING))
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if (!on && (movement_type & FLOATING))
|
||||
animate(src, pixel_y = initial(pixel_y), time = 10)
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
floating_need_update = FALSE
|
||||
floating_need_update = FALSE // assume it's done
|
||||
|
||||
/* Language procs
|
||||
* Unless you are doing something very specific, these are the ones you want to use.
|
||||
@@ -611,10 +684,32 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Updates the grab state of the movable
|
||||
/// This exists to act as a hook for behaviour
|
||||
/**
|
||||
* Updates the grab state of the movable
|
||||
*
|
||||
* This exists to act as a hook for behaviour
|
||||
*/
|
||||
/atom/movable/proc/setGrabState(newstate)
|
||||
if(newstate == grab_state)
|
||||
return
|
||||
// SEND_SIGNAL(src, COMSIG_MOVABLE_SET_GRAB_STATE, newstate)
|
||||
. = grab_state
|
||||
grab_state = newstate
|
||||
// switch(grab_state) // Current state.
|
||||
// if(GRAB_PASSIVE)
|
||||
// REMOVE_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
|
||||
// REMOVE_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
|
||||
// if(. >= GRAB_NECK) // Previous state was a a neck-grab or higher.
|
||||
// REMOVE_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
|
||||
// if(GRAB_AGGRESSIVE)
|
||||
// if(. >= GRAB_NECK) // Grab got downgraded.
|
||||
// REMOVE_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
|
||||
// else // Grab got upgraded from a passive one.
|
||||
// ADD_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
|
||||
// ADD_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
|
||||
// if(GRAB_NECK, GRAB_KILL)
|
||||
// if(. <= GRAB_AGGRESSIVE)
|
||||
// ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
|
||||
|
||||
/obj/item/proc/do_pickup_animation(atom/target)
|
||||
set waitfor = FALSE
|
||||
@@ -626,31 +721,24 @@
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
var/turf/T = get_turf(src)
|
||||
var/direction
|
||||
var/to_x = 0
|
||||
var/to_y = 0
|
||||
var/to_x = initial(target.pixel_x)
|
||||
var/to_y = initial(target.pixel_y)
|
||||
|
||||
if(!QDELETED(T) && !QDELETED(target))
|
||||
direction = get_dir(T, target)
|
||||
if(direction & NORTH)
|
||||
to_y = 32
|
||||
to_y += 32
|
||||
else if(direction & SOUTH)
|
||||
to_y = -32
|
||||
to_y -= 32
|
||||
if(direction & EAST)
|
||||
to_x = 32
|
||||
to_x += 32
|
||||
else if(direction & WEST)
|
||||
to_x = -32
|
||||
to_x -= 32
|
||||
if(!direction)
|
||||
to_y = 16
|
||||
to_y += 16
|
||||
flick_overlay(I, GLOB.clients, 6)
|
||||
var/matrix/M = new
|
||||
M.Turn(pick(-30, 30))
|
||||
animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING)
|
||||
sleep(1)
|
||||
animate(I, alpha = 0, transform = matrix(), time = 1)
|
||||
|
||||
/atom/movable/proc/set_anchored(anchorvalue) //literally only for plumbing ran
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(anchored == anchorvalue)
|
||||
return
|
||||
. = anchored
|
||||
anchored = anchorvalue
|
||||
|
||||
+61
-40
@@ -5,8 +5,7 @@
|
||||
// Here's where we rewrite how byond handles movement except slightly different
|
||||
// To be removed on step_ conversion
|
||||
// All this work to prevent a second bump
|
||||
/atom/movable/Move(atom/newloc, direct=0)
|
||||
set waitfor = FALSE //n o
|
||||
/atom/movable/Move(atom/newloc, direct=0, glide_size_override = 0)
|
||||
. = FALSE
|
||||
if(!newloc || newloc == loc)
|
||||
return
|
||||
@@ -52,8 +51,7 @@
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct)
|
||||
set waitfor = FALSE //n o
|
||||
/atom/movable/Move(atom/newloc, direct, glide_size_override = 0)
|
||||
var/atom/movable/pullee = pulling
|
||||
var/turf/T = loc
|
||||
if(!moving_from_pull)
|
||||
@@ -61,6 +59,9 @@
|
||||
if(!loc || !newloc)
|
||||
return FALSE
|
||||
var/atom/oldloc = loc
|
||||
//Early override for some cases like diagonal movement
|
||||
if(glide_size_override)
|
||||
set_glide_size(glide_size_override, FALSE)
|
||||
|
||||
if(loc != newloc)
|
||||
if (!(direct & (direct - 1))) //Cardinal move
|
||||
@@ -120,32 +121,38 @@
|
||||
return
|
||||
|
||||
if(!loc || (loc == oldloc && oldloc != newloc))
|
||||
last_move = NONE
|
||||
last_move = 0
|
||||
return
|
||||
|
||||
setDir(direct)
|
||||
if(.)
|
||||
last_move = direct
|
||||
setDir(direct)
|
||||
|
||||
if(has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
|
||||
return FALSE
|
||||
|
||||
if(pulling && pulling == pullee && pulling != moving_from_pull) //we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
else
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
//puller and pullee more than one tile away or in diagonal position
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
|
||||
pulling.moving_from_pull = src
|
||||
pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
|
||||
pulling.moving_from_pull = null
|
||||
Moved(oldloc, direct)
|
||||
if(. && pulling && pulling == pullee && pulling != moving_from_pull) //we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
else
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
//puller and pullee more than one tile away or in diagonal position
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
|
||||
pulling.moving_from_pull = src
|
||||
pulling.Move(T, get_dir(pulling, T), glide_size) //the pullee tries to reach our previous position
|
||||
pulling.moving_from_pull = null
|
||||
check_pulling()
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
|
||||
|
||||
//glide_size strangely enough can change mid movement animation and update correctly while the animation is playing
|
||||
//This means that if you don't override it late like this, it will just be set back by the movement update that's called when you move turfs.
|
||||
if(glide_size_override)
|
||||
set_glide_size(glide_size_override, FALSE)
|
||||
|
||||
last_move = direct
|
||||
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s)
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(newloc, direct, glide_size_override)
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
if(!buckled_mob.Move(newloc, direct))
|
||||
if(!buckled_mob.Move(newloc, direct, glide_size_override))
|
||||
forceMove(buckled_mob.loc)
|
||||
last_move = buckled_mob.last_move
|
||||
inertia_dir = last_move
|
||||
@@ -155,6 +162,7 @@
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
|
||||
if (!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
@@ -174,6 +182,8 @@
|
||||
|
||||
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
|
||||
/atom/movable/Crossed(atom/movable/AM, oldloc)
|
||||
// SHOULD_CALL_PARENT(TRUE)
|
||||
. = ..()
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
|
||||
|
||||
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
|
||||
@@ -204,7 +214,11 @@
|
||||
var/atom/movable/AM = item
|
||||
AM.onTransitZ(old_z,new_z)
|
||||
|
||||
///Proc to modify the movement_type and hook behavior associated with it changing.
|
||||
/atom/movable/proc/setMovetype(newval)
|
||||
if(movement_type == newval)
|
||||
return
|
||||
. = movement_type
|
||||
movement_type = newval
|
||||
|
||||
///////////// FORCED MOVEMENT /////////////
|
||||
@@ -268,37 +282,44 @@
|
||||
old_area.Exited(src, null)
|
||||
loc = null
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
|
||||
//movement_dir == 0 when stopping or any dir when trying to move
|
||||
/**
|
||||
* Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
* And when an object or action applies a force on src, see [newtonian_move][/atom/movable/proc/newtonian_move]
|
||||
*
|
||||
* Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
*
|
||||
* Mobs should return 1 if they should be able to move of their own volition, see [/client/proc/Move]
|
||||
*
|
||||
* Arguments:
|
||||
* * movement_dir - 0 when stopping or any dir when trying to move
|
||||
*/
|
||||
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
|
||||
if(has_gravity(src))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(pulledby)
|
||||
return 1
|
||||
if(pulledby && (pulledby.pulledby != src || moving_from_pull))
|
||||
return TRUE
|
||||
|
||||
if(throwing)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(!isturf(loc))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
|
||||
if(!loc || Process_Spacemove(0))
|
||||
/// Only moves the object if it's under no gravity
|
||||
/atom/movable/proc/newtonian_move(direction)
|
||||
if(!isturf(loc) || Process_Spacemove(0))
|
||||
inertia_dir = 0
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
inertia_dir = direction
|
||||
if(!direction)
|
||||
return 1
|
||||
return TRUE
|
||||
inertia_last_loc = loc
|
||||
SSspacedrift.processing[src] = src
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
@@ -109,4 +109,4 @@
|
||||
else if (world.time > detectTime)
|
||||
detectTime = 0
|
||||
for(var/obj/machinery/computer/security/telescreen/entertainment/TV in GLOB.machines)
|
||||
TV.notify(FALSE)
|
||||
TV.notify(FALSE)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
blocked = TRUE
|
||||
var/attackamt = rand(2,6)
|
||||
temp = "You attack for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
updateUsrDialog()
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
@@ -74,7 +74,7 @@
|
||||
var/pointamt = rand(1,3)
|
||||
var/healamt = rand(6,8)
|
||||
temp = "You use [pointamt] magic to heal for [healamt] damage!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
updateUsrDialog()
|
||||
turtle++
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
blocked = TRUE
|
||||
var/chargeamt = rand(4,7)
|
||||
temp = "You regain [chargeamt] points"
|
||||
playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp += chargeamt
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
@@ -124,7 +124,7 @@
|
||||
if(!gameover)
|
||||
gameover = TRUE
|
||||
temp = "[enemy_name] has fallen! Rejoice!"
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
|
||||
@@ -141,13 +141,13 @@
|
||||
else if ((obj_flags & EMAGGED) && (turtle >= 4))
|
||||
var/boomamt = rand(5,10)
|
||||
temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
|
||||
playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/boom.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp -= boomamt
|
||||
|
||||
else if ((enemy_mp <= 5) && (prob(70)))
|
||||
var/stealamt = rand(2,3)
|
||||
temp = "[enemy_name] steals [stealamt] of your power!"
|
||||
playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp -= stealamt
|
||||
updateUsrDialog()
|
||||
|
||||
@@ -155,27 +155,27 @@
|
||||
gameover = TRUE
|
||||
sleep(turn_speed)
|
||||
temp = "You have been drained! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3)
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
else if ((enemy_hp <= 10) && (enemy_mp > 4))
|
||||
temp = "[enemy_name] heals for 4 health!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
enemy_hp += 4
|
||||
enemy_mp -= 4
|
||||
|
||||
else
|
||||
var/attackamt = rand(3,6)
|
||||
temp = "[enemy_name] attacks for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp -= attackamt
|
||||
|
||||
if ((player_mp <= 0) || (player_hp <= 0))
|
||||
gameover = TRUE
|
||||
temp = "You have been crushed! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3)
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
columns = 0
|
||||
mine_placed = 0
|
||||
if(href_list["Easy"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
@@ -87,7 +87,7 @@
|
||||
columns = 10
|
||||
mine_limit = 10
|
||||
if(href_list["Intermediate"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
@@ -96,7 +96,7 @@
|
||||
columns = 17
|
||||
mine_limit = 40
|
||||
if(href_list["Hard"])
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
|
||||
flag_text = "OFF"
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
@@ -110,9 +110,9 @@
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
reset_board = TRUE
|
||||
difficulty = "Custom"
|
||||
playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, startup_sound, 50, FALSE, extrarange = -3)
|
||||
if(href_list["Flag"])
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
|
||||
if(!flagging)
|
||||
flagging = TRUE
|
||||
flag_text = "ON"
|
||||
@@ -122,10 +122,10 @@
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, FALSE, extrarange = -3)
|
||||
web += "<font size='2'>Explode in the game, explode in real life!<br>What difficulty do you want to play?<br><br><br><br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font>"
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, FALSE, extrarange = -3)
|
||||
web += web_difficulty_menu
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_PLAYING)
|
||||
@@ -152,7 +152,7 @@
|
||||
if(table[y1][x1] < 10 && table[y1][x1] >= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode
|
||||
table[y1][x1] += 10
|
||||
if(table[y1][x1] != 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
|
||||
else
|
||||
if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON)
|
||||
game_status = MINESWEEPER_GAME_LOST
|
||||
@@ -164,14 +164,14 @@
|
||||
if(mine_sound)
|
||||
switch(rand(1,3)) //Play every time a mine is hit
|
||||
if(1)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, FALSE, extrarange = -3)
|
||||
if(2)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, FALSE, extrarange = -3)
|
||||
if(3)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, FALSE, extrarange = -3)
|
||||
mine_sound = FALSE
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, FALSE, extrarange = -3)
|
||||
if(table[y1][x1] >= 0) //Check that it's not already flagged
|
||||
table[y1][x1] -= 10
|
||||
else if(table[y1][x1] < 0) //If flagged, remove the flag
|
||||
@@ -182,7 +182,7 @@
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
if(table[y1][x1] >= 10) //If revealed, become unrevealed!
|
||||
if(mine_sound)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
mine_sound = FALSE
|
||||
table[y1][x1] -= 10
|
||||
if(table[y1][x1] > 10 && !reset_board)
|
||||
@@ -243,10 +243,10 @@
|
||||
if(safe_squares_revealed >= win_condition && game_status == MINESWEEPER_GAME_PLAYING)
|
||||
game_status = MINESWEEPER_GAME_WON
|
||||
if(rows < 10 || columns < 10) //If less than easy difficulty
|
||||
playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, FALSE, extrarange = -3)
|
||||
say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!")
|
||||
else
|
||||
playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, FALSE, extrarange = -3)
|
||||
say("You cleared the board of all mines! Congratulations!")
|
||||
if(CHECK_BITFIELD(obj_flags, EMAGGED))
|
||||
var/itemname
|
||||
@@ -299,32 +299,32 @@
|
||||
ENABLE_BITFIELD(obj_flags, EMAGGED)
|
||||
if(game_status == MINESWEEPER_GAME_MAIN_MENU)
|
||||
to_chat(user, "<span class='warning'>An ominous tune plays from the arcade's speakers!</span>")
|
||||
playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10)
|
||||
playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, FALSE, extrarange = 3)
|
||||
else //Can't let you do that, star fox!
|
||||
to_chat(user, "<span class='warning'>The machine buzzes and sparks... the game has been reset!</span>")
|
||||
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz
|
||||
playsound(user, 'sound/machines/buzz-sigh.ogg', 100, FALSE, extrarange = 3) //Loud buzz
|
||||
game_status = MINESWEEPER_GAME_MAIN_MENU
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3) //Entered into the menu so ping sound
|
||||
var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num
|
||||
if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return FALSE
|
||||
new_rows = clamp(new_rows + 1, 4, 30)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num
|
||||
if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return FALSE
|
||||
new_columns = clamp(new_columns + 1, 4, 50)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
var/grid_area = (new_rows - 1) * (new_columns - 1)
|
||||
var/lower_limit = round(grid_area*0.156)
|
||||
var/upper_limit = round(grid_area*0.85)
|
||||
var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num
|
||||
if(!new_mine_limit || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return FALSE
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
rows = new_rows
|
||||
columns = new_columns
|
||||
mine_limit = clamp(new_mine_limit, lower_limit, upper_limit)
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
to_chat(c_user, "<span class='warning'>You move your hand towards the machine, and begin to hesitate as a bloodied guillotine emerges from inside of it...</span>")
|
||||
if(do_after(c_user, 50, target = src))
|
||||
to_chat(c_user, "<span class='userdanger'>The guillotine drops on your arm, and the machine sucks it in!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, TRUE, -1)
|
||||
var/which_hand = BODY_ZONE_L_ARM
|
||||
if(!(c_user.active_hand_index % 2))
|
||||
which_hand = BODY_ZONE_R_ARM
|
||||
var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand)
|
||||
chopchop.dismember()
|
||||
qdel(chopchop)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3)
|
||||
for(var/i=1; i<=rand(3,5); i++)
|
||||
prizevend(user)
|
||||
else
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
. = ..()
|
||||
SSradio.remove_object(src, air_frequency)
|
||||
air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM)
|
||||
open()
|
||||
INVOKE_ASYNC(src, .proc/open)
|
||||
|
||||
/obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal)
|
||||
..()
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
|
||||
/obj/machinery/quantumpad/proc/doteleport(mob/user, obj/machinery/quantumpad/target_pad = linked_pad)
|
||||
if(target_pad)
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1)
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE)
|
||||
teleporting = TRUE
|
||||
|
||||
spawn(teleport_speed)
|
||||
@@ -155,9 +155,9 @@
|
||||
target_pad.sparks()
|
||||
|
||||
flick("qpad-beam", src)
|
||||
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
|
||||
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, TRUE)
|
||||
flick("qpad-beam", target_pad)
|
||||
playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
|
||||
playsound(get_turf(target_pad), 'sound/weapons/emitter2.ogg', 25, TRUE)
|
||||
for(var/atom/movable/ROI in get_turf(src))
|
||||
if(QDELETED(ROI))
|
||||
continue //sleeps in CHECK_TICK
|
||||
|
||||
@@ -100,51 +100,54 @@
|
||||
eat(AM)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/recycler/proc/eat(atom/AM0)
|
||||
if(stat & (BROKEN|NOPOWER) || safety_mode)
|
||||
/obj/machinery/recycler/proc/eat(atom/movable/AM0, sound=TRUE)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(safety_mode)
|
||||
return
|
||||
if(!isturf(AM0.loc))
|
||||
return //I don't know how you called Crossed() but stop it.
|
||||
|
||||
var/list/to_eat
|
||||
var/list/to_eat = AM0.GetAllContents()
|
||||
|
||||
to_eat = list(AM0)
|
||||
var/living_detected = FALSE //technically includes silicons as well but eh
|
||||
var/list/nom = list()
|
||||
var/list/crunchy_nom = list() //Mobs have to be handled differently so they get a different list instead of checking them multiple times.
|
||||
|
||||
var/items_recycled = 0
|
||||
var/buzz = FALSE
|
||||
for(var/i in to_eat)
|
||||
var/atom/movable/AM = i
|
||||
if(QDELETED(AM))
|
||||
continue
|
||||
var/obj/item/bodypart/head/as_head = AM
|
||||
var/obj/item/mmi/as_mmi = AM
|
||||
var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay)
|
||||
if(brain_holder)
|
||||
if(obj_flags & EMAGGED)
|
||||
continue
|
||||
else
|
||||
emergency_stop(AM)
|
||||
return
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/bodypart/head/as_head = AM
|
||||
var/obj/item/mmi/as_mmi = AM
|
||||
if(istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /obj/item/dullahan_relay))
|
||||
living_detected = TRUE
|
||||
nom += AM
|
||||
else if(isliving(AM))
|
||||
if((obj_flags & EMAGGED)||((!allowed(AM))&&(!ishuman(AM))))
|
||||
to_eat += crush_living(AM)
|
||||
else
|
||||
emergency_stop(AM)
|
||||
return
|
||||
else if(isitem(AM))
|
||||
var/obj/O = AM
|
||||
if(O.resistance_flags & INDESTRUCTIBLE)
|
||||
buzz = TRUE
|
||||
O.forceMove(loc)
|
||||
else
|
||||
to_eat += recycle_item(AM)
|
||||
items_recycled++
|
||||
else
|
||||
buzz = TRUE
|
||||
AM.forceMove(loc)
|
||||
|
||||
if(items_recycled)
|
||||
playsound(src, item_recycle_sound, 50, 1)
|
||||
if(buzz)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
living_detected = TRUE
|
||||
crunchy_nom += AM
|
||||
var/not_eaten = to_eat.len - nom.len - crunchy_nom.len
|
||||
if(living_detected) // First, check if we have any living beings detected.
|
||||
if(obj_flags & EMAGGED)
|
||||
for(var/CRUNCH in crunchy_nom) // Eat them and keep going because we don't care about safety.
|
||||
if(isliving(CRUNCH)) // MMIs and brains will get eaten like normal items
|
||||
crush_living(CRUNCH)
|
||||
else // Stop processing right now without eating anything.
|
||||
emergency_stop()
|
||||
return
|
||||
for(var/nommed in nom)
|
||||
recycle_item(nommed)
|
||||
if(nom.len && sound)
|
||||
playsound(src, item_recycle_sound, (50 + nom.len*5), TRUE, nom.len, ignore_walls = (nom.len - 10)) // As a substitute for playing 50 sounds at once.
|
||||
if(not_eaten)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', (50 + not_eaten*5), FALSE, not_eaten, ignore_walls = (not_eaten - 10)) // Ditto.
|
||||
if(!ismob(AM0))
|
||||
AM0.moveToNullspace()
|
||||
qdel(AM0)
|
||||
else // Lets not move a mob to nullspace and qdel it, yes?
|
||||
for(var/i in AM0.contents)
|
||||
var/atom/movable/content = i
|
||||
content.moveToNullspace()
|
||||
qdel(content)
|
||||
|
||||
/obj/machinery/recycler/proc/recycle_item(obj/item/I)
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#define SPIN_TIME 65 //As always, deciseconds.
|
||||
#define REEL_DEACTIVATE_DELAY 7
|
||||
#define SEVEN "<font color='red'>7</font>"
|
||||
#define HOLOCHIP 1
|
||||
#define COIN 2
|
||||
|
||||
/obj/machinery/computer/slot_machine
|
||||
name = "slot machine"
|
||||
@@ -21,40 +23,48 @@
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 50
|
||||
circuit = /obj/item/circuitboard/computer/slot_machine
|
||||
light_color = LIGHT_COLOR_BROWN
|
||||
var/money = 3000 //How much money it has CONSUMED
|
||||
var/plays = 0
|
||||
var/working = 0
|
||||
var/working = FALSE
|
||||
var/balance = 0 //How much money is in the machine, ready to be CONSUMED.
|
||||
var/jackpots = 0
|
||||
var/paymode = HOLOCHIP //toggles between HOLOCHIP/COIN, defined above
|
||||
var/cointype = /obj/item/coin/iron //default cointype
|
||||
var/list/coinvalues = list()
|
||||
var/list/reels = list(list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0, list("", "", "") = 0)
|
||||
var/list/symbols = list(SEVEN = 1, "<font color='orange'>&</font>" = 2, "<font color='yellow'>@</font>" = 2, "<font color='green'>$</font>" = 2, "<font color='blue'>?</font>" = 2, "<font color='grey'>#</font>" = 2, "<font color='white'>!</font>" = 2, "<font color='fuchsia'>%</font>" = 2) //if people are winning too much, multiply every number in this list by 2 and see if they are still winning too much.
|
||||
|
||||
light_color = LIGHT_COLOR_BROWN
|
||||
|
||||
/obj/machinery/computer/slot_machine/Initialize()
|
||||
. = ..()
|
||||
jackpots = rand(1, 4) //false hope
|
||||
plays = rand(75, 200)
|
||||
|
||||
toggle_reel_spin(1) //The reels won't spin unless we activate them
|
||||
INVOKE_ASYNC(src, .proc/toggle_reel_spin, TRUE)//The reels won't spin unless we activate them
|
||||
|
||||
var/list/reel = reels[1]
|
||||
for(var/i = 0, i < reel.len, i++) //Populate the reels.
|
||||
randomize_reels()
|
||||
|
||||
toggle_reel_spin(0)
|
||||
INVOKE_ASYNC(src, .proc/toggle_reel_spin, FALSE)
|
||||
|
||||
for(cointype in typesof(/obj/item/coin))
|
||||
var/obj/item/coin/C = new cointype
|
||||
coinvalues["[cointype]"] = C.get_item_credit_value()
|
||||
qdel(C) //Sigh
|
||||
|
||||
/obj/machinery/computer/slot_machine/Destroy()
|
||||
if(balance)
|
||||
give_coins(balance)
|
||||
give_payout(balance)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/slot_machine/process()
|
||||
/obj/machinery/computer/slot_machine/process(delta_time)
|
||||
. = ..() //Sanity checks.
|
||||
if(!.)
|
||||
return .
|
||||
|
||||
money++ //SPESSH MAJICKS
|
||||
money += round(delta_time / 2) //SPESSH MAJICKS
|
||||
|
||||
/obj/machinery/computer/slot_machine/update_icon_state()
|
||||
if(stat & NOPOWER)
|
||||
@@ -69,27 +79,46 @@
|
||||
else
|
||||
icon_state = "slots1"
|
||||
|
||||
/obj/machinery/computer/slot_machine/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/slot_machine/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/coin))
|
||||
var/obj/item/coin/C = I
|
||||
if(prob(2))
|
||||
if(!user.transferItemToLoc(C, drop_location()))
|
||||
return
|
||||
C.throw_at(user, 3, 10)
|
||||
if(prob(10))
|
||||
balance = max(balance - SPIN_PRICE, 0)
|
||||
to_chat(user, "<span class='warning'>[src] spits your coin back out!</span>")
|
||||
if(paymode == COIN)
|
||||
if(prob(2))
|
||||
if(!user.transferItemToLoc(C, drop_location()))
|
||||
return
|
||||
C.throw_at(user, 3, 10)
|
||||
if(prob(10))
|
||||
balance = max(balance - SPIN_PRICE, 0)
|
||||
to_chat(user, "<span class='warning'>[src] spits your coin back out!</span>")
|
||||
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(C))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert [C] into [src]'s slot!</span>")
|
||||
balance += C.value
|
||||
qdel(C)
|
||||
else
|
||||
if(!user.temporarilyRemoveItemFromInventory(C))
|
||||
to_chat(user, "<span class='warning'>This machine is only accepting holochips!</span>")
|
||||
else if(istype(I, /obj/item/holochip))
|
||||
if(paymode == HOLOCHIP)
|
||||
var/obj/item/holochip/H = I
|
||||
if(!user.temporarilyRemoveItemFromInventory(H))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert [C] into [src]'s slot!</span>")
|
||||
balance += C.value
|
||||
qdel(C)
|
||||
to_chat(user, "<span class='notice'>You insert [H.credits] holocredits into [src]'s slot!</span>")
|
||||
balance += H.credits
|
||||
qdel(H)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This machine is only accepting coins!</span>")
|
||||
else if(I.tool_behaviour == TOOL_MULTITOOL)
|
||||
if(balance > 0)
|
||||
visible_message("<b>[src]</b> says, 'ERROR! Please empty the machine balance before altering paymode'") //Prevents converting coins into holocredits and vice versa
|
||||
else
|
||||
if(paymode == HOLOCHIP)
|
||||
paymode = COIN
|
||||
visible_message("<b>[src]</b> says, 'This machine now works with COINS!'")
|
||||
else
|
||||
paymode = HOLOCHIP
|
||||
visible_message("<b>[src]</b> says, 'This machine now works with HOLOCHIPS!'")
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -101,8 +130,7 @@
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(4, 0, src.loc)
|
||||
spark_system.start()
|
||||
playsound(src, "sparks", 50, 1)
|
||||
return TRUE
|
||||
playsound(src, "sparks", 50, TRUE)
|
||||
|
||||
/obj/machinery/computer/slot_machine/ui_interact(mob/living/user)
|
||||
. = ..()
|
||||
@@ -127,8 +155,9 @@
|
||||
<A href='?src=[REF(src)];spin=1'>Play!</A><BR>
|
||||
<BR>
|
||||
[reeltext]
|
||||
<BR>
|
||||
<font size='1'><A href='?src=[REF(src)];refund=1'>Refund balance</A><BR>"}
|
||||
<BR>"}
|
||||
if(balance > 0)
|
||||
dat+="<font size='1'><A href='?src=[REF(src)];refund=1'>Refund balance</A><BR>"
|
||||
|
||||
var/datum/browser/popup = new(user, "slotmachine", "Slot Machine")
|
||||
popup.set_content(dat)
|
||||
@@ -143,21 +172,22 @@
|
||||
spin(usr)
|
||||
|
||||
else if(href_list["refund"])
|
||||
give_coins(balance)
|
||||
balance = 0
|
||||
if(balance > 0)
|
||||
give_payout(balance)
|
||||
balance = 0
|
||||
|
||||
/obj/machinery/computer/slot_machine/emp_act(severity)
|
||||
. = ..()
|
||||
if(stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
if(prob(1500 / severity))
|
||||
if(prob(15 * severity))
|
||||
return
|
||||
if(prob(1 * severity/100)) // :^)
|
||||
if(prob(1)) // :^)
|
||||
obj_flags |= EMAGGED
|
||||
var/severity_ascending = 4 - severity
|
||||
money = max(rand(money - (200 * severity_ascending), money + (200 * severity_ascending)), 0)
|
||||
balance = max(rand(balance - (50 * severity_ascending), balance + (50 * severity_ascending)), 0)
|
||||
money -= max(0, give_coins(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo
|
||||
money -= max(0, give_payout(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo
|
||||
spin()
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/spin(mob/user)
|
||||
@@ -174,37 +204,43 @@
|
||||
balance -= SPIN_PRICE
|
||||
money += SPIN_PRICE
|
||||
plays += 1
|
||||
working = 1
|
||||
working = TRUE
|
||||
|
||||
toggle_reel_spin(1)
|
||||
update_icon()
|
||||
updateDialog()
|
||||
|
||||
spawn(0)
|
||||
while(working)
|
||||
randomize_reels()
|
||||
updateDialog()
|
||||
sleep(2)
|
||||
var/spin_loop = addtimer(CALLBACK(src, .proc/do_spin), 2, TIMER_LOOP|TIMER_STOPPABLE)
|
||||
|
||||
spawn(SPIN_TIME - (REEL_DEACTIVATE_DELAY * reels.len)) //WARNING: no sanity checking for user since it's not needed and would complicate things (machine should still spin even if user is gone), be wary of this if you're changing this code.
|
||||
toggle_reel_spin(0, REEL_DEACTIVATE_DELAY)
|
||||
working = 0
|
||||
give_prizes(the_name, user)
|
||||
update_icon()
|
||||
updateDialog()
|
||||
addtimer(CALLBACK(src, .proc/finish_spinning, spin_loop, user, the_name), SPIN_TIME - (REEL_DEACTIVATE_DELAY * reels.len))
|
||||
//WARNING: no sanity checking for user since it's not needed and would complicate things (machine should still spin even if user is gone), be wary of this if you're changing this code.
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/do_spin()
|
||||
randomize_reels()
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/finish_spinning(spin_loop, mob/user, the_name)
|
||||
toggle_reel_spin(0, REEL_DEACTIVATE_DELAY)
|
||||
working = FALSE
|
||||
deltimer(spin_loop)
|
||||
give_prizes(the_name, user)
|
||||
update_icon()
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/can_spin(mob/user)
|
||||
if(stat & NOPOWER)
|
||||
to_chat(user, "<span class='warning'>The slot machine has no power!</span>")
|
||||
return FALSE
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>The slot machine is broken!</span>")
|
||||
return FALSE
|
||||
if(working)
|
||||
to_chat(user, "<span class='warning'>You need to wait until the machine stops spinning before you can play again!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(balance < SPIN_PRICE)
|
||||
to_chat(user, "<span class='warning'>Insufficient money to play!</span>")
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/toggle_reel_spin(value, delay = 0) //value is 1 or 0 aka on or off
|
||||
for(var/list/reel in reels)
|
||||
@@ -223,23 +259,25 @@
|
||||
var/linelength = get_lines()
|
||||
|
||||
if(reels[1][2] + reels[2][2] + reels[3][2] + reels[4][2] + reels[5][2] == "[SEVEN][SEVEN][SEVEN][SEVEN][SEVEN]")
|
||||
visible_message("<b>[src]</b> says, 'JACKPOT! You win [money] credits worth of coins!'")
|
||||
visible_message("<b>[src]</b> says, 'JACKPOT! You win [money] credits!'")
|
||||
priority_announce("Congratulations to [user ? user.real_name : usrname] for winning the jackpot at the slot machine in [get_area(src)]!")
|
||||
jackpots += 1
|
||||
balance += money - give_coins(JACKPOT)
|
||||
balance += money - give_payout(JACKPOT)
|
||||
money = 0
|
||||
|
||||
for(var/i = 0, i < 5, i++)
|
||||
var/cointype = pick(subtypesof(/obj/item/coin))
|
||||
var/obj/item/coin/C = new cointype(loc)
|
||||
random_step(C, 2, 50)
|
||||
if(paymode == HOLOCHIP)
|
||||
new /obj/item/holochip(loc,JACKPOT)
|
||||
else
|
||||
for(var/i = 0, i < 5, i++)
|
||||
cointype = pick(subtypesof(/obj/item/coin))
|
||||
var/obj/item/coin/C = new cointype(loc)
|
||||
random_step(C, 2, 50)
|
||||
|
||||
else if(linelength == 5)
|
||||
visible_message("<b>[src]</b> says, 'Big Winner! You win a thousand credits worth of coins!'")
|
||||
visible_message("<b>[src]</b> says, 'Big Winner! You win a thousand credits!'")
|
||||
give_money(BIG_PRIZE)
|
||||
|
||||
else if(linelength == 4)
|
||||
visible_message("<b>[src]</b> says, 'Winner! You win four hundred credits worth of coins!'")
|
||||
visible_message("<b>[src]</b> says, 'Winner! You win four hundred credits!'")
|
||||
give_money(SMALL_PRIZE)
|
||||
|
||||
else if(linelength == 3)
|
||||
@@ -271,12 +309,15 @@
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/give_money(amount)
|
||||
var/amount_to_give = money >= amount ? amount : money
|
||||
var/surplus = amount_to_give - give_coins(amount_to_give)
|
||||
var/surplus = amount_to_give - give_payout(amount_to_give)
|
||||
money = max(0, money - amount)
|
||||
balance += surplus
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/give_coins(amount)
|
||||
var/cointype = obj_flags & EMAGGED ? /obj/item/coin/iron : /obj/item/coin/silver
|
||||
/obj/machinery/computer/slot_machine/proc/give_payout(amount)
|
||||
if(paymode == HOLOCHIP)
|
||||
cointype = /obj/item/holochip
|
||||
else
|
||||
cointype = obj_flags & EMAGGED ? /obj/item/coin/iron : /obj/item/coin/silver
|
||||
|
||||
if(!(obj_flags & EMAGGED))
|
||||
amount = dispense(amount, cointype, null, 0)
|
||||
@@ -288,22 +329,25 @@
|
||||
|
||||
return amount
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/dispense(amount = 0, cointype = /obj/item/coin/silver, mob/living/target, throwit = FALSE)
|
||||
var/value = GLOB.coin_values[cointype] || GLOB.coin_values[/obj/item/coin/iron]
|
||||
INVOKE_ASYNC(src, .proc/become_rich, amount, value, cointype, target, throwit)
|
||||
return amount % value
|
||||
/obj/machinery/computer/slot_machine/proc/dispense(amount = 0, cointype = /obj/item/coin/silver, mob/living/target, throwit = 0)
|
||||
if(paymode == HOLOCHIP)
|
||||
var/obj/item/holochip/H = new /obj/item/holochip(loc,amount)
|
||||
|
||||
/obj/machinery/computer/slot_machine/proc/become_rich(amount, value, cointype = /obj/item/coin/silver, mob/living/target, throwit = FALSE)
|
||||
if(value <= 0)
|
||||
return
|
||||
while(amount >= value && !QDELETED(src))
|
||||
var/obj/item/coin/C = new cointype(loc) //DOUBLE THE PAIN
|
||||
amount -= value
|
||||
if(throwit && target)
|
||||
C.throw_at(target, 3, 10)
|
||||
else
|
||||
random_step(C, 2, 40)
|
||||
CHECK_TICK
|
||||
H.throw_at(target, 3, 10)
|
||||
else
|
||||
var/value = coinvalues["[cointype]"]
|
||||
if(value <= 0)
|
||||
CRASH("Coin value of zero, refusing to payout in dispenser")
|
||||
while(amount >= value)
|
||||
var/obj/item/coin/C = new cointype(loc) //DOUBLE THE PAIN
|
||||
amount -= value
|
||||
if(throwit && target)
|
||||
C.throw_at(target, 3, 10)
|
||||
else
|
||||
random_step(C, 2, 40)
|
||||
|
||||
return amount
|
||||
|
||||
#undef SEVEN
|
||||
#undef SPIN_TIME
|
||||
@@ -311,3 +355,5 @@
|
||||
#undef BIG_PRIZE
|
||||
#undef SMALL_PRIZE
|
||||
#undef SPIN_PRICE
|
||||
#undef HOLOCHIP
|
||||
#undef COIN
|
||||
|
||||
@@ -578,6 +578,7 @@
|
||||
|
||||
/obj/mecha/proc/mechstep(direction)
|
||||
var/current_dir = dir
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(step_in))
|
||||
var/result = step(src,direction)
|
||||
if(strafe)
|
||||
setDir(current_dir)
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
if(.)
|
||||
return
|
||||
if(can_buckle && has_buckled_mobs())
|
||||
if(ishuman(src)) //prevent people from unbuckling fireman-carried/piggybacked people unless on disarm or harm intents
|
||||
if(act_intent == INTENT_HELP || act_intent == INTENT_GRAB)
|
||||
return
|
||||
if(buckled_mobs.len > 1)
|
||||
var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs
|
||||
if(user_unbuckle_mob(unbuckled,user))
|
||||
@@ -84,16 +87,22 @@
|
||||
M.IgniteMob()
|
||||
|
||||
/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force=FALSE)
|
||||
if(istype(buckled_mob) && buckled_mob.buckled == src && (buckled_mob.can_unbuckle() || force))
|
||||
. = buckled_mob
|
||||
buckled_mob.buckled = null
|
||||
buckled_mob.anchored = initial(buckled_mob.anchored)
|
||||
buckled_mob.update_mobility()
|
||||
buckled_mob.clear_alert("buckled")
|
||||
buckled_mobs -= buckled_mob
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
|
||||
if(!isliving(buckled_mob))
|
||||
CRASH("Non-living [buckled_mob] thing called unbuckle_mob() for source.")
|
||||
if(buckled_mob.buckled != src)
|
||||
CRASH("[buckled_mob] called unbuckle_mob() for source while having buckled as [buckled_mob.buckled].")
|
||||
if(!force && !buckled_mob.can_unbuckle())
|
||||
return
|
||||
. = buckled_mob
|
||||
buckled_mob.buckled = null
|
||||
buckled_mob.anchored = initial(buckled_mob.anchored)
|
||||
buckled_mob.update_mobility()
|
||||
buckled_mob.clear_alert("buckled")
|
||||
buckled_mob.set_glide_size(DELAY_TO_GLIDE_SIZE(buckled_mob.total_multiplicative_slowdown()))
|
||||
buckled_mobs -= buckled_mob
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
|
||||
|
||||
post_unbuckle_mob(.)
|
||||
post_unbuckle_mob(.)
|
||||
|
||||
/atom/movable/proc/unbuckle_all_mobs(force=FALSE)
|
||||
if(!has_buckled_mobs())
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
return 0
|
||||
|
||||
/obj/effect/acid/Crossed(AM as mob|obj)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.movement_type & FLYING)
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
|
||||
/obj/effect/anomaly/grav/high/Initialize(mapload, new_lifespan)
|
||||
. = ..()
|
||||
setup_grav_field()
|
||||
INVOKE_ASYNC(src, .proc/setup_grav_field)
|
||||
|
||||
/obj/effect/anomaly/grav/high/proc/setup_grav_field()
|
||||
grav_field = make_field(/datum/proximity_monitor/advanced/gravity, list("current_range" = 7, "host" = src, "gravity_value" = rand(0,3)))
|
||||
|
||||
@@ -69,4 +69,5 @@
|
||||
persistent = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/oil/slippery/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/list/checkers //list of /obj/effect/abstract/proximity_checkers
|
||||
var/current_range
|
||||
var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf
|
||||
var/wire = FALSE
|
||||
|
||||
/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
|
||||
checkers = list()
|
||||
@@ -35,6 +36,8 @@
|
||||
return ..()
|
||||
|
||||
/datum/proximity_monitor/proc/HandleMove()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/_host = host
|
||||
var/atom/new_host_loc = _host.loc
|
||||
if(last_host_loc != new_host_loc)
|
||||
@@ -58,6 +61,8 @@
|
||||
var/atom/_host = host
|
||||
|
||||
var/atom/loc_to_use = ignore_if_not_on_turf ? _host.loc : get_turf(_host)
|
||||
if(wire && !isturf(loc_to_use)) //it makes assemblies attached on wires work
|
||||
loc_to_use = get_turf(loc_to_use)
|
||||
if(!isturf(loc_to_use)) //only check the host's loc
|
||||
if(range)
|
||||
var/obj/effect/abstract/proximity_checker/pc
|
||||
@@ -109,4 +114,5 @@
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
|
||||
set waitfor = FALSE
|
||||
monitor?.hasprox_receiver.HasProximity(AM)
|
||||
. = ..()
|
||||
monitor?.hasprox_receiver?.HasProximity(AM)
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
/obj/item/clothing/under/rank/civilian/mime/sexy)
|
||||
|
||||
/obj/effect/spawner/bundle/crate/Initialize(mapload)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
if(items && items.len)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/closet/LC = locate(/obj/structure/closet) in T
|
||||
|
||||
@@ -664,9 +664,8 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 12,
|
||||
/obj/item/weaponcrafting/receiver = 25,
|
||||
/obj/item/weaponcrafting/stock = 25,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
@@ -674,8 +673,8 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 80,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 5,
|
||||
/obj/item/weaponcrafting/receiver = 5,
|
||||
/obj/item/weaponcrafting/stock = 5,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
message_admins("An alien egg has been delivered to [ADMIN_VERBOSEJMP(T)].")
|
||||
log_game("An alien egg has been delivered to [AREACOORD(T)]")
|
||||
var/message = "Attention [station_name()], we have entrusted you with a research specimen in [get_area_name(T, TRUE)]. Remember to follow all safety precautions when dealing with the specimen."
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, CALLBACK(GLOBAL_PROC, /proc/print_command_report, message), announcement_time))
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/_addtimer, CALLBACK(GLOBAL_PROC, /proc/print_command_report, message), announcement_time))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
+30
-17
@@ -428,18 +428,19 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/obj/item/proc/dropped(mob/user)
|
||||
/// Called when a mob drops an item.
|
||||
/obj/item/proc/dropped(mob/user, silent = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
current_equipped_slot = null
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(user)
|
||||
if(item_flags & DROPDEL)
|
||||
qdel(src)
|
||||
item_flags &= ~IN_INVENTORY
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user) & COMPONENT_DROPPED_RELOCATION)
|
||||
. = ITEM_RELOCATED_BY_DROPPED
|
||||
user.update_equipment_speed_mods()
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
|
||||
// if(!silent)
|
||||
// playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE)
|
||||
user?.update_equipment_speed_mods()
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
@@ -478,23 +479,33 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
over.MouseDrop_T(src,usr)
|
||||
return
|
||||
|
||||
// called after an item is placed in an equipment slot
|
||||
// user is mob that equipped it
|
||||
// slot uses the slot_X defines found in setup.dm
|
||||
// for items that can be placed in multiple slots
|
||||
// note this isn't called during the initial dressing of a player
|
||||
/obj/item/proc/equipped(mob/user, slot)
|
||||
/**
|
||||
* Called after an item is placed in an equipment slot.
|
||||
*
|
||||
* Note that hands count as slots.
|
||||
*
|
||||
* Arguments:
|
||||
* * user is mob that equipped it
|
||||
* * slot uses the slot_X defines found in setup.dm for items that can be placed in multiple slots
|
||||
* * Initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it
|
||||
*/
|
||||
/obj/item/proc/equipped(mob/user, slot, initial = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
. = SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
|
||||
current_equipped_slot = slot
|
||||
if(!(. & COMPONENT_NO_GRANT_ACTIONS))
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
|
||||
A.Grant(user)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
|
||||
A.Grant(user)
|
||||
item_flags |= IN_INVENTORY
|
||||
// if(!initial)
|
||||
// if(equip_sound && (slot_flags & slot))
|
||||
// playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
|
||||
// else if(slot == ITEM_SLOT_HANDS)
|
||||
// playsound(src, pickup_sound, PICKUP_SOUND_VOLUME, ignore_walls = FALSE)
|
||||
user.update_equipment_speed_mods()
|
||||
|
||||
|
||||
//Overlays for the worn overlay so you can overlay while you overlay
|
||||
//eg: ammo counters, primed grenade flashing, etc.
|
||||
//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file
|
||||
@@ -661,6 +672,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
else
|
||||
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
|
||||
|
||||
// else
|
||||
// playsound(src, drop_sound, YEET_SOUND_VOLUME, ignore_walls = FALSE)
|
||||
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
|
||||
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
|
||||
|
||||
@@ -263,6 +263,7 @@
|
||||
/obj/machinery/vending/cola = "Robust Softdrinks",
|
||||
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
|
||||
/obj/machinery/vending/games = "\improper Good Clean Fun",
|
||||
/obj/machinery/vending/kink = "KinkMate",
|
||||
/obj/machinery/vending/autodrobe = "AutoDrobe",
|
||||
/obj/machinery/vending/assist = "\improper Vendomat",
|
||||
/obj/machinery/vending/engivend = "\improper Engi-Vend",
|
||||
|
||||
@@ -347,9 +347,9 @@
|
||||
last_hearcheck = world.time
|
||||
for(var/mob/H in hearing_mobs)
|
||||
if(!istype(H.loc, /obj/item/dogborg/sleeper))
|
||||
H.playsound_local(source, null, 45, falloff = 0, S = pred_death)
|
||||
H.playsound_local(source, null, 45, S = pred_death)
|
||||
else if(H in contents)
|
||||
H.playsound_local(source, null, 65, falloff = 0, S = prey_death)
|
||||
H.playsound_local(source, null, 65, S = prey_death)
|
||||
for(var/belly in T.vore_organs)
|
||||
var/obj/belly/B = belly
|
||||
for(var/atom/movable/thing in B)
|
||||
@@ -391,9 +391,9 @@
|
||||
last_hearcheck = world.time
|
||||
for(var/mob/H in hearing_mobs)
|
||||
if(!istype(H.loc, /obj/item/dogborg/sleeper))
|
||||
H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
|
||||
H.playsound_local(source, null, 45, S = pred_digest)
|
||||
else if(H in contents)
|
||||
H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
|
||||
H.playsound_local(source, null, 65, S = prey_digest)
|
||||
|
||||
update_gut(hound)
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/obj/item/grenade/plastic/Crossed(atom/movable/AM)
|
||||
if(nadeassembly)
|
||||
nadeassembly.Crossed(AM)
|
||||
. = ..()
|
||||
|
||||
/obj/item/grenade/plastic/on_found(mob/finder)
|
||||
if(nadeassembly)
|
||||
|
||||
@@ -803,6 +803,7 @@
|
||||
force = 4
|
||||
throwforce = 0
|
||||
attack_verb = list("whipped", "repented", "lashed", "flagellated")
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
var/praying = FALSE
|
||||
var/deity_name = "Coderbus" //This is the default, hopefully won't actually appear if the religion subsystem is running properly
|
||||
|
||||
|
||||
@@ -466,6 +466,7 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/random/Initialize()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
var/newtype
|
||||
var/list/snowflake_list = CONFIG_GET(keyed_list/snowflake_plushies)
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
/obj/item/pressure_plate/hologrid/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(trigger_item && istype(AM, specific_item) && !claimed)
|
||||
AM.anchored = TRUE
|
||||
AM.set_anchored(TRUE)
|
||||
flick("laserbox_burn", AM)
|
||||
trigger()
|
||||
QDEL_IN(src, 15)
|
||||
|
||||
@@ -173,11 +173,11 @@
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
use(2)
|
||||
else if(I.is_drainable() && I.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine))
|
||||
if(!I.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine, 10))
|
||||
if(!I.reagents.has_reagent(/datum/reagent/space_cleaner/sterilizine, 5))
|
||||
to_chat(user, "<span class='warning'>There's not enough sterilizine in [I] to sterilize [src]!</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [I] onto [src], sterilizing it.</span>", "<span class='notice'>You pour the contents of [I] onto [src], sterilizing it.</span>")
|
||||
I.reagents.remove_reagent(/datum/reagent/space_cleaner/sterilizine, 10)
|
||||
user.visible_message("<span class='notice'>[user] sterilizes [src] with the contents of [I].</span>", "<span class='notice'>You pour the contents of [I] onto [src], sterilizing it.</span>")
|
||||
I.reagents.remove_reagent(/datum/reagent/space_cleaner/sterilizine, 5)
|
||||
new /obj/item/stack/medical/gauze/adv/one(user.drop_location())
|
||||
use(1)
|
||||
else
|
||||
@@ -187,6 +187,9 @@
|
||||
user.visible_message("<span class='suicide'>[user] begins tightening \the [src] around [user.p_their()] neck! It looks like [user.p_they()] forgot how to use medical supplies!</span>")
|
||||
return OXYLOSS
|
||||
|
||||
/obj/item/stack/medical/gauze/one
|
||||
amount = 1
|
||||
|
||||
/obj/item/stack/medical/gauze/improvised
|
||||
name = "improvised gauze"
|
||||
singular_name = "improvised gauze"
|
||||
@@ -204,8 +207,9 @@
|
||||
heal_brute = 6
|
||||
self_delay = 45
|
||||
other_delay = 15
|
||||
absorption_rate = 0.4
|
||||
absorption_capacity = 6
|
||||
absorption_rate = 0.5
|
||||
absorption_capacity = 12
|
||||
splint_factor = 0.15
|
||||
|
||||
/obj/item/stack/medical/gauze/adv/one
|
||||
amount = 1
|
||||
@@ -472,3 +476,51 @@
|
||||
return TRUE
|
||||
|
||||
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
|
||||
|
||||
/obj/item/stack/medical/nanogel
|
||||
name = "nanogel"
|
||||
singular_name = "nanogel"
|
||||
desc = "A highly advanced gel that when applied on a sufficiently repaired robotic limb will neutralize internal damage if present, allowing further repairs without the need for surgery."
|
||||
self_delay = 150 //Agonizingly slow if used on self, but, not completely forbidden because antags with robolimbs need a way to handle their thresholds.
|
||||
other_delay = 30 //Pretty fast if used on others.
|
||||
amount = 12
|
||||
max_amount = 12 //Two synths worth of fixing, if every single bodypart of them has internal damage. Usually, probably more like 6-12.
|
||||
icon_state = "nanogel"
|
||||
var/being_applied = FALSE //No doafter stacking.
|
||||
|
||||
/obj/item/stack/medical/nanogel/try_heal(mob/living/M, mob/user, silent = FALSE)
|
||||
if(being_applied)
|
||||
to_chat(user, "<span class='warning'>You are already applying [src]!</span>")
|
||||
return
|
||||
if(!iscarbon(M))
|
||||
to_chat(user, "<span class='warning'>This won't work on [M]!</span>")
|
||||
return
|
||||
being_applied = TRUE
|
||||
..()
|
||||
being_applied = FALSE
|
||||
|
||||
/obj/item/stack/medical/nanogel/heal(mob/living/M, mob/user)
|
||||
var/mob/living/carbon/C = M //Only carbons should be able to get here
|
||||
if(!C)
|
||||
return
|
||||
var/obj/item/bodypart/affecting = C.get_bodypart(check_zone(user.zone_selected))
|
||||
if(!affecting) //Missing limb?
|
||||
to_chat(user, "<span class='warning'>[C] doesn't have \a [parse_zone(user.zone_selected)]!</span>")
|
||||
return
|
||||
if(!affecting.is_robotic_limb())
|
||||
to_chat(user, "<span class='warning'>This won't work on nonrobotic limbs!</span>")
|
||||
return
|
||||
if(!affecting.threshhold_brute_passed && !affecting.threshhold_burn_passed)
|
||||
to_chat(user, "<span class='warning'>There is no need to use this on [affecting]</span>")
|
||||
return
|
||||
if(affecting.threshhold_brute_passed && affecting.brute_dam == affecting.threshhold_passed_mindamage)
|
||||
. = TRUE
|
||||
affecting.threshhold_brute_passed = FALSE
|
||||
if(affecting.threshhold_burn_passed && affecting.burn_dam == affecting.threshhold_passed_mindamage)
|
||||
. = TRUE
|
||||
affecting.threshhold_burn_passed = FALSE
|
||||
if(.)
|
||||
user.visible_message("<span class='green'>The nanogel gets to work on [C], repairing [affecting]'s internal damage.</span>", "<span_class='green'>You watch as the nanogel gets to work on fixing the internal damage in [affecting]</span>")
|
||||
return
|
||||
//If it gets here: It failed, lets tell the user why.
|
||||
to_chat(user, "<span class='warning'>[src] fails to work on [affecting] due to residual [(affecting.threshhold_burn_passed && affecting.threshhold_burn_passed) ? "brute and burn" : "[affecting.threshhold_burn_passed ? "burn" : "brute"]"] damage! Perform some external repairs before using this.</span>")
|
||||
|
||||
@@ -246,7 +246,6 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
new /datum/stack_recipe("pew (right)", /obj/structure/chair/pew/right, 3, one_per_turf = TRUE, on_floor = TRUE),\
|
||||
)),
|
||||
null, \
|
||||
new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 20), \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 20), \
|
||||
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \
|
||||
@@ -391,7 +390,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
new/datum/stack_recipe("construction bag", /obj/item/storage/bag/construction, 4), \
|
||||
null, \
|
||||
new/datum/stack_recipe("string", /obj/item/weaponcrafting/string, 1, time = 10), \
|
||||
new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 6), \
|
||||
new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 10), \
|
||||
new/datum/stack_recipe("rag", /obj/item/reagent_containers/rag, 1), \
|
||||
new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \
|
||||
new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
if(merge)
|
||||
for(var/obj/item/stack/S in loc)
|
||||
if(S.merge_type == merge_type)
|
||||
merge(S)
|
||||
INVOKE_ASYNC(src, .proc/merge, S)
|
||||
var/list/temp_recipes = get_main_recipes()
|
||||
recipes = temp_recipes.Copy()
|
||||
if(material_type)
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
return FALSE
|
||||
stunpwr *= round(stuncharge/hitcost, 0.1)
|
||||
|
||||
if(!user.UseStaminaBuffer(getweight(user, STAM_COST_BATON_MOB_MULT), warn = TRUE))
|
||||
if(user && !user.UseStaminaBuffer(getweight(user, STAM_COST_BATON_MOB_MULT), warn = TRUE))
|
||||
return FALSE
|
||||
|
||||
if(!disarming)
|
||||
@@ -317,12 +317,12 @@
|
||||
/obj/item/melee/baton/boomerang
|
||||
name = "\improper OZtek Boomerang"
|
||||
desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!"
|
||||
throw_speed = 1
|
||||
throw_speed = 1.5
|
||||
icon_state = "boomerang"
|
||||
item_state = "boomerang"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_range = 5
|
||||
throw_range = 10
|
||||
hitcost = 2000
|
||||
throw_hit_chance = 99 //Have you prayed today?
|
||||
custom_materials = list(/datum/material/iron = 10000, /datum/material/glass = 4000, /datum/material/silver = 10000, /datum/material/gold = 2000)
|
||||
@@ -331,7 +331,7 @@
|
||||
if(turned_on)
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.throw_mode_off() //so they can catch it on the return.
|
||||
H.throw_mode_on() //so they can catch it on the return.
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
|
||||
@@ -531,6 +531,7 @@
|
||||
pop_burst()
|
||||
|
||||
/obj/item/toy/snappop/Crossed(H as mob|obj)
|
||||
. = ..()
|
||||
if(ishuman(H) || issilicon(H)) //i guess carp and shit shouldn't set them off
|
||||
var/mob/living/carbon/M = H
|
||||
if(issilicon(H) || M.m_intent == MOVE_INTENT_RUN)
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
new /obj/item/tank/internals/emergency_oxygen/engi(src)
|
||||
new /obj/item/analyzer(src)
|
||||
new /obj/item/holosign_creator/atmos(src)
|
||||
new /obj/item/holosign_creator/firelock(src)
|
||||
new /obj/item/holosign_creator/firelock(src) //what if atmos techs could test things they are meant to test, wild, innit?
|
||||
new /obj/item/watertank/atmos(src)
|
||||
new /obj/item/clothing/suit/fire/atmos(src)
|
||||
new /obj/item/clothing/head/hardhat/atmos(src)
|
||||
|
||||
@@ -269,13 +269,13 @@
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/structure/table/rolling/Moved(atom/OldLoc, Dir)
|
||||
. = ..()
|
||||
for(var/mob/M in OldLoc.contents)//Kidnap everyone on top
|
||||
M.forceMove(loc)
|
||||
for(var/x in attached_items)
|
||||
var/atom/movable/AM = x
|
||||
if(!AM.Move(loc))
|
||||
RemoveItemFromTable(AM, AM.loc)
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Glass tables
|
||||
|
||||
@@ -126,12 +126,13 @@
|
||||
|
||||
if(current_tube == null)
|
||||
setDir(next_dir)
|
||||
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
|
||||
Move(get_step(loc, dir), dir, DELAY_TO_GLIDE_SIZE(exit_delay)) // Allow collisions when leaving the tubes.
|
||||
break
|
||||
|
||||
last_delay = current_tube.enter_delay(src, next_dir)
|
||||
sleep(last_delay)
|
||||
setDir(next_dir)
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(last_delay + exit_delay))
|
||||
forceMove(next_loc) // When moving from one tube to another, skip collision and such.
|
||||
density = current_tube.density
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
animate(src, alpha = initial(alpha), time = time_between_triggers)
|
||||
|
||||
/obj/structure/trap/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(last_trigger + time_between_triggers > world.time)
|
||||
return
|
||||
// Don't want the traps triggered by sparks, ghosts or projectiles.
|
||||
@@ -67,6 +68,7 @@
|
||||
return
|
||||
if(M.anti_magic_check())
|
||||
flare()
|
||||
return
|
||||
if(charges <= 0)
|
||||
return
|
||||
flare()
|
||||
|
||||
+2
-1
@@ -59,7 +59,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
var/endspanpart = "</span>"
|
||||
|
||||
//Message
|
||||
var/messagepart = " <span class='message'>[say_emphasis(lang_treat(speaker, message_language, raw_message, spans, message_mode))]</span></span>"
|
||||
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans, message_mode)]</span></span>"
|
||||
|
||||
var/languageicon = ""
|
||||
var/datum/language/D = GLOB.language_datum_instances[message_language]
|
||||
@@ -116,6 +116,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
/atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode, no_quote = FALSE)
|
||||
if(has_language(language))
|
||||
var/atom/movable/AM = speaker.GetSource()
|
||||
raw_message = say_emphasis(raw_message)
|
||||
if(AM) //Basically means "if the speaker is virtual"
|
||||
return no_quote ? AM.quoteless_say_quote(raw_message, spans, message_mode) : AM.say_quote(raw_message, spans, message_mode)
|
||||
else
|
||||
|
||||
+133
-37
@@ -1,4 +1,49 @@
|
||||
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, soundenvwet = -10000, soundenvdry = 0)
|
||||
// /tg/ reverb disabled
|
||||
/*
|
||||
///Default override for echo
|
||||
/sound
|
||||
echo = list(
|
||||
0, // Direct
|
||||
0, // DirectHF
|
||||
-10000, // Room, -10000 means no low frequency sound reverb
|
||||
-10000, // RoomHF, -10000 means no high frequency sound reverb
|
||||
0, // Obstruction
|
||||
0, // ObstructionLFRatio
|
||||
0, // Occlusion
|
||||
0.25, // OcclusionLFRatio
|
||||
1.5, // OcclusionRoomRatio
|
||||
1.0, // OcclusionDirectRatio
|
||||
0, // Exclusion
|
||||
1.0, // ExclusionLFRatio
|
||||
0, // OutsideVolumeHF
|
||||
0, // DopplerFactor
|
||||
0, // RolloffFactor
|
||||
0, // RoomRolloffFactor
|
||||
1.0, // AirAbsorptionFactor
|
||||
0, // Flags (1 = Auto Direct, 2 = Auto Room, 4 = Auto RoomHF)
|
||||
)
|
||||
environment = SOUND_ENVIRONMENT_NONE //Default to none so sounds without overrides dont get reverb
|
||||
*/
|
||||
|
||||
/*! playsound
|
||||
|
||||
playsound is a proc used to play a 3D sound in a specific range. This uses SOUND_RANGE + extra_range to determine that.
|
||||
|
||||
source - Origin of sound
|
||||
soundin - Either a file, or a string that can be used to get an SFX
|
||||
vol - The volume of the sound, excluding falloff and pressure affection.
|
||||
vary - bool that determines if the sound changes pitch every time it plays
|
||||
extrarange - modifier for sound range. This gets added on top of SOUND_RANGE
|
||||
falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive.
|
||||
frequency - playback speed of audio
|
||||
channel - The channel the sound is played at
|
||||
pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space)
|
||||
ignore_walls - Whether or not the sound can pass through walls.
|
||||
falloff_distance - Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range.
|
||||
|
||||
*/
|
||||
|
||||
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff_exponent = SOUND_FALLOFF_EXPONENT, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, envwet = -10000, envdry = 0)
|
||||
if(isarea(source))
|
||||
CRASH("playsound(): source is an area")
|
||||
|
||||
@@ -10,26 +55,60 @@
|
||||
//allocate a channel if necessary now so its the same for everyone
|
||||
channel = channel || SSsounds.random_available_channel()
|
||||
|
||||
// Looping through the player list has the added bonus of working for mobs inside containers
|
||||
// Looping through the player list has the added bonus of working for mobs inside containers
|
||||
var/sound/S = sound(get_sfx(soundin))
|
||||
var/maxdistance = (world.view + extrarange)
|
||||
var/z = turf_source.z
|
||||
var/list/listeners = SSmobs.clients_by_zlevel[z]
|
||||
var/maxdistance = SOUND_RANGE + extrarange
|
||||
var/source_z = turf_source.z
|
||||
var/list/listeners = SSmobs.clients_by_zlevel[source_z].Copy()
|
||||
|
||||
var/turf/above_turf = SSmapping.get_turf_above(turf_source)
|
||||
var/turf/below_turf = SSmapping.get_turf_below(turf_source)
|
||||
|
||||
if(!ignore_walls) //these sounds don't carry through walls
|
||||
listeners = listeners & hearers(maxdistance,turf_source)
|
||||
|
||||
if(above_turf && istransparentturf(above_turf))
|
||||
listeners += hearers(maxdistance,above_turf)
|
||||
|
||||
if(below_turf && istransparentturf(turf_source))
|
||||
listeners += hearers(maxdistance,below_turf)
|
||||
|
||||
else
|
||||
if(above_turf && istransparentturf(above_turf))
|
||||
listeners += SSmobs.clients_by_zlevel[above_turf.z]
|
||||
|
||||
if(below_turf && istransparentturf(turf_source))
|
||||
listeners += SSmobs.clients_by_zlevel[below_turf.z]
|
||||
|
||||
for(var/P in listeners)
|
||||
var/mob/M = P
|
||||
if(get_dist(M, turf_source) <= maxdistance)
|
||||
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S, soundenvwet, soundenvdry)
|
||||
for(var/P in SSmobs.dead_players_by_zlevel[z])
|
||||
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, null, envwet, envdry)
|
||||
for(var/P in SSmobs.dead_players_by_zlevel[source_z])
|
||||
var/mob/M = P
|
||||
if(get_dist(M, turf_source) <= maxdistance)
|
||||
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S, soundenvwet, soundenvdry)
|
||||
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, null, envwet, envdry)
|
||||
|
||||
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S, envwet = -10000, envdry = 0, manual_x, manual_y, distance_multiplier = 1)
|
||||
if(audiovisual_redirect)
|
||||
var/turf/T = get_turf(src)
|
||||
audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S, 0, -1000, turf_source.x - T.x, turf_source.y - T.y, distance_multiplier)
|
||||
/*! playsound
|
||||
|
||||
playsound_local is a proc used to play a sound directly on a mob from a specific turf.
|
||||
This is called by playsound to send sounds to players, in which case it also gets the max_distance of that sound.
|
||||
|
||||
turf_source - Origin of sound
|
||||
soundin - Either a file, or a string that can be used to get an SFX
|
||||
vol - The volume of the sound, excluding falloff
|
||||
vary - bool that determines if the sound changes pitch every time it plays
|
||||
frequency - playback speed of audio
|
||||
falloff_exponent - Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive.
|
||||
channel - The channel the sound is played at
|
||||
pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space)
|
||||
max_distance - The peak distance of the sound, if this is a 3D sound
|
||||
falloff_distance - Distance at which falloff begins, if this is a 3D sound
|
||||
distance_multiplier - Can be used to multiply the distance at which the sound is heard
|
||||
|
||||
*/
|
||||
|
||||
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, envwet = -10000, envdry = 0)
|
||||
if(!client || !can_hear())
|
||||
return
|
||||
|
||||
@@ -39,7 +118,9 @@
|
||||
S.wait = 0 //No queue
|
||||
S.channel = channel || SSsounds.random_available_channel()
|
||||
S.volume = vol
|
||||
// CITADEL EDIT - Force citadel reverb
|
||||
S.environment = 7
|
||||
// End
|
||||
|
||||
if(vary)
|
||||
if(frequency)
|
||||
@@ -51,13 +132,13 @@
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
//sound volume falloff with distance
|
||||
var/distance = 0
|
||||
if(!manual_x && !manual_y)
|
||||
distance = get_dist(T, turf_source)
|
||||
var/distance = get_dist(T, turf_source)
|
||||
|
||||
distance *= distance_multiplier
|
||||
|
||||
S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff.
|
||||
if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff.
|
||||
S.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * S.volume
|
||||
//https://www.desmos.com/calculator/sqdfl8ipgf
|
||||
|
||||
if(pressure_affected)
|
||||
//Atmosphere affects sound
|
||||
@@ -72,42 +153,57 @@
|
||||
else //space
|
||||
pressure_factor = 0
|
||||
|
||||
S.echo = list(envdry, null, envwet, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null)
|
||||
|
||||
if(distance <= 1)
|
||||
pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound
|
||||
|
||||
S.volume *= pressure_factor
|
||||
//End Atmosphere affecting sound
|
||||
|
||||
/// Citadel edit - Citadel reverb
|
||||
S.echo = list(envdry, null, envwet, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null)
|
||||
/// End
|
||||
|
||||
if(S.volume <= 0)
|
||||
return //No sound
|
||||
|
||||
var/dx = 0 // Hearing from the right/left
|
||||
if(!manual_x)
|
||||
dx = turf_source.x - T.x
|
||||
else
|
||||
dx = manual_x
|
||||
var/dx = turf_source.x - T.x // Hearing from the right/left
|
||||
S.x = dx * distance_multiplier
|
||||
var/dz = 0 // Hearing from infront/behind
|
||||
if(!manual_x)
|
||||
dz = turf_source.y - T.y
|
||||
else
|
||||
dz = manual_y
|
||||
var/dz = turf_source.y - T.y // Hearing from infront/behind
|
||||
S.z = dz * distance_multiplier
|
||||
// The y value is for above your head, but there is no ceiling in 2d spessmens.
|
||||
S.y = 1
|
||||
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
|
||||
var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
|
||||
S.y = dy
|
||||
|
||||
S.falloff = isnull(max_distance)? FALLOFF_SOUNDS : max_distance //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.
|
||||
|
||||
/*
|
||||
/// Tg reverb removed
|
||||
if(S.environment == SOUND_ENVIRONMENT_NONE)
|
||||
if(sound_environment_override != SOUND_ENVIRONMENT_NONE)
|
||||
S.environment = sound_environment_override
|
||||
else
|
||||
var/area/A = get_area(src)
|
||||
if(A.sound_environment != SOUND_ENVIRONMENT_NONE)
|
||||
S.environment = A.sound_environment
|
||||
|
||||
if(use_reverb)
|
||||
if(S.environment == SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting
|
||||
S.environment = SOUND_ENVIRONMENT_CONCERT_HALL
|
||||
S.echo = list(0, null, -10000, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null)
|
||||
else
|
||||
S.echo[3] = 0 //Room setting, 0 means normal reverb
|
||||
S.echo[4] = 0 //RoomHF setting, 0 means normal reverb.
|
||||
*/
|
||||
///
|
||||
|
||||
SEND_SOUND(src, S)
|
||||
|
||||
/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S)
|
||||
/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S)
|
||||
if(!S)
|
||||
S = sound(get_sfx(soundin))
|
||||
for(var/m in GLOB.player_list)
|
||||
if(ismob(m) && !isnewplayer(m))
|
||||
var/mob/M = m
|
||||
M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S)
|
||||
M.playsound_local(M, null, volume, vary, frequency, null, channel, pressure_affected, S)
|
||||
|
||||
/mob/proc/stop_sound_channel(chan)
|
||||
SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
|
||||
@@ -130,14 +226,14 @@
|
||||
/proc/get_sfx(soundin)
|
||||
if(istext(soundin))
|
||||
switch(soundin)
|
||||
if ("explosion_creaking") // from skyrat-ss13/skyrat13/pull/3295
|
||||
soundin = pick('sound/effects/explosioncreak1.ogg', 'sound/effects/explosioncreak2.ogg')
|
||||
if ("hull_creaking") // from skyrat-ss13/skyrat13/pull/3295
|
||||
soundin = pick('sound/effects/creak1.ogg', 'sound/effects/creak2.ogg', 'sound/effects/creak3.ogg')
|
||||
if ("shatter")
|
||||
soundin = pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg')
|
||||
if ("explosion")
|
||||
soundin = pick('sound/effects/explosion1.ogg','sound/effects/explosion2.ogg')
|
||||
if ("explosion_creaking")
|
||||
soundin = pick('sound/effects/explosioncreak1.ogg', 'sound/effects/explosioncreak2.ogg')
|
||||
if ("hull_creaking")
|
||||
soundin = pick('sound/effects/creak1.ogg', 'sound/effects/creak2.ogg', 'sound/effects/creak3.ogg')
|
||||
if ("sparks")
|
||||
soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
|
||||
if ("rustle")
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
if(M.client && (is_servant_of_ratvar(M) || isobserver(M) || M.stat == DEAD))
|
||||
viewing += M.client
|
||||
flick_overlay(I, viewing, 8)
|
||||
L.adjustToxLoss(-3, TRUE, TRUE)
|
||||
L.adjustToxLoss(-3, TRUE, TRUE, toxins_type = TOX_OMNI)
|
||||
|
||||
/turf/open/floor/clockwork/try_replace_tile(obj/item/stack/tile/T, mob/user, params)
|
||||
return
|
||||
@@ -278,4 +278,4 @@
|
||||
heavyfootstep = FOOTSTEP_RUST
|
||||
|
||||
/turf/open/floor/plating/rust/rust_heretic_act()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -25,7 +25,13 @@
|
||||
//This is used to optimize the map loader
|
||||
return
|
||||
|
||||
/**
|
||||
* Space Initialize
|
||||
*
|
||||
* Doesn't call parent, see [/atom/proc/Initialize]
|
||||
*/
|
||||
/turf/open/space/Initialize()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
icon_state = SPACE_ICON_STATE
|
||||
air = space_gas
|
||||
update_air_ref()
|
||||
@@ -36,6 +42,15 @@
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
flags_1 |= INITIALIZED_1
|
||||
|
||||
// if (length(smoothing_groups))
|
||||
// sortTim(smoothing_groups) //In case it's not properly ordered, let's avoid duplicate entries with the same values.
|
||||
// SET_BITFLAG_LIST(smoothing_groups)
|
||||
// if (length(canSmoothWith))
|
||||
// sortTim(canSmoothWith)
|
||||
// if(canSmoothWith[length(canSmoothWith)] > MAX_S_TURF) //If the last element is higher than the maximum turf-only value, then it must scan turf contents for smoothing targets.
|
||||
// smoothing_flags |= SMOOTH_OBJ
|
||||
// SET_BITFLAG_LIST(canSmoothWith)
|
||||
|
||||
var/area/A = loc
|
||||
if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A))
|
||||
add_overlay(/obj/effect/fullbright)
|
||||
@@ -49,6 +64,13 @@
|
||||
if (opacity)
|
||||
has_opaque_atom = TRUE
|
||||
|
||||
var/turf/T = SSmapping.get_turf_above(src)
|
||||
if(T)
|
||||
T.multiz_turf_new(src, DOWN)
|
||||
T = SSmapping.get_turf_below(src)
|
||||
if(T)
|
||||
T.multiz_turf_new(src, UP)
|
||||
|
||||
ComponentInitialize()
|
||||
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
@@ -74,6 +96,10 @@
|
||||
/turf/open/space/Assimilate_Air()
|
||||
return
|
||||
|
||||
//IT SHOULD RETURN NULL YOU MONKEY, WHY IN TARNATION WHAT THE FUCKING FUCK
|
||||
/turf/open/space/remove_air(amount)
|
||||
return null
|
||||
|
||||
/turf/open/space/proc/update_starlight()
|
||||
if(CONFIG_GET(flag/starlight))
|
||||
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
|
||||
@@ -90,9 +116,8 @@
|
||||
/turf/open/space/proc/CanBuildHere()
|
||||
return TRUE
|
||||
|
||||
/turf/open/space/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
|
||||
if(lube & FLYING_DOESNT_HELP)
|
||||
return ..()
|
||||
/turf/open/space/handle_slip()
|
||||
return // no lube bullshit, this is space
|
||||
|
||||
/turf/open/space/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
@@ -107,15 +132,16 @@
|
||||
return
|
||||
if(L)
|
||||
if(R.use(1))
|
||||
qdel(L)
|
||||
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new/obj/structure/lattice/catwalk(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need two rods to build a catwalk!</span>")
|
||||
return
|
||||
if(R.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
ReplaceWithLattice()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
|
||||
@@ -126,7 +152,7 @@
|
||||
var/obj/item/stack/tile/plasteel/S = C
|
||||
if(S.use(1))
|
||||
qdel(L)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
to_chat(user, "<span class='notice'>You build a floor.</span>")
|
||||
PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
|
||||
+47
-37
@@ -1,8 +1,11 @@
|
||||
GLOBAL_LIST_EMPTY(station_turfs)
|
||||
|
||||
/// Any floor or wall. What makes up the station and the rest of the map.
|
||||
/turf
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
level = 1
|
||||
vis_flags = VIS_INHERIT_PLANE|VIS_INHERIT_ID //when this be added to vis_contents of something it inherit something.plane and be associatet with something on clicking,
|
||||
//important for visualisation of turf in openspace and interraction with openspace that show you turf.
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE // Important for interaction with and visualization of openspace.
|
||||
luminosity = 1
|
||||
|
||||
var/intact = 1
|
||||
|
||||
@@ -19,8 +22,6 @@
|
||||
|
||||
var/blocks_air = FALSE
|
||||
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes
|
||||
|
||||
var/explosion_level = 0 //for preventing explosion dodging
|
||||
@@ -41,7 +42,13 @@
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Turf Initialize
|
||||
*
|
||||
* Doesn't call parent, see [/atom/proc/Initialize]
|
||||
*/
|
||||
/turf/Initialize(mapload)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
flags_1 |= INITIALIZED_1
|
||||
@@ -49,7 +56,7 @@
|
||||
// by default, vis_contents is inherited from the turf that was here before
|
||||
vis_contents.Cut()
|
||||
|
||||
if(color)
|
||||
if(color) // is this being used? This is here because parent isn't being called
|
||||
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
assemble_baseturfs()
|
||||
@@ -57,6 +64,7 @@
|
||||
levelupdate()
|
||||
if(smooth)
|
||||
queue_smooth(src)
|
||||
|
||||
visibilityChanged()
|
||||
|
||||
for(var/atom/movable/AM in src)
|
||||
@@ -76,11 +84,10 @@
|
||||
var/turf/T = SSmapping.get_turf_above(src)
|
||||
if(T)
|
||||
T.multiz_turf_new(src, DOWN)
|
||||
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN)
|
||||
T = SSmapping.get_turf_below(src)
|
||||
if(T)
|
||||
T.multiz_turf_new(src, UP)
|
||||
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP)
|
||||
|
||||
|
||||
if (opacity)
|
||||
has_opaque_atom = TRUE
|
||||
@@ -112,8 +119,6 @@
|
||||
var/turf/B = new world.turf(src)
|
||||
for(var/A in B.contents)
|
||||
qdel(A)
|
||||
for(var/I in B.vars)
|
||||
B.vars[I] = null
|
||||
return
|
||||
SSair.remove_from_active(src)
|
||||
visibilityChanged()
|
||||
@@ -122,12 +127,14 @@
|
||||
requires_activation = FALSE
|
||||
..()
|
||||
|
||||
/turf/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/turf/on_attack_hand(mob/user)
|
||||
user.Move_Pulled(src)
|
||||
|
||||
/turf/proc/multiz_turf_del(turf/T, dir)
|
||||
// SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_DEL, T, dir)
|
||||
|
||||
/turf/proc/multiz_turf_new(turf/T, dir)
|
||||
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_NEW, T, dir)
|
||||
|
||||
//zPassIn doesn't necessarily pass an atom!
|
||||
//direction is direction of travel of air
|
||||
@@ -158,13 +165,14 @@
|
||||
prev_turf.visible_message("<span class='danger'>[mov_name] falls through [prev_turf]!</span>")
|
||||
if(flags & FALL_INTERCEPTED)
|
||||
return
|
||||
if(zFall(A, ++levels))
|
||||
if(zFall(A, levels + 1))
|
||||
return FALSE
|
||||
A.visible_message("<span class='danger'>[A] crashes into [src]!</span>")
|
||||
A.onZImpact(src, levels)
|
||||
return TRUE
|
||||
|
||||
/turf/proc/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return zPassOut(A, DOWN, target) && target.zPassIn(A, DOWN, src)
|
||||
|
||||
/turf/proc/zFall(atom/movable/A, levels = 1, force = FALSE)
|
||||
@@ -217,49 +225,54 @@
|
||||
stack_trace("Non movable passed to turf CanPass : [mover]")
|
||||
return FALSE
|
||||
|
||||
//There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanPass/Cross call, lemme know or go ahead and fix this mess - kevinz000
|
||||
/turf/Enter(atom/movable/mover, atom/oldloc)
|
||||
// Do not call ..()
|
||||
// Byond's default turf/Enter() doesn't have the behaviour we want with Bump()
|
||||
// By default byond will call Bump() on the first dense object in contents
|
||||
// Here's hoping it doesn't stay like this for years before we finish conversion to step_
|
||||
var/atom/firstbump
|
||||
if(!CanPass(mover, src))
|
||||
firstbump = src
|
||||
else
|
||||
var/canPassSelf = CanPass(mover, src)
|
||||
if(canPassSelf || (mover.movement_type & UNSTOPPABLE))
|
||||
for(var/i in contents)
|
||||
if(QDELETED(mover))
|
||||
return FALSE //We were deleted, do not attempt to proceed with movement.
|
||||
if(i == mover || i == mover.loc) // Multi tile objects and moving out of other objects
|
||||
continue
|
||||
if(QDELETED(mover))
|
||||
break
|
||||
var/atom/movable/thing = i
|
||||
if(!thing.Cross(mover))
|
||||
if(CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE))
|
||||
if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed.
|
||||
return FALSE
|
||||
if((mover.movement_type & UNSTOPPABLE))
|
||||
mover.Bump(thing)
|
||||
continue
|
||||
else
|
||||
if(!firstbump || ((thing.layer > firstbump.layer || thing.flags_1 & ON_BORDER_1) && !(firstbump.flags_1 & ON_BORDER_1)))
|
||||
firstbump = thing
|
||||
if(QDELETED(mover)) //Mover deleted from Cross/CanPass/Bump, do not proceed.
|
||||
return FALSE
|
||||
if(!canPassSelf) //Even if mover is unstoppable they need to bump us.
|
||||
firstbump = src
|
||||
if(firstbump)
|
||||
if(!QDELETED(mover))
|
||||
mover.Bump(firstbump)
|
||||
return CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)
|
||||
mover.Bump(firstbump)
|
||||
return (mover.movement_type & UNSTOPPABLE)
|
||||
return TRUE
|
||||
|
||||
/turf/Exit(atom/movable/mover, atom/newloc)
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(!. || QDELETED(mover))
|
||||
return FALSE
|
||||
for(var/i in contents)
|
||||
if(QDELETED(mover))
|
||||
break
|
||||
if(i == mover)
|
||||
continue
|
||||
var/atom/movable/thing = i
|
||||
if(!thing.Uncross(mover, newloc))
|
||||
if(thing.flags_1 & ON_BORDER_1)
|
||||
mover.Bump(thing)
|
||||
if(!CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE))
|
||||
if(!(mover.movement_type & UNSTOPPABLE))
|
||||
return FALSE
|
||||
if(QDELETED(mover))
|
||||
return FALSE //We were deleted.
|
||||
|
||||
/turf/Entered(atom/movable/AM)
|
||||
..()
|
||||
@@ -271,6 +284,7 @@
|
||||
has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case.
|
||||
reconsider_lights()
|
||||
|
||||
|
||||
/turf/open/Entered(atom/movable/AM)
|
||||
..()
|
||||
//melting
|
||||
@@ -278,7 +292,6 @@
|
||||
var/obj/O = AM
|
||||
if(O.obj_flags & FROZEN)
|
||||
O.make_unfrozen()
|
||||
|
||||
if(!AM.zfalling)
|
||||
zFall(AM)
|
||||
|
||||
@@ -336,14 +349,13 @@
|
||||
|
||||
/turf/proc/levelupdate()
|
||||
for(var/obj/O in src)
|
||||
if(O.level == 1 && (O.flags_1 & INITIALIZED_1))
|
||||
O.hide(src.intact)
|
||||
if(O.flags_1 & INITIALIZED_1)
|
||||
// SEND_SIGNAL(O, COMSIG_OBJ_HIDE, intact)
|
||||
O.hide(intact)
|
||||
|
||||
// override for space turfs, since they should never hide anything
|
||||
/turf/open/space/levelupdate()
|
||||
for(var/obj/O in src)
|
||||
if(O.level == 1 && (O.flags_1 & INITIALIZED_1))
|
||||
O.hide(0)
|
||||
return
|
||||
|
||||
// Removes all signs of lattice on the pos of the turf -Donkieyo
|
||||
/turf/proc/RemoveLattice()
|
||||
@@ -368,13 +380,13 @@
|
||||
if(.)
|
||||
return
|
||||
if(length(src_object.contents()))
|
||||
to_chat(user, "<span class='notice'>You start dumping out the contents...</span>")
|
||||
if(!do_after(user,20,target=src_object.parent))
|
||||
to_chat(usr, "<span class='notice'>You start dumping out the contents...</span>")
|
||||
if(!do_after(usr,20,target=src_object.parent))
|
||||
return FALSE
|
||||
|
||||
var/list/things = src_object.contents()
|
||||
var/datum/progressbar/progress = new(user, things.len, src)
|
||||
while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress)))
|
||||
while (do_after(usr, 1 SECONDS, TRUE, src, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress)))
|
||||
stoplag(1)
|
||||
qdel(progress)
|
||||
|
||||
@@ -494,10 +506,8 @@
|
||||
I.loc = src
|
||||
I.setDir(AM.dir)
|
||||
I.alpha = 128
|
||||
|
||||
LAZYADD(blueprint_data, I)
|
||||
|
||||
|
||||
/turf/proc/add_blueprints_preround(atom/movable/AM)
|
||||
if(!SSticker.HasRoundStarted())
|
||||
add_blueprints(AM)
|
||||
@@ -531,7 +541,7 @@
|
||||
if(!forced)
|
||||
return
|
||||
if(has_gravity(src))
|
||||
playsound(src, "bodyfall", 50, 1)
|
||||
playsound(src, "bodyfall", 50, TRUE)
|
||||
faller.drop_all_held_items()
|
||||
|
||||
/turf/proc/photograph(limit=20)
|
||||
|
||||
+95
-47
@@ -1,21 +1,46 @@
|
||||
#define RESTART_COUNTER_PATH "data/round_counter.txt"
|
||||
|
||||
GLOBAL_VAR(restart_counter)
|
||||
|
||||
GLOBAL_VAR_INIT(tgs_initialized, FALSE)
|
||||
|
||||
GLOBAL_VAR(topic_status_lastcache)
|
||||
GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
//This happens after the Master subsystem new(s) (it's a global datum)
|
||||
//So subsystems globals exist, but are not initialised
|
||||
/**
|
||||
* World creation
|
||||
*
|
||||
* Here is where a round itself is actually begun and setup.
|
||||
* * db connection setup
|
||||
* * config loaded from files
|
||||
* * loads admins
|
||||
* * Sets up the dynamic menu system
|
||||
* * and most importantly, calls initialize on the master subsystem, starting the game loop that causes the rest of the game to begin processing and setting up
|
||||
*
|
||||
*
|
||||
* Nothing happens until something moves. ~Albert Einstein
|
||||
*
|
||||
* For clarity, this proc gets triggered later in the initialization pipeline, it is not the first thing to happen, as it might seem.
|
||||
*
|
||||
* Initialization Pipeline:
|
||||
* Global vars are new()'ed, (including config, glob, and the master controller will also new and preinit all subsystems when it gets new()ed)
|
||||
* Compiled in maps are loaded (mainly centcom). all areas/turfs/objs/mobs(ATOMs) in these maps will be new()ed
|
||||
* world/New() (You are here)
|
||||
* Once world/New() returns, client's can connect.
|
||||
* 1 second sleep
|
||||
* Master Controller initialization.
|
||||
* Subsystem initialization.
|
||||
* Non-compiled-in maps are maploaded, all atoms are new()ed
|
||||
* All atoms in both compiled and uncompiled maps are initialized()
|
||||
*/
|
||||
/world/New()
|
||||
if (fexists(EXTOOLS))
|
||||
call(EXTOOLS, "maptick_initialize")()
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
call(EXTOOLS, "init_logging")()
|
||||
else
|
||||
CRASH("[EXTOOLS] does not exist!")
|
||||
#endif
|
||||
#endif
|
||||
enable_debugger()
|
||||
#ifdef REFERENCE_TRACKING
|
||||
enable_reference_tracking()
|
||||
@@ -23,12 +48,11 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
world.Profile(PROFILE_START)
|
||||
|
||||
log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!")
|
||||
|
||||
GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl
|
||||
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!")
|
||||
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
|
||||
GLOB.revdata = new
|
||||
|
||||
@@ -36,6 +60,9 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
config.Load(params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER])
|
||||
|
||||
load_admins()
|
||||
load_mentors()
|
||||
|
||||
//SetupLogs depends on the RoundID, so lets check
|
||||
//DB schema and set RoundID if we can
|
||||
SSdbcore.CheckSchemaVersion()
|
||||
@@ -49,14 +76,9 @@ GLOBAL_LIST(topic_status_cache)
|
||||
world.log = file("[GLOB.log_directory]/dd.log") //not all runtimes trigger world/Error, so this is the only way to ensure we can see all of them.
|
||||
#endif
|
||||
|
||||
load_admins()
|
||||
load_mentors()
|
||||
LoadVerbs(/datum/verbs/menu)
|
||||
if(CONFIG_GET(flag/usewhitelist))
|
||||
load_whitelist()
|
||||
LoadBans()
|
||||
initialize_global_loadout_items()
|
||||
reload_custom_roundstart_items_list()//Cit change - loads donator items. Remind me to remove when I port over bay's loadout system
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
@@ -67,10 +89,15 @@ GLOBAL_LIST(topic_status_cache)
|
||||
if(NO_INIT_PARAMETER in params)
|
||||
return
|
||||
|
||||
LoadBans()
|
||||
initialize_global_loadout_items()
|
||||
reload_custom_roundstart_items_list()//Cit change - loads donator items. Remind me to remove when I port over bay's loadout system
|
||||
|
||||
Master.Initialize(10, FALSE, TRUE)
|
||||
|
||||
if(TEST_RUN_PARAMETER in params)
|
||||
HandleTestRun()
|
||||
#ifdef UNIT_TESTS
|
||||
HandleTestRun()
|
||||
#endif
|
||||
|
||||
/world/proc/InitTgs()
|
||||
TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED)
|
||||
@@ -88,7 +115,7 @@ GLOBAL_LIST(topic_status_cache)
|
||||
#else
|
||||
cb = VARSET_CALLBACK(SSticker, force_ending, TRUE)
|
||||
#endif
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, cb, 10 SECONDS))
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/_addtimer, cb, 10 SECONDS))
|
||||
|
||||
/world/proc/SetupLogs()
|
||||
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
|
||||
@@ -136,7 +163,7 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
GLOB.test_log = file("[GLOB.log_directory]/tests.log")
|
||||
GLOB.test_log = "[GLOB.log_directory]/tests.log"
|
||||
start_log(GLOB.test_log)
|
||||
#endif
|
||||
start_log(GLOB.world_game_log)
|
||||
@@ -170,14 +197,6 @@ GLOBAL_LIST(topic_status_cache)
|
||||
/world/Topic(T, addr, master, key)
|
||||
TGS_TOPIC //redirect to server tools if necessary
|
||||
|
||||
if(!SSfail2topic)
|
||||
return "Server not initialized."
|
||||
else if(SSfail2topic.IsRateLimited(addr))
|
||||
return "Rate limited."
|
||||
|
||||
if(length(T) > CONFIG_GET(number/topic_max_size))
|
||||
return "Payload too large!"
|
||||
|
||||
var/static/list/topic_handlers = TopicHandlers()
|
||||
|
||||
var/list/input = params2list(T)
|
||||
@@ -243,9 +262,10 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
TgsReboot()
|
||||
|
||||
if(TEST_RUN_PARAMETER in params)
|
||||
FinishTestRun()
|
||||
return
|
||||
#ifdef UNIT_TESTS
|
||||
FinishTestRun()
|
||||
return
|
||||
#endif
|
||||
|
||||
if(TgsAvailable())
|
||||
var/do_hard_reboot
|
||||
@@ -280,11 +300,11 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
var/list/features = list()
|
||||
|
||||
/*if(GLOB.master_mode) CIT CHANGE - hides the gamemode from the hub entry, removes some useless info from the hub entry
|
||||
features += GLOB.master_mode
|
||||
// if(GLOB.master_mode)
|
||||
// features += GLOB.master_mode
|
||||
|
||||
if (!GLOB.enter_allowed)
|
||||
features += "closed"*/
|
||||
// if (!GLOB.enter_allowed)
|
||||
// features += "closed"
|
||||
|
||||
var/s = ""
|
||||
var/hostedby
|
||||
@@ -292,25 +312,22 @@ GLOBAL_LIST(topic_status_cache)
|
||||
var/server_name = CONFIG_GET(string/servername)
|
||||
if (server_name)
|
||||
s += "<b>[server_name]</b> — "
|
||||
/*features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn" CIT CHANGE - removes some useless info from the hub entry
|
||||
if(CONFIG_GET(flag/allow_vote_mode))
|
||||
features += "vote"
|
||||
if(CONFIG_GET(flag/allow_ai))
|
||||
features += "AI allowed"*/
|
||||
// features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn"
|
||||
// if(CONFIG_GET(flag/allow_vote_mode))
|
||||
// features += "vote"
|
||||
// if(CONFIG_GET(flag/allow_ai))
|
||||
// features += "AI allowed"
|
||||
hostedby = CONFIG_GET(string/hostedby)
|
||||
|
||||
s += "<b>[station_name()]</b>";
|
||||
s += " ("
|
||||
s += "<a href=\"https://citadel-station.net/home/\">" //Change this to wherever you want the hub to link to. CIT CHANGE - links to cit's website on the hub
|
||||
s += "Citadel" //Replace this with something else. Or ever better, delete it and uncomment the game version. CIT CHANGE - modifies the hub entry link
|
||||
s += "<a href=\"https://citadel-station.net/home\">" //Change this to wherever you want the hub to link to.
|
||||
s += "Citadel" //Replace this with something else. Or ever better, delete it and uncomment the game version.
|
||||
s += "</a>"
|
||||
s += ")\]" //CIT CHANGE - encloses the server title in brackets to make the hub entry fancier
|
||||
s += "<br>[CONFIG_GET(string/servertagline)]<br>" //CIT CHANGE - adds a tagline!
|
||||
|
||||
var/n = 0
|
||||
for (var/mob/M in GLOB.player_list)
|
||||
if (M.client)
|
||||
n++
|
||||
var/players = GLOB.clients.len
|
||||
|
||||
if(SSmapping.config) // this just stops the runtime, honk.
|
||||
features += "[SSmapping.config.map_name]" //CIT CHANGE - makes the hub entry display the current map
|
||||
@@ -318,16 +335,23 @@ GLOBAL_LIST(topic_status_cache)
|
||||
if(NUM2SECLEVEL(GLOB.security_level))//CIT CHANGE - makes the hub entry show the security level
|
||||
features += "[NUM2SECLEVEL(GLOB.security_level)] alert"
|
||||
|
||||
if (n > 1)
|
||||
features += "~[n] players"
|
||||
else if (n > 0)
|
||||
features += "~[n] player"
|
||||
var/popcaptext = ""
|
||||
var/popcap = max(CONFIG_GET(number/extreme_popcap), CONFIG_GET(number/hard_popcap), CONFIG_GET(number/soft_popcap))
|
||||
if (popcap)
|
||||
popcaptext = "/[popcap]"
|
||||
|
||||
if (players > 1)
|
||||
features += "[players][popcaptext] players"
|
||||
else if (players > 0)
|
||||
features += "[players][popcaptext] player"
|
||||
|
||||
game_state = (CONFIG_GET(number/extreme_popcap) && players >= CONFIG_GET(number/extreme_popcap)) //tells the hub if we are full
|
||||
|
||||
if (!host && hostedby)
|
||||
features += "hosted by <b>[hostedby]</b>"
|
||||
|
||||
if (features)
|
||||
s += "\[[jointext(features, ", ")]" //CIT CHANGE - replaces the colon here with a left bracket
|
||||
s += "\[[jointext(features, ", ")]"
|
||||
|
||||
status = s
|
||||
|
||||
@@ -346,4 +370,28 @@ GLOBAL_LIST(topic_status_cache)
|
||||
SSidlenpcpool.MaxZChanged()
|
||||
world.refresh_atmos_grid()
|
||||
|
||||
/// Extools atmos
|
||||
/world/proc/refresh_atmos_grid()
|
||||
|
||||
/world/proc/change_fps(new_value = 20)
|
||||
if(new_value <= 0)
|
||||
CRASH("change_fps() called with [new_value] new_value.")
|
||||
if(fps == new_value)
|
||||
return //No change required.
|
||||
|
||||
fps = new_value
|
||||
on_tickrate_change()
|
||||
|
||||
|
||||
/world/proc/change_tick_lag(new_value = 0.5)
|
||||
if(new_value <= 0)
|
||||
CRASH("change_tick_lag() called with [new_value] new_value.")
|
||||
if(tick_lag == new_value)
|
||||
return //No change required.
|
||||
|
||||
tick_lag = new_value
|
||||
on_tickrate_change()
|
||||
|
||||
|
||||
/world/proc/on_tickrate_change()
|
||||
SStimer?.reset_buckets()
|
||||
|
||||
Reference in New Issue
Block a user