more merge conflict fixes

This commit is contained in:
Seris02
2020-01-24 10:14:31 +08:00
315 changed files with 15287 additions and 11002 deletions
@@ -266,7 +266,7 @@
/turf/open/indestructible/boss,
/area/ruin/unpowered/ash_walkers)
"aH" = (
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker,
/obj/structure/lavaland/ash_walker,
/turf/open/lava/smooth{
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
+3 -3
View File
@@ -3675,7 +3675,7 @@
/area/awaymission/snowdin/cave/cavern)
"im" = (
/obj/effect/decal/cleanable/blood/old,
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 5
},
/turf/open/floor/engine/cult{
@@ -8278,7 +8278,7 @@
/turf/open/floor/engine/cult,
/area/awaymission/snowdin/post/cavern2)
"sb" = (
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 4;
name = "weak netherworld link"
},
@@ -10179,7 +10179,7 @@
/obj/structure/cable/yellow{
icon_state = "2-8"
},
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 4;
name = "weak netherworld link"
},
+8 -8
View File
@@ -103,7 +103,7 @@
},
/area/awaymission/caves/BMP_asteroid/level_four)
"at" = (
/mob/living/simple_animal/hostile/spawner/skeleton,
/obj/structure/spawner/skeleton,
/turf/open/floor/plating/asteroid/basalt/lava{
initial_gas_mix = "n2=23;o2=14"
},
@@ -164,7 +164,7 @@
},
/area/awaymission/caves/BMP_asteroid/level_four)
"aB" = (
/mob/living/simple_animal/hostile/spawner/skeleton,
/obj/structure/spawner/skeleton,
/turf/open/floor/engine/cult{
initial_gas_mix = "n2=23;o2=14"
},
@@ -374,7 +374,7 @@
},
/area/awaymission/caves/BMP_asteroid/level_three)
"be" = (
/mob/living/simple_animal/hostile/spawner/mining/goliath,
/obj/structure/spawner/mining/goliath,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
@@ -504,7 +504,7 @@
/area/awaymission/caves/BMP_asteroid/level_three)
"bw" = (
/obj/effect/decal/cleanable/blood,
/mob/living/simple_animal/hostile/spawner/skeleton,
/obj/structure/spawner/skeleton,
/turf/open/floor/engine/cult{
initial_gas_mix = "n2=23;o2=14"
},
@@ -930,7 +930,7 @@
/turf/closed/wall,
/area/awaymission/caves/BMP_asteroid/level_two)
"cL" = (
/mob/living/simple_animal/hostile/spawner/mining/basilisk,
/obj/structure/spawner/mining/basilisk,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
@@ -1644,7 +1644,7 @@
/turf/open/floor/plasteel,
/area/awaymission/caves/listeningpost)
"fb" = (
/mob/living/simple_animal/hostile/spawner/mining/hivelord,
/obj/structure/spawner/mining/hivelord,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
@@ -2133,7 +2133,7 @@
/turf/open/floor/plasteel/recharge_floor,
/area/awaymission/caves/BMP_asteroid)
"gD" = (
/mob/living/simple_animal/hostile/spawner/mining/hivelord,
/obj/structure/spawner/mining/hivelord,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
@@ -2206,7 +2206,7 @@
},
/area/awaymission/caves/BMP_asteroid)
"gQ" = (
/mob/living/simple_animal/hostile/spawner/mining/basilisk,
/obj/structure/spawner/mining/basilisk,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
+3 -3
View File
@@ -3670,7 +3670,7 @@
/area/awaymission/snowdin/cave/cavern)
"im" = (
/obj/effect/decal/cleanable/blood/old,
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 5
},
/turf/open/floor/engine/cult{
@@ -8333,7 +8333,7 @@
/turf/open/floor/engine/cult,
/area/awaymission/snowdin/post/cavern2)
"sb" = (
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 4;
name = "weak netherworld link"
},
@@ -10243,7 +10243,7 @@
/obj/structure/cable/yellow{
icon_state = "2-8"
},
/mob/living/simple_animal/hostile/spawner/nether{
/obj/structure/spawner/nether{
max_mobs = 4;
name = "weak netherworld link"
},
+2 -6
View File
@@ -53620,10 +53620,6 @@
},
/turf/open/floor/plasteel,
/area/engine/gravity_generator)
"eZP" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/space/basic,
/area/hallway/secondary/entry)
"fbm" = (
/obj/structure/chair/comfy/brown{
dir = 4
@@ -67472,9 +67468,9 @@ aaa
aaa
aaa
aaf
eZP
awW
auP
eZP
awW
aaf
vZs
aaa
+2 -1
View File
@@ -47211,6 +47211,7 @@
dir = 4
},
/obj/item/storage/box/lights/mixed,
/obj/structure/closet/firecloset,
/turf/open/floor/plating{
icon_state = "platingdmg2"
},
@@ -96215,7 +96216,7 @@ bMA
alK
bPD
asa
pHS
alK
aaa
aaa
aaf
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+12
View File
@@ -254,6 +254,18 @@
#define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build.
//HELPERS
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
if(T.dir & NORTH || T.dir & SOUTH) { \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
} \
if(T.dir & WEST || T.dir & EAST) { \
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;\
}
#define PIPING_LAYER_DOUBLE_SHIFT(T, PipingLayer) \
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
+1
View File
@@ -110,6 +110,7 @@
#define HIDENECK (1<<10)
#define HIDETAUR (1<<11) //gotta hide that snowflake
#define HIDESNOUT (1<<12) //or do we actually hide our snoots
#define HIDEACCESSORY (1<<13) //hides the jumpsuit accessory.
//bitflags for clothing coverage - also used for limbs
#define HEAD (1<<0)
-24
View File
@@ -25,30 +25,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define NOT_IMPLEMENTED "NOT_IMPLEMENTED"
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
#define JANUARY 1
#define FEBRUARY 2
#define MARCH 3
#define APRIL 4
#define MAY 5
#define JUNE 6
#define JULY 7
#define AUGUST 8
#define SEPTEMBER 9
#define OCTOBER 10
#define NOVEMBER 11
#define DECEMBER 12
//Select holiday names -- If you test for a holiday in the code, make the holiday's name a define and test for that instead
#define NEW_YEAR "New Year"
#define VALENTINES "Valentine's Day"
#define APRIL_FOOLS "April Fool's Day"
#define EASTER "Easter"
#define HALLOWEEN "Halloween"
#define CHRISTMAS "Christmas"
#define FESTIVE_SEASON "Festive Season"
//Human Overlays Indexes/////////
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
#define MUTATIONS_LAYER 32 //mutations. Tk headglows, cold resistance glow, etc
+20
View File
@@ -0,0 +1,20 @@
//Defaults
#define MOVE_FORCE_DEFAULT 1000
#define MOVE_RESIST_DEFAULT 1000
#define PULL_FORCE_DEFAULT 1000
//Factors/modifiers
#define MOVE_FORCE_PULL_RATIO 1 //Same move force to pull objects
#define MOVE_FORCE_PUSH_RATIO 1 //Same move force to normally push
#define MOVE_FORCE_FORCEPUSH_RATIO 2 //2x move force to forcefully push
#define MOVE_FORCE_CRUSH_RATIO 3 //3x move force to do things like crush objects
#define MOVE_FORCE_THROW_RATIO 1 //Same force throw as resist to throw objects
#define MOVE_FORCE_OVERPOWERING (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 10)
#define MOVE_FORCE_EXTREMELY_STRONG (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 3)
#define MOVE_FORCE_VERY_STRONG ((MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO) - 1)
#define MOVE_FORCE_STRONG (MOVE_FORCE_DEFAULT * 2)
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2)
#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1)
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
+24
View File
@@ -1,3 +1,27 @@
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
#define JANUARY 1
#define FEBRUARY 2
#define MARCH 3
#define APRIL 4
#define MAY 5
#define JUNE 6
#define JULY 7
#define AUGUST 8
#define SEPTEMBER 9
#define OCTOBER 10
#define NOVEMBER 11
#define DECEMBER 12
//Select holiday names -- If you test for a holiday in the code, make the holiday's name a define and test for that instead
#define NEW_YEAR "New Year"
#define VALENTINES "Valentine's Day"
#define APRIL_FOOLS "April Fool's Day"
#define EASTER "Easter"
#define HALLOWEEN "Halloween"
#define CHRISTMAS "Christmas"
#define FESTIVE_SEASON "Festive Season"
/*
Days of the week to make it easier to reference them.
+2
View File
@@ -175,6 +175,7 @@
#define TRAIT_FREESPRINT "free_sprinting"
#define TRAIT_XRAY_VISION "xray_vision"
#define TRAIT_THERMAL_VISION "thermal_vision"
#define TRAIT_NO_TELEPORT "no-teleport" //you just can't
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
// common trait sources
@@ -236,4 +237,5 @@
#define NUKEOP_ANTAGONIST "nukeop-antagonist"
#define MADE_UNCLONEABLE "made-uncloneable"
#define NUKEOP_TRAIT "nuke-op"
#define MEGAFAUNA_TRAIT "megafauna"
#define DEATHSQUAD_TRAIT "deathsquad"
+1 -1
View File
@@ -178,7 +178,7 @@
if(!C.credits)
C.RollCredits()
C.playtitlemusic(40)
CONFIG_SET(flag/suicide_allowed,TRUE) // EORG suicides allowed
var/popcount = gather_roundend_feedback()
display_report(popcount)
+1 -1
View File
@@ -1276,7 +1276,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
invisibility = 101
density = FALSE
see_in_dark = 1e6
anchored = TRUE
move_resist = INFINITY
var/ready_to_die = FALSE
/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists
@@ -408,3 +408,5 @@
/datum/config_entry/number/dropped_modes
config_entry_value = 3
/datum/config_entry/flag/suicide_allowed
+1
View File
@@ -55,6 +55,7 @@ SUBSYSTEM_DEF(throwing)
var/dist_y
var/dx
var/dy
var/force = MOVE_FORCE_DEFAULT
var/pure_diagonal
var/diagonal_error
var/datum/callback/callback
+3
View File
@@ -544,6 +544,9 @@
cooldown = world.time
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
/datum/action/item_action/flash
name = "Flash"
//Preset for spells
/datum/action/spell_action
check_flags = 0
+49
View File
@@ -0,0 +1,49 @@
/datum/component/spawner
var/mob_types = list(/mob/living/simple_animal/hostile/carp)
var/spawn_time = 300 //30 seconds default
var/list/spawned_mobs = list()
var/spawn_delay = 0
var/max_mobs = 5
var/spawn_text = "emerges from"
var/list/faction = list("mining")
/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs)
if(_spawn_time)
spawn_time=_spawn_time
if(_mob_types)
mob_types=_mob_types
if(_faction)
faction=_faction
if(_spawn_text)
spawn_text=_spawn_text
if(_max_mobs)
max_mobs=_max_mobs
RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), .proc/stop_spawning)
START_PROCESSING(SSprocessing, src)
/datum/component/spawner/process()
try_spawn_mob()
/datum/component/spawner/proc/stop_spawning(force, hint)
STOP_PROCESSING(SSprocessing, src)
for(var/mob/living/simple_animal/L in spawned_mobs)
if(L.nest == src)
L.nest = null
spawned_mobs = null
/datum/component/spawner/proc/try_spawn_mob()
var/atom/P = parent
if(spawned_mobs.len >= max_mobs)
return 0
if(spawn_delay > world.time)
return 0
spawn_delay = world.time + spawn_time
var/chosen_mob_type = pick(mob_types)
var/mob/living/simple_animal/L = new chosen_mob_type(P.loc)
L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1)
spawned_mobs += L
L.nest = src
L.faction = src.faction
P.visible_message("<span class='danger'>[L] [spawn_text] [P].</span>")
@@ -0,0 +1,26 @@
/datum/element/dusts_on_catatonia
element_flags = ELEMENT_DETACH
var/list/mob/attached_mobs = list()
/datum/element/dusts_on_catatonia/Attach(datum/target,penalize = FALSE)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
var/mob/M = target
if(!(M in attached_mobs))
attached_mobs += M
START_PROCESSING(SSprocessing,src)
/datum/element/dusts_on_catatonia/Detach(mob/M)
. = ..()
if(M in attached_mobs)
attached_mobs -= M
if(!attached_mobs.len)
STOP_PROCESSING(SSprocessing,src)
/datum/element/dusts_on_catatonia/process()
for(var/m in attached_mobs)
var/mob/M = m
if(!M.key && !M.get_ghost())
M.dust(force = TRUE)
Detach(M)
@@ -22,6 +22,8 @@
if(!(M.ckey in timeouts))
timeouts += M.ckey
timeouts[M.ckey] = 0
else if(timeouts[M.ckey] == CANT_REENTER_ROUND)
return
timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
/datum/element/ghost_role_eligibility/Detach(mob/M)
+1 -1
View File
@@ -66,7 +66,7 @@
var/area/A = get_area(curturf)
var/area/B = get_area(destturf)
if(!forced && (A.noteleport || B.noteleport))
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || A.noteleport || B.noteleport))
return FALSE
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf))
+1 -1
View File
@@ -26,7 +26,7 @@
if(A.grab_state >= GRAB_AGGRESSIVE)
D.grabbedby(A, 1)
else
A.start_pulling(D, 1)
A.start_pulling(D, supress_message = TRUE)
if(A.pulling)
D.drop_all_held_items()
D.stop_pulling()
+1 -1
View File
@@ -132,7 +132,7 @@
//CIT CHANGE - makes arousal update when transfering bodies
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
var/mob/living/L = new_character
if(L.client && L.client.prefs & L.client.prefs.auto_ooc & L.client.prefs.chat_toggles & CHAT_OOC)
if(L.client?.prefs && L.client.prefs.auto_ooc && L.client.prefs.chat_toggles & CHAT_OOC)
DISABLE_BITFIELD(L.client.prefs.chat_toggles,CHAT_OOC)
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
+7
View File
@@ -34,3 +34,10 @@
id = "engine_tesla"
suffix = "Box/Engine/engine_tesla.dmm"
name = "Box Tesla"
// Lavaland
// Mining Base
/datum/map_template/ruin/station/lavaland/mining_base
id = "mining_public_01"
suffix = "Lavaland/Mining_Station/Mining_Station_Public_01.dmm"
name = "Public Mining Base"
+1 -1
View File
@@ -615,7 +615,7 @@
if(do_after(mob_viewer, 35, null, mob_viewer))
if(isliving(mob_viewer))
var/mob/living/L = mob_viewer
to_chat(mob_viewer, "<span class='notice'>You succesfuly remove the durathread strand.</span>")
to_chat(mob_viewer, "<span class='notice'>You successfully remove the durathread strand.</span>")
L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
+1 -1
View File
@@ -360,7 +360,7 @@
SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume)
return
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...).
addtimer(CALLBACK(src, .proc/hitby_react, AM), 2)
+38 -14
View File
@@ -3,6 +3,9 @@
var/last_move = null
var/last_move_time = 0
var/anchored = FALSE
var/move_resist = MOVE_RESIST_DEFAULT
var/move_force = MOVE_FORCE_DEFAULT
var/pull_force = PULL_FORCE_DEFAULT
var/datum/thrownthing/throwing = null
var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported
var/throw_range = 7
@@ -115,20 +118,20 @@
return FALSE
return ..()
/atom/movable/proc/start_pulling(atom/movable/AM,gs)
/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
if(QDELETED(AM))
return FALSE
if(!(AM.can_be_pulled(src)))
if(!(AM.can_be_pulled(src, state, force)))
return FALSE
// If we're pulling something then drop what we're currently pulling and pull this instead.
if(pulling)
if(gs==0)
if(state == 0)
stop_pulling()
return FALSE
// Are we trying to pull something we are already pulling? Then enter grab cycle and end.
if(AM == pulling)
grab_state = gs
grab_state = state
if(istype(AM,/mob/living))
var/mob/living/AMob = AM
AMob.grabbedby(src)
@@ -139,11 +142,12 @@
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
grab_state = gs
grab_state = state
if(ismob(AM))
var/mob/M = AM
log_combat(src, M, "grabbed", addition="passive grab")
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
if(!supress_message)
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
return TRUE
/atom/movable/proc/stop_pulling()
@@ -508,17 +512,19 @@
/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
set waitfor = 0
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
return hit_atom.hitby(src)
return hit_atom.hitby(src, throwingdatum=throwingdatum)
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked)
if(!anchored && 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, var/datum/callback/callback, messy_throw = TRUE)
return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, messy_throw)
/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)
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)
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) //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 = INFINITY, messy_throw = TRUE) //If this returns FALSE then callback will not be called.
. = FALSE
if (!target || speed <= 0)
return
@@ -564,6 +570,7 @@
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
@@ -614,6 +621,22 @@
return 0
return 1
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
/atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE)
. = AM.force_pushed(src, force, direction)
if(!silent && .)
visible_message("<span class='warning'>[src] forcefully pushes against [AM]!</span>", "<span class='warning'>You forcefully push against [AM]!</span>")
/atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE)
. = AM.move_crushed(src, force, direction)
if(!silent && .)
visible_message("<span class='danger'>[src] crushes past [AM]!</span>", "<span class='danger'>You crush [AM]!</span>")
/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
/atom/movable/CanPass(atom/movable/mover, turf/target)
if(mover in buckled_mobs)
return 1
@@ -833,14 +856,15 @@
/atom/movable/proc/get_cell()
return
/atom/movable/proc/can_be_pulled(user)
/atom/movable/proc/can_be_pulled(user, grab_state, force)
if(src == user || !isturf(loc))
return FALSE
if(anchored || throwing)
return FALSE
if(force < (move_resist * MOVE_FORCE_PULL_RATIO))
return FALSE
return TRUE
/obj/item/proc/do_pickup_animation(atom/target)
set waitfor = FALSE
if(!istype(loc, /turf))
@@ -145,9 +145,9 @@
C.throw_mode_on() //so they can catch it on the return.
return ..()
/obj/item/shield/energy/bananium/throw_impact(atom/hit_atom)
/obj/item/shield/energy/bananium/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(active)
var/caught = hit_atom.hitby(src, 0, 0)
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
if(iscarbon(hit_atom) && !caught)//if they are a carbon and they didn't catch it
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(hit_atom)
+7 -1
View File
@@ -220,6 +220,12 @@
T -= M.rating*0.2
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
/obj/machinery/autolathe/examine(mob/user)
. += ..()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[prod_coeff*100]%</b>.</span>"
/obj/machinery/autolathe/proc/main_win(mob/user)
var/dat = "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
dat += materials_printout()
@@ -380,4 +386,4 @@
//Called when the object is constructed by an autolathe
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A)
return
return
+2
View File
@@ -28,6 +28,8 @@
. += "There's [charging ? "a" : "no"] cell in the charger."
if(charging)
. += "Current charge: [round(charging.percent(), 1)]%."
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Charge rate at <b>[charge_rate]J</b> per cycle.</span>"
/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stock_parts/cell) && !panel_open)
+5
View File
@@ -104,8 +104,13 @@
/obj/machinery/clonepod/examine(mob/user)
. = ..()
var/mob/living/mob_occupant = occupant
. += "<span class='notice'>The <i>linking</i> device can be <i>scanned<i> with a multitool.</span>"
if(mess)
. += "It's filled with blood and viscera. You swear you can see it moving..."
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Cloning speed at <b>[speed_coeff*50]%</b>.<br>Predicted amount of cellular damage: <b>[100-heal_level]%</b>.</span>"
if(efficiency > 5)
to_chat(user, "<span class='notice'>Pod has been upgraded to support autoprocessing.<span>")
if(is_operational() && mob_occupant)
if(mob_occupant.stat != DEAD)
. += "Current clone cycle is [round(get_completion())]% complete."
+3 -3
View File
@@ -44,7 +44,7 @@
data += "Current target: [(!target) ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"]<BR>"
if(calibrating)
data += "Calibration: <font color='yellow'>In Progress</font>"
else if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
else if(power_station.teleporter_hub.calibrated || power_station.efficiency >= 3)
data += "Calibration: <font color='green'>Optimal</font>"
else
data += "Calibration: <font color='red'>Sub-Optimal</font>"
@@ -84,14 +84,14 @@
if(!target)
say("Error: No target set to calibrate to.")
return
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
if(power_station.teleporter_hub.calibrated || power_station.efficiency >= 3)
say("Hub is already calibrated!")
return
say("Processing hub calibration to target...")
calibrating = 1
power_station.update_icon()
spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
spawn(50 * (3 - power_station.efficiency)) //Better parts mean faster calibration
calibrating = 0
if(check_hub_connection())
power_station.teleporter_hub.calibrated = 1
+3 -3
View File
@@ -181,6 +181,9 @@
if(component_check)
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc)
if(new_machine.circuit)
QDEL_NULL(new_machine.circuit)
new_machine.circuit = circuit
new_machine.setAnchored(anchored)
new_machine.on_construction()
for(var/obj/O in new_machine.component_parts)
@@ -189,9 +192,6 @@
for(var/obj/O in src)
O.moveToNullspace()
new_machine.component_parts += O
if(new_machine.circuit)
QDEL_NULL(new_machine.circuit)
new_machine.circuit = circuit
circuit.moveToNullspace()
new_machine.RefreshParts()
qdel(src)
+7
View File
@@ -27,6 +27,13 @@
for(var/obj/item/stock_parts/micro_laser/P in component_parts)
damage_coeff = P.rating
/obj/machinery/dna_scannernew/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Radiation pulse accuracy increased by factor <b>[precision_coeff**2]</b>.<br>Radiation pulse damage decreased by factor <b>[damage_coeff**2]</b>.</span>"
if(scan_level >= 3)
. += "<span class='notice'>Scanner has been upgraded to support autoprocessing.<span>"
/obj/machinery/dna_scannernew/update_icon()
//no power or maintenance
+1
View File
@@ -5,6 +5,7 @@
icon_state = "door1"
opacity = 1
density = TRUE
move_resist = MOVE_FORCE_VERY_STRONG
layer = OPEN_DOOR_LAYER
power_channel = ENVIRON
max_integrity = 350
+1 -1
View File
@@ -32,7 +32,7 @@
CalculateAffectingAreas()
/obj/machinery/door/firedoor/examine(mob/user)
..()
. = ..()
if(!density)
. += "<span class='notice'>It is open, but could be <b>pried</b> closed.</span>"
else if(!welded)
+4 -2
View File
@@ -129,7 +129,7 @@
/obj/machinery/harvester/proc/end_harvesting()
harvesting = FALSE
open_machine()
say("Subject has been succesfuly harvested.")
say("Subject has been successfully harvested.")
playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, 0)
/obj/machinery/harvester/screwdriver_act(mob/living/user, obj/item/I)
@@ -191,4 +191,6 @@
if(state_open)
. += "<span class='notice'>[src] must be closed before harvesting.</span>"
else if(!harvesting)
. += "<span class='notice'>Alt-click [src] to start harvesting.</span>"
. += "<span class='notice'>Alt-click [src] to start harvesting.</span>"
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Harvest speed at <b>[interval*0.1]</b> seconds per organ.<span>"
+5
View File
@@ -143,6 +143,11 @@ GLOBAL_LIST_EMPTY(network_holopads)
holograph_range += 1 * B.rating
holo_range = holograph_range
/obj/machinery/holopad/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Current projection range: <b>[holo_range]</b> units.</span>"
/obj/machinery/holopad/attackby(obj/item/P, mob/user, params)
if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P))
return
+5
View File
@@ -23,6 +23,11 @@
E += M.rating*15
range = E
/obj/machinery/launchpad/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Maximum range: <b>[range]</b> units.</span>"
/obj/machinery/launchpad/attackby(obj/item/I, mob/user, params)
if(stationary)
if(default_deconstruction_screwdriver(user, "lpad-idle-o", "lpad-idle", I))
+6 -1
View File
@@ -144,7 +144,7 @@
// Set this limb up using the specias name and body zone
limb.icon_state = "[selected_category]_[limb.body_zone]"
limb.name = "\improper synthetic [selected_category] [parse_zone(limb.body_zone)]"
limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]"
limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]."
limb.species_id = selected_category
limb.update_icon_dropped()
@@ -158,6 +158,11 @@
T -= M.rating*0.2
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
/obj/machinery/limbgrower/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[reagents.maximum_volume]u</b> of synthflesh.<br>Synthflesh consumption at <b>[prod_coeff*100]%</b>.<span>"
/obj/machinery/limbgrower/proc/main_win(mob/user)
var/dat = "<div class='statusDisplay'><h3>Limb Grower Menu:</h3><br>"
dat += "<A href='?src=[REF(src)];menu=[LIMBGROWER_CHEMICAL_MENU]'>Chemical Storage</A>"
+2 -4
View File
@@ -75,8 +75,7 @@ Buildable meters
new_layer = PIPING_LAYER_DEFAULT
piping_layer = new_layer
pixel_x += (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
pixel_y += (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
PIPING_LAYER_SHIFT(src, piping_layer)
layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
/obj/item/pipe/proc/update()
@@ -232,5 +231,4 @@ Buildable meters
/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
piping_layer = new_layer
pixel_x = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
PIPING_LAYER_DOUBLE_SHIFT(src, piping_layer)
+17
View File
@@ -23,6 +23,23 @@
for(var/obj/item/stock_parts/capacitor/C in component_parts)
recharge_coeff = C.rating
/obj/machinery/recharger/examine(mob/user)
. = ..()
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
. += "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>"
return
if(charging)
. += {"<span class='notice'>\The [src] contains:</span>
<span class='notice'>- \A [charging].</span>"}
if(!(stat & (NOPOWER|BROKEN)))
. += "<span class='notice'>The status display reads:</span>"
. += "<span class='notice'>- Recharging <b>[recharge_coeff*10]%</b> cell charge per cycle.</span>"
if(charging)
var/obj/item/stock_parts/cell/C = charging.get_cell()
. += "<span class='notice'>- \The [charging]'s cell is at <b>[C.percent()]%</b>.</span>"
/obj/machinery/recharger/proc/setCharging(new_charging)
charging = new_charging
if (new_charging)
+7
View File
@@ -50,6 +50,13 @@
for(var/obj/item/stock_parts/cell/C in component_parts)
recharge_speed *= C.maxcharge / 10000
/obj/machinery/recharge_station/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Recharging <b>[recharge_speed]J</b> per cycle.</span>"
if(repairs)
to_chat(user, "<span class='notice'>[src] has been upgraded to support automatic repairs.<span>")
/obj/machinery/recharge_station/process()
if(!is_operational())
return
+4 -3
View File
@@ -41,9 +41,10 @@
/obj/machinery/recycler/examine(mob/user)
. = ..()
. += "The power light is [(stat & NOPOWER) ? "off" : "on"]."
. += "The safety-mode light is [safety_mode ? "on" : "off"]."
. += "The safety-sensors status light is [obj_flags & EMAGGED ? "off" : "on"]."
. += "<span class='notice'>Reclaiming <b>[amount_produced]%</b> of materials salvaged.</span>"
. += {"The power light is [(stat & NOPOWER) ? "off" : "on"].
The safety-mode light is [safety_mode ? "on" : "off"].
The safety-sensors status light is [obj_flags & EMAGGED ? "off" : "on"]."}
/obj/machinery/recycler/power_change()
..()
+3
View File
@@ -4,6 +4,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "shield-old"
density = TRUE
move_resist = INFINITY
opacity = 0
anchored = TRUE
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
@@ -93,6 +94,7 @@
/obj/machinery/shieldgen/proc/shields_up()
active = TRUE
update_icon()
move_resist = INFINITY
for(var/turf/target_tile in range(shield_range, src))
if(isspaceturf(target_tile) && !(locate(/obj/structure/emergency_shield) in target_tile))
@@ -101,6 +103,7 @@
/obj/machinery/shieldgen/proc/shields_down()
active = FALSE
move_resist = initial(move_resist)
update_icon()
QDEL_LIST(deployed_shields)
+2
View File
@@ -52,6 +52,8 @@
. += "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%."
else
. += "There is no power cell installed."
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Temperature range at <b>[settableTemperatureRange]°C</b>.<br>Heating power at <b>[heatingPower*0.001]kJ</b>.<br>Power consumption at <b>[(efficiency*-0.0025)+150]%</b>.<span>" //100%, 75%, 50%, 25%
/obj/machinery/space_heater/update_icon()
if(on)
+19 -5
View File
@@ -11,7 +11,7 @@
idle_power_usage = 10
active_power_usage = 2000
circuit = /obj/item/circuitboard/machine/teleporter_hub
var/accurate = FALSE
var/accuracy = 0
var/obj/machinery/teleport/station/power_station
var/calibrated //Calibration prevents mutation
@@ -29,7 +29,12 @@
var/A = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
A += M.rating
accurate = A
accuracy = A
/obj/machinery/teleport/hub/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Probability of malfunction decreased by <b>[(accuracy*25)-25]%</b>.</span>"
/obj/machinery/teleport/hub/proc/link_power_station()
if(power_station)
@@ -69,13 +74,13 @@
if(do_teleport(M, com.target, channel = TELEPORT_CHANNEL_BLUESPACE))
use_power(5000)
if(!calibrated && iscarbon(M) && prob(30 - ((accurate) * 10))) //oh dear a problem
if(!calibrated && iscarbon(M) && prob(30 - ((accuracy) * 10))) //oh dear a problem
var/mob/living/carbon/C = M
if(C.dna?.species && C.dna.species.id != "fly" && !HAS_TRAIT(C, TRAIT_RADIMMUNE))
to_chat(C, "<span class='italics'>You hear a buzzing in your ears.</span>")
C.set_species(/datum/species/fly)
log_game("[C] ([key_name(C)]) was turned into a fly person")
C.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), EFFECT_IRRADIATE, 0)
C.apply_effect((rand(120 - accuracy * 40, 180 - accuracy * 60)), EFFECT_IRRADIATE, 0)
calibrated = FALSE
return
@@ -102,7 +107,7 @@
/obj/machinery/teleport/station
name = "station"
name = "teleporter station"
desc = "The power control station for a bluespace teleporter. Used for toggling power, and can activate a test-fire to prevent malfunctions."
icon_state = "controller"
use_power = IDLE_POWER_USE
@@ -125,6 +130,15 @@
E += C.rating
efficiency = E - 1
/obj/machinery/teleport/station/examine(mob/user)
. = ..()
if(!panel_open)
. += "<span class='notice'>The panel is <i>screwed</i> in, obstructing the linking device and wiring panel.</span>"
else
. += "<span class='notice'>The <i>linking</i> device is now able to be <i>scanned</i> with a multitool.<br>The <i>wiring</i> can be <i>connected<i> to a nearby console and hub with a pair of wirecutters.</span>"
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: This station can be linked to <b>[efficiency]</b> other station(s).</span>"
/obj/machinery/teleport/station/proc/link_console_and_hub()
for(var/direction in GLOB.cardinals)
teleporter_hub = locate(/obj/machinery/teleport/hub, get_step(src, direction))
@@ -84,7 +84,7 @@
switch(mode)
if(1)
if(!locked)
if(!istype(target) || target.anchored)
if(!istype(target) || target.anchored || target.move_resist >= MOVE_FORCE_EXTREMELY_STRONG)
occupant_message("Unable to lock on [target]")
return
locked = target
@@ -110,7 +110,7 @@
else
atoms = orange(3, target)
for(var/atom/movable/A in atoms)
if(A.anchored)
if(A.anchored || A.move_resist >= MOVE_FORCE_EXTREMELY_STRONG)
continue
spawn(0)
var/iter = 5-get_dist(A,target)
+1 -1
View File
@@ -436,7 +436,7 @@
throwforce = 35
icon_state = "punching_glove"
/obj/item/punching_glove/throw_impact(atom/hit_atom)
/obj/item/punching_glove/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
if(ismovableatom(hit_atom))
var/atom/movable/AM = hit_atom
+5
View File
@@ -36,6 +36,11 @@
MC += C.rating
max_charge = MC * 25
/obj/machinery/mech_bay_recharge_port/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Base recharge rate at <b>[max_charge]J</b> per cycle.</span>"
/obj/machinery/mech_bay_recharge_port/process()
if(stat & NOPOWER || !recharge_console)
return
+5
View File
@@ -62,6 +62,11 @@
T += Ml.rating
time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
/obj/machinery/mecha_part_fabricator/examine(mob/user)
. = ..()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[component_coeff*100]%</b>.<br>Build time reduced by <b>[100-time_coeff*100]%</b>.</span>"
/obj/machinery/mecha_part_fabricator/emag_act()
. = ..()
+2 -2
View File
@@ -108,8 +108,8 @@
/obj/mecha/attack_tk()
return
/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
log_message("Hit by [A].", color="red")
/obj/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper
log_message("Hit by [AM].", color="red")
. = ..()
+1
View File
@@ -4,6 +4,7 @@
/obj/effect
icon = 'icons/effects/effects.dmi'
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
move_resist = INFINITY
obj_flags = 0
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
+5
View File
@@ -481,3 +481,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
/obj/effect/landmark/stationroom/box/engine/New()
. = ..()
templates = CONFIG_GET(keyed_list/box_random_engine)
// Landmark for the mining station
/obj/effect/landmark/stationroom/lavaland/station
templates = list("Public Mining Base" = 3)
icon = 'icons/rooms/Lavaland/Mining.dmi'
@@ -39,4 +39,8 @@
/obj/effect/projectile/impact/laser/wavemotion
name = "particle impact"
icon_state = "impact_wavemotion"
icon_state = "impact_wavemotion"
/obj/effect/projectile/impact/laser/emitter
name = "emitter impact"
icon_state = "impact_emitter"
@@ -31,4 +31,8 @@
/obj/effect/projectile/muzzle/laser/wavemotion
name = "particle backblast"
icon_state = "muzzle_wavemotion"
icon_state = "muzzle_wavemotion"
/obj/effect/projectile/muzzle/laser/emitter
name = "emitter flash"
icon_state = "muzzle_emitter"
@@ -70,3 +70,7 @@
/obj/effect/projectile/tracer/laser/wavemotion
name = "particle trail"
icon_state = "tracer_wavemotion"
/obj/effect/projectile/tracer/laser/emitter
name = "emitter beam"
icon_state = "emitter"
+9 -9
View File
@@ -568,21 +568,21 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
else
return
/obj/item/throw_impact(atom/A, datum/thrownthing/throwingdatum)
if(A && !QDELETED(A))
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, A, throwingdatum)
if(get_temperature() && isliving(A))
var/mob/living/L = A
/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(hit_atom && !QDELETED(hit_atom))
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
if(get_temperature() && isliving(hit_atom))
var/mob/living/L = hit_atom
L.IgniteMob()
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
return A.hitby(src, 0, itempush)
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, messy_throw = TRUE)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
thrownby = thrower
callback = CALLBACK(src, .proc/after_throw, callback, (spin && messy_throw)) //replace their callback with our own
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
. = ..(target, range, speed, thrower, spin, diagonals_first, callback, force)
/obj/item/proc/after_throw(datum/callback/callback, messy_throw)
if (callback) //call the original callback
@@ -674,7 +674,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
else
. = ""
/obj/item/hitby(atom/movable/AM)
/obj/item/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return
/obj/item/attack_hulk(mob/living/carbon/human/user)
+10 -5
View File
@@ -329,7 +329,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit))
var/turf/T = get_turf(A)
if(!user.IsAdvancedToolUser() || !T || istype(T, /turf/open/space/transit) || isindestructiblewall(T))
return ..()
//So that changing the menu settings doesn't affect the pipes already being built.
@@ -376,12 +377,16 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
if(ATMOS_CATEGORY) //Making pipes
if(!can_make_pipe)
return ..()
A = T
if(is_type_in_typecache(recipe, GLOB.ventcrawl_machinery) && isclosedturf(A)) //wall escapism sanity check.
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if (recipe.type == /datum/pipe_info/meter)
to_chat(user, "<span class='notice'>You start building a meter...</span>")
if(do_after(user, atmos_build_speed, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A)
PM.setAttachLayer(piping_layer)
if(mode&WRENCH_MODE)
PM.wrench_act(user, src)
@@ -391,7 +396,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
activate()
var/obj/machinery/atmospherics/path = queued_p_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), queued_p_type, queued_p_dir)
var/obj/item/pipe/P = new pipe_item_type(A, queued_p_type, queued_p_dir)
if(queued_p_flipped && istype(P, /obj/item/pipe/trinary/flippable))
var/obj/item/pipe/trinary/flippable/F = P
@@ -408,7 +413,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
if(DISPOSALS_CATEGORY) //Making disposals pipes
if(!can_make_pipe)
return ..()
A = get_turf(A)
A = T
if(isclosedturf(A))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
@@ -433,7 +438,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
if(TRANSIT_CATEGORY) //Making transit tubes
if(!can_make_pipe)
return ..()
A = get_turf(A)
A = T
if(isclosedturf(A))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
@@ -308,6 +308,7 @@
/obj/item/circuitboard/machine/thermomachine
name = "Thermomachine (Machine Board)"
desc = "You can use a screwdriver to switch between heater and freezer."
var/pipe_layer = PIPING_LAYER_DEFAULT
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/micro_laser = 2,
@@ -342,8 +343,18 @@
build_path = initial(new_type.build_path)
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>You change the circuitboard setting to \"[new_setting]\".</span>")
else
return ..()
return
if(I.tool_behaviour == TOOL_MULTITOOL)
pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
to_chat(user, "<span class='notice'>You change the circuitboard to layer [pipe_layer].</span>")
return
. = ..()
/obj/item/circuitboard/machine/thermomachine/examine()
. = ..()
. += "<span class='notice'>It is set to layer [pipe_layer].</span>"
/obj/item/circuitboard/machine/thermomachine/heater
name = "Heater (Machine Board)"
+46 -11
View File
@@ -93,6 +93,8 @@ GLOBAL_LIST_EMPTY(PDAs)
var/underline_flag = TRUE //flag for underline
var/list/blocked_pdas
/obj/item/pda/suicide_act(mob/living/carbon/user)
var/deathMessage = msg_input(user)
if (!deathMessage)
@@ -387,7 +389,10 @@ GLOBAL_LIST_EMPTY(PDAs)
for (var/obj/item/pda/P in sortNames(get_viewable_pdas()))
if (P == src)
continue
dat += "<li><a href='byond://?src=[REF(src)];choice=Message;target=[REF(P)]'>[P]</a>"
if(P.owner in blocked_pdas)
dat += "<li><a href='byond://?src=[REF(src)];choice=unblock_pda;target=[P.owner]'>(BLOCKED - CLICK TO UNBLOCK) [P]</a>"
else
dat += "<li><a href='byond://?src=[REF(src)];choice=Message;target=[REF(P)]'>[P]</a>"
if(cartridge)
dat += cartridge.message_special(P)
dat += "</li>"
@@ -646,6 +651,15 @@ GLOBAL_LIST_EMPTY(PDAs)
if("MessageAll")
send_to_all(U)
if("toggle_block")
toggle_blocking(usr, href_list["target"])
if("block_pda")
block_pda(usr, href_list["target"])
if("unblock_pda")
unblock_pda(usr, href_list["target"])
if("cart")
if(cartridge)
cartridge.special(U, href_list)
@@ -744,9 +758,16 @@ GLOBAL_LIST_EMPTY(PDAs)
message += "\nSent from my PDA"
// Send the signal
var/list/string_targets = list()
for (var/obj/item/pda/P in targets)
if (P.owner && P.ownjob) // != src is checked by the UI
var/list/string_blocked
for(var/obj/item/pda/P in targets)
if(owner in P.blocked_pdas)
LAZYADD(string_blocked, P.owner)
continue
if(P.owner && P.ownjob) // != src is checked by the UI
string_targets += "[P.owner] ([P.ownjob])"
if(string_blocked)
string_blocked = english_list(string_blocked)
to_chat(user, "<span class='warning'>[icon2html(src, user)] The following recipients have blocked your message: [string_blocked].</span>")
for (var/obj/machinery/computer/message_monitor/M in targets)
// In case of "Reply" to a message from a console, this will make the
// message be logged successfully. If the console is impersonating
@@ -779,12 +800,13 @@ GLOBAL_LIST_EMPTY(PDAs)
tnote += "<i><b>&rarr; To [target_text]:</b></i><br>[signal.format_message()]<br>"
// Show it to ghosts
var/ghost_message = "<span class='name'>[owner] </span><span class='game say'>PDA Message</span> --> <span class='name'>[target_text]</span>: <span class='message'>[signal.format_message(TRUE)]</span>"
for(var/mob/M in GLOB.player_list)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
for(var/i in GLOB.dead_mob_list)
var/mob/M = i
if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA)
to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]")
// Log in the talk log
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text]")
to_chat(user, "<span class='info'>Message sent to [target_text]: \"[emoji_message]\"</span>")
// Log in the talk log
user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])")
if (!silent)
playsound(src, 'sound/machines/terminal_success.ogg', 15, 1)
// Reset the photo
@@ -794,8 +816,7 @@ GLOBAL_LIST_EMPTY(PDAs)
last_everyone = world.time
/obj/item/pda/proc/receive_message(datum/signal/subspace/pda/signal)
tnote += "<i><b>&larr; From <a href='byond://?src=[REF(src)];choice=Message;target=[REF(signal.source)]'>[signal.data["name"]]</a> ([signal.data["job"]]):</b></i><br>[signal.format_message()]<br>"
tnote += "<i><b>&larr; From <a href='byond://?src=[REF(src)];choice=Message;target=[REF(signal.source)]'>[signal.data["name"]]</a> ([signal.data["job"]]):</b></i> <a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>(BLOCK/UNBLOCK)</a><br>[signal.format_message()]<br>"
if (!silent)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3)
@@ -814,7 +835,7 @@ GLOBAL_LIST_EMPTY(PDAs)
hrefstart = "<a href='?src=[REF(L)];track=[html_encode(signal.data["name"])]'>"
hrefend = "</a>"
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message(TRUE)] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>)")
to_chat(L, "[icon2html(src)] <b>Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], </b>[signal.format_message(TRUE)] (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(signal.source)]'>Reply</a>) <a href='byond://?src=[REF(src)];choice=toggle_block;target=[signal.data["name"]]'>(BLOCK/UNBLOCK)</a>")
update_icon(TRUE)
@@ -827,6 +848,20 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda/proc/create_message(mob/living/U, obj/item/pda/P)
send_message(U,list(P))
/obj/item/pda/proc/toggle_blocking(mob/user, target)
if(target in blocked_pdas)
unblock_pda(user, target)
else
block_pda(user, target)
/obj/item/pda/proc/block_pda(mob/user, target)
to_chat(user, "<span class='notice'>[icon2html(src, user)] [target] blocked from messages. Use the messenger PDA list to unblock.</span>")
LAZYOR(blocked_pdas, target)
/obj/item/pda/proc/unblock_pda(mob/user, target)
to_chat(user, "<span class='notice'>[icon2html(src, user)] [target] unblocked from messages.</span>")
LAZYREMOVE(blocked_pdas, target)
/obj/item/pda/AltClick(mob/user)
. = ..()
if(id)
@@ -1172,4 +1207,4 @@ GLOBAL_LIST_EMPTY(PDAs)
#undef PDA_OVERLAY_ID
#undef PDA_OVERLAY_ITEM
#undef PDA_OVERLAY_LIGHT
#undef PDA_OVERLAY_PAI
#undef PDA_OVERLAY_PAI
@@ -1,6 +1,6 @@
/obj/item/forcefield_projector
name = "forcefield projector"
desc = "An experimental device that can create several forcefields at a distance."
desc = "An experimental device that can create several forcefields at a short distance."
icon = 'icons/obj/device.dmi'
icon_state = "signmaker_forcefield"
slot_flags = ITEM_SLOT_BELT
@@ -14,7 +14,7 @@
var/shield_integrity = 250
var/max_fields = 3
var/list/current_fields
var/field_distance_limit = 7
var/field_distance_limit = 2
/obj/item/forcefield_projector/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
@@ -56,6 +56,14 @@
else
return ..()
/obj/item/laser_pointer/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
if(!diode)
. += "<span class='notice'>The diode is missing.<span>"
else
. += "<span class='notice'>A class <b>[diode.rating]</b> laser diode is installed. It is <i>screwed</i> in place.<span>"
/obj/item/laser_pointer/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
laser_act(target, user, params)
+1 -1
View File
@@ -160,7 +160,7 @@
/obj/item/dice/attack_self(mob/user)
diceroll(user)
/obj/item/dice/throw_impact(atom/target)
/obj/item/dice/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
diceroll(thrownby)
. = ..()
+2 -3
View File
@@ -93,9 +93,8 @@
var/obj/item/I = loc
I.grenade_prime_react(src)
/obj/item/grenade/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
/obj/item/grenade/tool_act(mob/living/user, obj/item/I, tool_behaviour)
if(tool_behaviour == TOOL_SCREWDRIVER)
switch(det_time)
if ("1")
det_time = 10
+2 -2
View File
@@ -340,7 +340,7 @@
return
playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, 1)
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
return//abort
var/mob/living/carbon/C = hit_atom
@@ -368,7 +368,7 @@
w_class = WEIGHT_CLASS_SMALL
breakouttime = 60
/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscarbon(hit_atom))
var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom))
B.Crossed(hit_atom)
+4 -4
View File
@@ -333,13 +333,13 @@
if(proximity_flag)
consume_everything(target)
/obj/item/melee/supermatter_sword/throw_impact(target)
/obj/item/melee/supermatter_sword/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if(ismob(target))
var/mob/M
if(ismob(hit_atom))
var/mob/M = hit_atom
if(src.loc == M)
M.dropItemToGround(src)
consume_everything(target)
consume_everything(hit_atom)
/obj/item/melee/supermatter_sword/pickup(user)
..()
+3 -3
View File
@@ -105,10 +105,10 @@
playsound(src.loc, "sparks", 50, 1)
shock(M)
/obj/item/twohanded/mjollnir/throw_impact(atom/target)
/obj/item/twohanded/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(isliving(target))
shock(target)
if(isliving(hit_atom))
shock(hit_atom)
/obj/item/twohanded/mjollnir/update_icon() //Currently only here to fuck with the on-mob icons.
icon_state = "mjollnir[wielded]"
+1 -1
View File
@@ -35,7 +35,7 @@
/obj/item/stack/ore/bluespace_crystal/proc/blink_mob(mob/living/L)
do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom)
/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) // not caught in mid-air
visible_message("<span class='notice'>[src] fizzles and disappears upon impact!</span>")
var/turf/T = get_turf(hit_atom)
+24 -1
View File
@@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
grind_results = list(/datum/reagent/silicon = 20)
point_value = 1
tableVariant = /obj/structure/table/glass
shard_type = /obj/item/shard
/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -93,6 +94,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
merge_type = /obj/item/stack/sheet/plasmaglass
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10)
tableVariant = /obj/structure/table/plasmaglass
shard_type = /obj/item/shard/plasma
/obj/item/stack/sheet/plasmaglass/fifty
amount = 50
@@ -120,7 +122,9 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
else
return ..()
/obj/item/stack/sheet/plasmaglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 1.2
S.efficiency *= 1.2
/*
* Reinforced glass sheets
@@ -145,11 +149,15 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
merge_type = /obj/item/stack/sheet/rglass
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10)
point_value = 4
shard_type = /obj/item/shard
/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
..()
/obj/item/stack/sheet/rglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
/obj/item/stack/sheet/rglass/cyborg
materials = list()
var/datum/robot_energy_storage/glasource
@@ -188,6 +196,11 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \
merge_type = /obj/item/stack/sheet/plasmarglass
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10)
point_value = 23
shard_type = /obj/item/shard/plasma
/obj/item/stack/sheet/plasmarglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.2
S.efficiency *= 1.2
/obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.prglass_recipes
@@ -207,6 +220,11 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list(
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/titaniumglass
shard_type = /obj/item/shard
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.5
S.efficiency *= 1.5
/obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.titaniumglass_recipes
@@ -226,11 +244,16 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/plastitaniumglass
shard_type = /obj/item/shard
/obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plastitaniumglass_recipes
return ..()
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
S.efficiency *= 2
/obj/item/shard
name = "shard"
desc = "A nasty looking shard of glass."
@@ -15,4 +15,15 @@
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity
var/is_fabric = FALSE //is this a valid material for the loom?
var/loom_result //result from pulling on the loom
var/pull_effort = 0 //amount of delay when pulling on the loom
var/pull_effort = 0 //amount of delay when pulling on the loom
var/shard_type // the shard debris typepath left over by solar panels and windows etc.
/**
* Called on the glass sheet upon solar construction (duh):
* Different glass sheets can modify different stas/vars, such as obj_integrity or efficiency
* and possibly extra effects if you wish to code them.
* Keep in mind the solars' max_integrity is set equal to the obj_integrity later,
* so you won't have to do so here.
*/
/obj/item/stack/sheet/proc/on_solar_construction(/obj/machinery/power/solar/S)
return
+1 -1
View File
@@ -342,7 +342,7 @@
merge(o)
. = ..()
/obj/item/stack/hitby(atom/movable/AM, skip, hitpush)
/obj/item/stack/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(istype(AM, merge_type))
merge(AM)
. = ..()
+1 -1
View File
@@ -41,7 +41,7 @@
cell = new preload_cell_type(src)
update_icon()
/obj/item/melee/baton/throw_impact(atom/hit_atom)
/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
//Only mob/living types have stun handling
if(status && prob(throw_hit_chance) && iscarbon(hit_atom))
+1 -1
View File
@@ -259,7 +259,7 @@
if(proximity && ismovableatom(O) && O != sliver)
Consume(O, user)
/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins
/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) // no instakill supermatter javelins
if(sliver)
sliver.forceMove(loc)
to_chat(usr, "<span class='notice'>\The [sliver] falls out of \the [src] as you throw them.</span>")
+4 -4
View File
@@ -84,7 +84,7 @@
else
return ..()
/obj/item/toy/balloon/throw_impact(atom/hit_atom)
/obj/item/toy/balloon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
balloon_burst(hit_atom)
@@ -531,7 +531,7 @@
/obj/item/toy/snappop/fire_act(exposed_temperature, exposed_volume)
pop_burst()
/obj/item/toy/snappop/throw_impact(atom/hit_atom)
/obj/item/toy/snappop/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
pop_burst()
@@ -1152,7 +1152,7 @@
icon_state = "minimeteor"
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/minimeteor/throw_impact(atom/hit_atom)
/obj/item/toy/minimeteor/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1)
for(var/mob/M in urange(10, src))
@@ -1201,7 +1201,7 @@
if(user.dropItemToGround(src))
throw_at(target, throw_range, throw_speed)
/obj/item/toy/snowball/throw_impact(atom/hit_atom)
/obj/item/toy/snowball/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
playsound(src, 'sound/effects/pop.ogg', 20, 1)
qdel(src)
+12 -1
View File
@@ -46,7 +46,7 @@
if(BURN)
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/hitby(atom/movable/AM)
/obj/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
..()
var/throwdamage = AM.throwforce
if(isobj(AM))
@@ -126,6 +126,17 @@
if(. && !play_soundeffect)
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
/obj/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return TRUE
/obj/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
collision_damage(pusher, force, direction)
return TRUE
/obj/proc/collision_damage(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10)
take_damage(amt, BRUTE)
/obj/attack_slime(mob/living/simple_animal/slime/user)
if(!user.is_adult)
return
+1 -1
View File
@@ -80,7 +80,7 @@
SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue)
anchored = anchorvalue
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw)
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
. = ..()
if(obj_flags & FROZEN)
visible_message("<span class='danger'>[src] shatters into a million pieces!</span>")
@@ -46,6 +46,7 @@
roundstart = FALSE
death = FALSE
anchored = FALSE
move_resist = MOVE_FORCE_NORMAL
density = FALSE
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest.</b>"
@@ -120,6 +121,7 @@
roundstart = FALSE
death = FALSE
anchored = FALSE
move_resist = MOVE_FORCE_NORMAL
density = FALSE
var/has_owner = FALSE
var/can_transfer = TRUE //if golems can switch bodies to this new shell
@@ -645,6 +647,7 @@
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT)
+1 -1
View File
@@ -258,7 +258,7 @@
take_damage(1, BURN, 0, 0)
..()
/obj/structure/grille/hitby(AM as mob|obj)
/obj/structure/grille/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(isobj(AM))
if(prob(50) && anchored && !broken)
var/obj/O = AM
@@ -1,39 +1,32 @@
//Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed
/obj/effect/light_emitter/tendril
set_luminosity = 4
set_cap = 2.5
light_color = LIGHT_COLOR_LAVA
/mob/living/simple_animal/hostile/spawner/lavaland
/obj/structure/spawner/lavaland
name = "necropolis tendril"
desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it."
icon = 'icons/mob/nest.dmi'
icon_state = "tendril"
icon_living = "tendril"
icon_dead = "tendril"
faction = list("mining")
weather_immunities = list("lava","ash")
health = 250
maxHealth = 250
max_mobs = 3
spawn_time = 300 //30 seconds default
max_integrity = 250
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
spawn_text = "emerges from"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = INFINITY
loot = list(/obj/effect/collapse, /obj/structure/closet/crate/necropolis/tendril)
del_on_death = 1
move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it
anchored = TRUE
resistance_flags = FIRE_PROOF | LAVA_PROOF
var/gps = null
var/obj/effect/light_emitter/tendril/emitted_light
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
/obj/structure/spawner/lavaland/goliath
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/legion
/obj/structure/spawner/lavaland/legion
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/Initialize()
GLOBAL_LIST_INIT(tendrils, list())
/obj/structure/spawner/lavaland/Initialize()
. = ..()
emitted_light = new(loc)
for(var/F in RANGE_TURFS(1, src))
@@ -41,18 +34,19 @@
var/turf/closed/mineral/M = F
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
gps = new /obj/item/gps/internal(src)
GLOB.tendrils += src
/mob/living/simple_animal/hostile/spawner/lavaland/Destroy()
QDEL_NULL(emitted_light)
QDEL_NULL(gps)
/obj/structure/spawner/lavaland/deconstruct(disassembled)
new /obj/effect/collapse(loc)
new /obj/structure/closet/crate/necropolis/tendril(loc)
return ..()
/mob/living/simple_animal/hostile/spawner/lavaland/death()
/obj/structure/spawner/lavaland/Destroy()
var/last_tendril = TRUE
for(var/mob/living/simple_animal/hostile/spawner/lavaland/other in GLOB.mob_living_list)
if(other != src)
last_tendril = FALSE
break
if(GLOB.tendrils.len>1)
last_tendril = FALSE
if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1))
if(SSmedals.hub_enabled)
for(var/mob/living/L in view(7,src))
@@ -60,7 +54,15 @@
continue
SSmedals.UnlockMedal("[BOSS_MEDAL_TENDRIL] [ALL_KILL_MEDAL]", L.client)
SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1)
..()
GLOB.tendrils -= src
QDEL_NULL(emitted_light)
QDEL_NULL(gps)
return ..()
/obj/effect/light_emitter/tendril
set_luminosity = 4
set_cap = 2.5
light_color = LIGHT_COLOR_LAVA
/obj/effect/collapse
name = "collapsing necropolis tendril"
@@ -92,4 +94,4 @@
for(var/turf/T in range(2,src))
if(!T.density)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
qdel(src)
qdel(src)
+75
View File
@@ -0,0 +1,75 @@
/obj/structure/spawner
name = "monster nest"
icon = 'icons/mob/animal.dmi'
icon_state = "hole"
max_integrity = 100
move_resist = MOVE_FORCE_EXTREMELY_STRONG
anchored = TRUE
density = TRUE
var/max_mobs = 5
var/spawn_time = 300 //30 seconds default
var/mob_types = list(/mob/living/simple_animal/hostile/carp)
var/spawn_text = "emerges from"
var/faction = list("hostile")
/obj/structure/spawner/Initialize()
. = ..()
AddComponent(/datum/component/spawner, mob_types, spawn_time, faction, spawn_text, max_mobs)
/obj/structure/spawner/syndicate
name = "warp beacon"
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
spawn_text = "warps in from"
mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
faction = list(ROLE_SYNDICATE)
/obj/structure/spawner/skeleton
name = "bone pit"
desc = "A pit full of bones, and some still seem to be moving..."
icon_state = "hole"
icon = 'icons/mob/nest.dmi'
max_integrity = 150
max_mobs = 15
spawn_time = 150
mob_types = list(/mob/living/simple_animal/hostile/skeleton)
spawn_text = "climbs out of"
faction = list("skeleton")
/obj/structure/spawner/mining
name = "monster den"
desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids."
icon_state = "hole"
max_integrity = 200
max_mobs = 3
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls out of"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu)
faction = list("mining")
/obj/structure/spawner/mining/goldgrub
name = "goldgrub den"
desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
/obj/structure/spawner/mining/goliath
name = "goliath den"
desc = "A den housing a nest of goliaths, oh god why?"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
/obj/structure/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
/obj/structure/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
/obj/structure/spawner/mining/wumborian
name = "wumborian fugu den"
desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu)
+10 -19
View File
@@ -15,7 +15,8 @@
var/decon_speed = 30
var/wtype = "glass"
var/fulltile = FALSE
var/glass_type = /obj/item/stack/sheet/glass
var/obj/item/stack/sheet/glass_type = /obj/item/stack/sheet/glass
var/cleanable_type = /obj/effect/decal/cleanable/glass
var/glass_amount = 1
var/mutable_appearance/crack_overlay
can_be_unanchored = TRUE
@@ -277,12 +278,15 @@
/obj/structure/window/proc/spawnDebris(location)
. = list()
. += new /obj/item/shard(location)
. += new /obj/effect/decal/cleanable/glass(location)
var/shard = initial(glass_type.shard_type)
if(shard)
. += new shard(location)
if (fulltile)
. += new shard(location)
if(cleanable_type)
. += new cleanable_type(location)
if (reinf)
. += new /obj/item/stack/rods(location, (fulltile ? 2 : 1))
if (fulltile)
. += new /obj/item/shard(location)
/obj/structure/window/proc/can_be_rotated(mob/user,rotation_type)
if (get_dist(src,user) > 1)
@@ -416,17 +420,9 @@
max_integrity = 150
explosion_block = 1
glass_type = /obj/item/stack/sheet/plasmaglass
cleanable_type = /obj/effect/decal/cleanable/glass/plasma
rad_insulation = RAD_NO_INSULATION
/obj/structure/window/plasma/spawnDebris(location)
. = list()
. += new /obj/item/shard/plasma(location)
. += new /obj/effect/decal/cleanable/glass/plasma(location)
if (reinf)
. += new /obj/item/stack/rods(location, (fulltile ? 2 : 1))
if (fulltile)
. += new /obj/item/shard/plasma(location)
/obj/structure/window/plasma/spawner/east
dir = EAST
@@ -662,11 +658,6 @@
level = 3
glass_amount = 2
/obj/structure/window/reinforced/clockwork/spawnDebris(location)
. = list()
for(var/i in 1 to 4)
. += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location)
/obj/structure/window/reinforced/clockwork/Initialize(mapload, direct)
made_glow = TRUE
new /obj/effect/temp_visual/ratvar/window(get_turf(src))
@@ -151,9 +151,9 @@
has_data = TRUE
/turf/open/floor/plating/asteroid/airless/cave/volcanic
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /mob/living/simple_animal/hostile/spawner/lavaland/goliath = 3, \
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /mob/living/simple_animal/hostile/spawner/lavaland = 2, \
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /mob/living/simple_animal/hostile/spawner/lavaland/legion = 3, \
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /obj/structure/spawner/lavaland/goliath = 3, \
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \
SPAWN_MEGAFAUNA = 6, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data
@@ -274,7 +274,7 @@
return //if there's a megafauna within standard view don't spawn anything at all
if(ispath(randumb, /mob/living/simple_animal/hostile/asteroid) || istype(H, /mob/living/simple_animal/hostile/asteroid))
return //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
if((ispath(randumb, /mob/living/simple_animal/hostile/spawner/lavaland) || istype(H, /mob/living/simple_animal/hostile/spawner/lavaland)) && get_dist(src, H) <= 2)
if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(H, /obj/structure/spawner/lavaland)) && get_dist(src, H) <= 2)
return //prevents tendrils spawning in each other's collapse range
new randumb(T)
+1 -1
View File
@@ -36,7 +36,7 @@
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
/turf/open/lava/hitby(atom/movable/AM)
/turf/open/lava/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
+1 -1
View File
@@ -25,7 +25,7 @@
if(stored_pulling)
stored_pulling.setDir(get_dir(stored_pulling.loc, newloc))
stored_pulling.forceMove(src)
H.start_pulling(stored_pulling, TRUE)
H.start_pulling(stored_pulling, supress_message = TRUE)
/turf/closed/wall/mineral/cult/ratvar_act()
. = ..()
+36 -4
View File
@@ -185,7 +185,6 @@
body += "<A href='?_src_=holder;[HrefToken()];simplemake=shade;mob=[REF(M)]'>Shade</A>"
body += "<br>"
if (M.client)
body += "<br><br>"
body += "<b>Other actions:</b>"
body += "<br>"
@@ -194,9 +193,9 @@
body += "<A href='?_src_=holder;[HrefToken()];tdome2=[REF(M)]'>Thunderdome 2</A> | "
body += "<A href='?_src_=holder;[HrefToken()];tdomeadmin=[REF(M)]'>Thunderdome Admin</A> | "
body += "<A href='?_src_=holder;[HrefToken()];tdomeobserve=[REF(M)]'>Thunderdome Observer</A> | "
body += usr.client.citaPPoptions(M) // CITADEL
body += "<A href='?_src_=holder;[HrefToken()];makementor=[M.ckey]'>Make mentor</A> | "
body += "<A href='?_src_=holder;[HrefToken()];removementor=[M.ckey]'>Remove mentor</A>"
body += "<A href='?_src_=holder;[HrefToken()];makeeligible=[REF(M)]'>Allow reentering round</A>"
body += "<br>"
body += "</body></html>"
@@ -1009,3 +1008,36 @@
"Admin login: [key_name(src)]")
if(string)
message_admins("[string]")
/client/proc/cmd_admin_man_up(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set name = "Man Up"
if(!M)
return
if(!check_rights(R_ADMIN))
return
to_chat(M, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up")
var/message = "<span class='adminnotice'>[key_name_admin(usr)] told [key_name_admin(M)] to man up.</span>"
message_admins(message)
admin_ticket_log(M, message)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up")
/client/proc/cmd_admin_man_up_global()
set category = "Special Verbs"
set name = "Man Up Global"
if(!check_rights(R_ADMIN))
return
to_chat(world, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
for(var/mob/M in GLOB.player_list)
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up global: [key_name(usr)] told everybody to man up")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] told everybody to man up.</span>")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global")
+73 -2
View File
@@ -22,7 +22,10 @@
if(!CheckAdminHref(href, href_list))
return
citaTopic(href, href_list) //CITADEL EDIT, MENTORS
if(href_list["makementor"])
makeMentor(href_list["makementor"])
else if(href_list["removementor"])
removeMentor(href_list["removementor"])
if(href_list["ahelp"])
if(!check_rights(R_ADMIN, TRUE))
@@ -907,12 +910,16 @@
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=alien;jobban4=[REF(M)]'><font color=red>Alien</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=alien;jobban4=[REF(M)]'>Alien</a></td>"
//Gang
if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept)
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=gang;jobban4=[REF(M)]'><font color=red>Gang</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=gang;jobban4=[REF(M)]'>Gang</a></td>"
//Bloodsucker
if(jobban_isbanned(M, ROLE_BLOODSUCKER) || isbanned_dept)
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=bloodsucker;jobban4=[REF(M)]'><font color=red>Bloodsucker</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=bloodsucker;jobban4=[REF(M)]'>Bloodsucker</a></td>"
//Other Roles (black)
@@ -1715,6 +1722,16 @@
log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]</span>")
else if(href_list["makeeligible"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["makeeligible"])
if(!ismob(M))
to_chat(usr, "this can only be used on instances of type /mob.")
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
if(M.ckey in eli.timeouts)
eli.timeouts -= M.ckey
else if(href_list["sendtoprison"])
if(!check_rights(R_ADMIN))
return
@@ -2846,3 +2863,57 @@
dat += {"<A href='?src=[REF(src)];[HrefToken()];f_secret2=secret'>Random (default)</A><br>"}
dat += {"Now: [GLOB.secret_force_mode]"}
usr << browse(dat, "window=f_secret")
/datum/admins/proc/makeMentor(ckey)
if(!usr.client)
return
if (!check_rights(0))
return
if(!ckey)
return
var/client/C = GLOB.directory[ckey]
if(C)
if(check_rights_for(C, R_ADMIN,0))
to_chat(usr, "<span class='danger'>The client chosen is an admin! Cannot mentorize.</span>")
return
if(SSdbcore.Connect())
var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
if(query_get_mentor.NextRow())
to_chat(usr, "<span class='danger'>[ckey] is already a mentor.</span>")
return
var/datum/DBQuery/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')")
if(!query_add_mentor.warn_execute())
return
var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');")
if(!query_add_admin_log.warn_execute())
return
else
to_chat(usr, "<span class='danger'>Failed to establish database connection. The changes will last only for the current round.</span>")
new /datum/mentors(ckey)
to_chat(usr, "<span class='adminnotice'>New mentor added.</span>")
/datum/admins/proc/removeMentor(ckey)
if(!usr.client)
return
if (!check_rights(0))
return
if(!ckey)
return
var/client/C = GLOB.directory[ckey]
if(C)
if(check_rights_for(C, R_ADMIN,0))
to_chat(usr, "<span class='danger'>The client chosen is an admin, not a mentor! Cannot de-mentorize.</span>")
return
C.remove_mentor_verbs()
C.mentor_datum = null
GLOB.mentors -= C
if(SSdbcore.Connect())
var/datum/DBQuery/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
if(!query_remove_mentor.warn_execute())
return
var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');")
if(!query_add_admin_log.warn_execute())
return
else
to_chat(usr, "<span class='danger'>Failed to establish database connection. The changes will last only for the current round.</span>")
to_chat(usr, "<span class='adminnotice'>Mentor removed.</span>")
@@ -46,7 +46,6 @@
dat += "<a href='?src=[REF(src)];dispense=baton'>Advanced Baton (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=mind_device'>Mental Interface Device (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=chem_dispenser'>Reagent Synthesizer (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=shrink_ray'>Shrink Ray Blaster (2 Credits)</a><br>"
dat += "<a href='?src=[REF(src)];dispense=helmet'>Agent Helmet (1 Credit)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=vest'>Agent Vest (1 Credit)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=silencer'>Radio Silencer (1 Credit)</A><br>"
@@ -119,8 +118,6 @@
Dispense(/obj/item/abductor_machine_beacon/chem_dispenser,cost=2)
if("tongue")
Dispense(/obj/item/organ/tongue/abductor)
if("shrink_ray")
Dispense(/obj/item/gun/energy/shrink_ray,cost=2)
updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
@@ -245,4 +242,4 @@
new item(drop_location)
else
say("Insufficent data!")
say("Insufficent data!")
@@ -174,7 +174,7 @@
if(!GlandTest)
say("Experimental dissection not detected!")
return "<span class='bad'>No glands detected!</span>"
if(H.mind != null && H.ckey != null)
if(H.mind != null && (H.voluntary_ghosted || (H.ckey != null)))
LAZYINITLIST(abductee_minds)
LAZYADD(history, H)
LAZYADD(abductee_minds, H.mind)
@@ -45,10 +45,10 @@
bonus_damage *= 3 //total 30 damage on cultists, 50 with ratvar
GLOB.clockwork_vitality += target.adjustFireLoss(bonus_damage) //adds the damage done to existing vitality
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
if(isliving(target))
var/mob/living/L = target
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(is_servant_of_ratvar(L))
if(L.put_in_active_hand(src))
L.visible_message("<span class='warning'>[L] catches [src] out of the air!</span>")
@@ -70,6 +70,7 @@
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil)
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC
/obj/item/clothing/suit/armor/clockwork/Initialize()
. = ..()
+9 -9
View File
@@ -265,7 +265,7 @@
to_chat(user, "<span class='warning'>The bola seems to take on a life of its own!</span>")
throw_impact(user)
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscultist(hit_atom))
return
. = ..()
@@ -690,10 +690,10 @@
/obj/item/twohanded/cult_spear/update_icon()
icon_state = "bloodspear[wielded]"
/obj/item/twohanded/cult_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
if(isliving(target))
var/mob/living/L = target
/obj/item/twohanded/cult_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(iscultist(L))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
if(L.put_in_active_hand(src))
@@ -987,11 +987,11 @@
return TRUE
return FALSE
/obj/item/shield/mirror/throw_impact(atom/target, throwingdatum)
var/turf/T = get_turf(target)
/obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
var/datum/thrownthing/D = throwingdatum
if(isliving(target))
var/mob/living/L = target
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(iscultist(L))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
if(L.put_in_active_hand(src))
@@ -44,7 +44,7 @@
wander = FALSE
density = FALSE
movement_type = FLYING
anchored = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_TINY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
speed = 1
@@ -361,7 +361,7 @@
user.dropItemToGround(src)
scatter()
/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom)
/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if(inert)
return
+1 -1
View File
@@ -142,7 +142,7 @@
. = ..()
olddir = dir
/obj/item/assembly/infra/throw_impact()
/obj/item/assembly/infra/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(!olddir)
return
+2 -2
View File
@@ -130,10 +130,10 @@
return FALSE
/obj/item/assembly/mousetrap/hitby(A as mob|obj)
/obj/item/assembly/mousetrap/hitby(atom/hit_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
visible_message("<span class='warning'>[src] is triggered by [hit_atom].</span>")
triggered(null)
@@ -267,12 +267,13 @@
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
set waitfor = 0
var/move_prob = 100
if (pressure_resistance > 0)
move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET
move_prob += pressure_resistance_prob_delta
if (move_prob > PROBABILITY_OFFSET && prob(move_prob))
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
@@ -1,19 +1,18 @@
/*
Quick overview:
// Quick overview:
//
// Pipes combine to form pipelines
// Pipelines and other atmospheric objects combine to form pipe_networks
// Note: A single pipe_network represents a completely open space
//
// Pipes -> Pipelines
// Pipelines + Other Objects -> Pipe network
Pipes combine to form pipelines
Pipelines and other atmospheric objects combine to form pipe_networks
Note: A single pipe_network represents a completely open space
Pipes -> Pipelines
Pipelines + Other Objects -> Pipe network
*/
#define PIPE_VISIBLE_LEVEL 2
#define PIPE_HIDDEN_LEVEL 1
/obj/machinery/atmospherics
anchored = TRUE
move_resist = INFINITY //Moving a connected machine without actually doing the normal (dis)connection things will probably cause a LOT of issues.
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
@@ -100,13 +99,14 @@ Pipelines + Other Objects -> Pipe network
return node_connects
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
if(dir==SOUTH)
setDir(NORTH)
else if(dir==WEST)
setDir(EAST)
switch(dir)
if(SOUTH)
setDir(NORTH)
if(WEST)
setDir(EAST)
//this is called just after the air controller sets up turfs
/obj/machinery/atmospherics/proc/atmosinit(var/list/node_connects)
/obj/machinery/atmospherics/proc/atmosinit(list/node_connects)
if(!node_connects) //for pipes where order of nodes doesn't matter
node_connects = getNodeConnects()
@@ -118,12 +118,8 @@ Pipelines + Other Objects -> Pipe network
update_icon()
/obj/machinery/atmospherics/proc/setPipingLayer(new_layer)
if(pipe_flags & PIPING_DEFAULT_LAYER_ONLY)
new_layer = PIPING_LAYER_DEFAULT
piping_layer = new_layer
pixel_x = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
pixel_y = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_icon()
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration)
return connection_check(target, piping_layer)
@@ -175,9 +171,6 @@ Pipelines + Other Objects -> Pipe network
nodes[nodes.Find(reference)] = null
update_icon()
/obj/machinery/atmospherics/update_icon()
return
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe)) //lets you autodrop
var/obj/item/pipe/pipe = W
@@ -234,15 +227,13 @@ Pipelines + Other Objects -> Pipe network
var/datum/gas_mixture/env_air = loc.return_air()
pressures = int_air.return_pressure() - env_air.return_pressure()
var/fuck_you_dir = get_dir(src, user) // Because fuck you...
if(!fuck_you_dir)
fuck_you_dir = pick(GLOB.cardinals)
var/turf/target = get_edge_target_turf(user, fuck_you_dir)
var/range = pressures/250
var/speed = range/5
user.visible_message("<span class='danger'>[user] is sent flying by pressure!</span>","<span class='userdanger'>The pressure sends you flying!</span>")
user.throw_at(target, range, speed)
// if get_dir(src, user) is not 0, target is the edge_target_turf on that dir
// otherwise, edge_target_turf uses a random cardinal direction
// range is pressures / 250
// speed is pressures / 1250
user.throw_at(get_edge_target_turf(user, get_dir(src, user) || pick(GLOB.cardinals)), pressures / 250, pressures / 1250)
/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
@@ -254,30 +245,20 @@ Pipelines + Other Objects -> Pipe network
transfer_fingerprints_to(stored)
..()
/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255))
/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=2)
//Add identifiers for the iconset
if(iconsetids[iconset] == null)
iconsetids[iconset] = num2text(iconsetids.len + 1)
//Generate a unique identifier for this image combination
var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]"
var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]_[piping_layer]"
if((!(. = pipeimages[identifier])))
var/image/pipe_overlay
pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction)
pipe_overlay.color = col
/obj/machinery/atmospherics/proc/icon_addintact(var/obj/machinery/atmospherics/node)
var/image/img = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_intact", get_dir(src,node), node.pipe_color)
underlays += img
return img.dir
/obj/machinery/atmospherics/proc/icon_addbroken(var/connected = FALSE)
var/unconnected = (~connected) & initialize_directions
for(var/direction in GLOB.cardinals)
if(unconnected & direction)
underlays += getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_exposed", direction)
PIPING_LAYER_SHIFT(pipe_overlay, piping_layer)
/obj/machinery/atmospherics/on_construction(obj_color, set_layer)
if(can_unwrench)
@@ -319,7 +300,7 @@ Pipelines + Other Objects -> Pipe network
if(target_move.can_crawl_through())
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
user.forceMove(target_move.loc) //handle entering and so on.
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>","<span class='notice'>You climb out the ventilation system.")
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
else
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
if(pipenetdiff.len)
@@ -331,7 +312,7 @@ Pipelines + Other Objects -> Pipe network
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
user.forceMove(loc)
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>","<span class='notice'>You climb out the ventilation system.")
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.")
user.canmove = FALSE
addtimer(VARSET_CALLBACK(user, canmove, TRUE), 1)
@@ -355,3 +336,6 @@ Pipelines + Other Objects -> Pipe network
//Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it.
/obj/machinery/atmospherics/proc/can_see_pipes()
return TRUE
/obj/machinery/atmospherics/proc/update_layer()
layer = initial(layer) + (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE

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