Merge branch 'master' into departmentalclothes

This commit is contained in:
faaaay
2021-07-20 17:16:43 +01:00
committed by GitHub
76 changed files with 689 additions and 203 deletions

View File

@@ -254,7 +254,7 @@
"aIp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 6; name = "scrubbers pipe"},/turf/open/floor/plasteel,/area/crew_quarters/fitness/pool)
"aIr" = (/obj/effect/turf_decal/stripes/line{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 5; name = "air supply pipe"},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_trim"},/area/ai_monitored/security/armory)
"aIB" = (/obj/machinery/chem_heater,/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/effect/turf_decal/tile/yellow{dir = 1},/turf/open/floor/plasteel/white,/area/medical/chemistry)
"aIE" = (/obj/machinery/door/airlock/public/glass{name = "Abandon Maintenance Pool"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/maintenance/fore)
"aIE" = (/obj/machinery/door/airlock/public/glass{name = "Abandoned Maintenance Pool"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{dir = 8; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/turf/open/floor/plasteel/dark,/area/maintenance/fore)
"aIJ" = (/obj/effect/spawner/structure/window/reinforced,/turf/open/floor/plating,/area/medical/virology)
"aIK" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer3{dir = 1; name = "air supply pipe"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1{dir = 1; name = "scrubbers pipe"},/obj/structure/cable{icon_state = "2-8"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel{dir = 1; icon_plating = "floor"; icon_state = "floor_whole"},/area/hallway/secondary/exit)
"aIT" = (/obj/machinery/atm{pixel_y = 30},/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/brown,/turf/open/floor/plasteel,/area/hallway/primary/aft)
@@ -2953,7 +2953,7 @@
"iqp" = (/obj/structure/table,/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral,/obj/item/clothing/glasses/meson{pixel_x = 2; pixel_y = 4},/obj/item/clothing/glasses/meson,/turf/open/floor/plasteel,/area/engine/engineering)
"iqt" = (/obj/effect/turf_decal/tile/blue{dir = 1},/obj/effect/turf_decal/tile/blue{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{dir = 4; name = "scrubbers pipe"},/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{name = "air vent"},/obj/structure/cable{icon_state = "2-4"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/newscaster{pixel_y = 32},/turf/open/floor/plasteel/white,/area/medical/sleeper)
"iqu" = (/obj/structure/table,/turf/open/floor/plasteel/freezer,/area/medical/sleeper)
"iqD" = (/obj/structure/flora/crystal/medium/growth,/turf/open/indestructible/layenia/crystal/garden,/area/layenia)
"iqD" = (/obj/structure/flora/crystal/medium/growth,/turf/open/indestructible/layenia/crystal/garden,/area/crew_quarters/heads/hop)
"iqP" = (/obj/structure/flora/junglebush,/obj/structure/window/reinforced{dir = 8},/turf/open/floor/grass,/area/medical/sleeper)
"ire" = (/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/obj/machinery/porta_turret/ai{dir = 8},/turf/open/floor/circuit,/area/ai_monitored/turret_protected/ai_upload)
"irn" = (/obj/structure/chair{dir = 8},/obj/structure/window{dir = 4},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel{dir = 4; icon_state = "floor_plate"},/area/hallway/secondary/exit)
@@ -3236,7 +3236,7 @@
"jax" = (/obj/machinery/meter/atmos/atmos_waste_loop,/obj/machinery/camera{c_tag = "Atmospherics North East"},/obj/machinery/light{dir = 1; pixel_y = 16},/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{dir = 1},/obj/structure/cable{icon_state = "2-4"},/turf/open/floor/plasteel,/area/engine/atmos)
"jaB" = (/obj/item/twohanded/required/kirbyplants/random,/turf/open/floor/wood,/area/lawoffice)
"jaD" = (/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/effect/turf_decal/tile/neutral,/turf/open/floor/plasteel/dark,/area/security/main)
"jaH" = (/obj/structure/cable/yellow{icon_state = "1-4"},/obj/machinery/turretid{control_area = "/area/ai_monitored/turret_protected/aisat_interior"; name = "Antechamber Turret Control"; pixel_y = 24; req_access = null; req_access_txt = "65"},/obj/effect/turf_decal/tile/blue{dir = 4},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/aisat_interior)
"jaH" = (/obj/structure/cable/yellow{icon_state = "1-4"},/obj/machinery/turretid{control_area = "/area/ai_monitored/turret_protected/aisat/hallway"; name = "Antechamber Turret Control"; pixel_y = 24; req_access = null; req_access_txt = "65"},/obj/effect/turf_decal/tile/blue{dir = 4},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/aisat_interior)
"jaR" = (/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/obj/effect/turf_decal/tile/neutral{dir = 4},/obj/machinery/light{pixel_y = -1},/obj/structure/sign/departments/restroom{pixel_y = -32},/turf/open/floor/plasteel{icon_state = "floor_plate"},/area/hallway/primary/fore)
"jaX" = (/obj/effect/baseturf_helper/asteroid/layenia,/turf/closed/wall/r_wall,/area/science/xenobiology)
"jaZ" = (/obj/machinery/vending/wardrobe/law_wardrobe,/obj/machinery/light{dir = 4; pixel_x = 7; pixel_y = 0},/turf/open/floor/wood,/area/lawoffice)
@@ -6365,7 +6365,7 @@
"rNe" = (/obj/effect/turf_decal/tile/red,/obj/effect/turf_decal/tile/red{dir = 4},/obj/effect/turf_decal/tile/neutral{dir = 8},/obj/effect/turf_decal/tile/neutral{dir = 1},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/turf/open/floor/plasteel/dark/side{dir = 8},/area/security/main)
"rNg" = (/obj/machinery/atmospherics/pipe/simple/cyan/visible,/obj/structure/cable{icon_state = "1-2"},/turf/open/floor/plasteel{dir = 8; icon_state = "floor_trim"},/area/engine/atmos)
"rNj" = (/obj/machinery/power/apc{areastring = "/area/crew_quarters/fitness"; name = "Fitness Room APC"; pixel_y = -24},/obj/structure/cable,/turf/open/floor/wood,/area/crew_quarters/fitness)
"rNv" = (/obj/structure/flora/crystal/small/pile,/obj/structure/flora/crystal/small/growth{icon_state = "crystalgrowth3"},/turf/open/indestructible/layenia/crystal/garden,/area/layenia)
"rNv" = (/obj/structure/flora/crystal/small/pile,/obj/structure/flora/crystal/small/growth{icon_state = "crystalgrowth3"},/turf/open/indestructible/layenia/crystal/garden,/area/crew_quarters/heads/hop)
"rNy" = (/obj/structure/toilet{dir = 4},/obj/machinery/light{dir = 8; pixel_x = -7; pixel_y = 0},/turf/open/floor/plasteel/freezer,/area/crew_quarters/toilet)
"rNz" = (/obj/structure/table/reinforced,/obj/machinery/keycard_auth{pixel_x = 3; pixel_y = 5},/obj/effect/turf_decal/tile/green,/obj/effect/turf_decal/tile/green{dir = 4},/obj/effect/turf_decal/tile/blue{dir = 1},/turf/open/floor/plasteel/white/corner{dir = 8},/area/bridge)
"rNF" = (/obj/effect/turf_decal/loading_area{icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/white/corner{dir = 1},/area/science/research)
@@ -7304,7 +7304,7 @@
"ulb" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8; layer = 2.9},/obj/machinery/conveyor{id = "gasstor"},/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/open/floor/plating,/area/engine/engineering)
"ulm" = (/obj/structure/flora/crystal/medium/growth{icon_state = "crystalgrowth1"},/turf/open/indestructible/layenia/crystal/garden,/area/crew_quarters/heads/hor)
"ulp" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,/obj/structure/cable{icon_state = "4-8"},/turf/open/floor/plasteel/dark,/area/maintenance/disposal/incinerator)
"ulL" = (/obj/structure/cable/yellow{icon_state = "1-2"},/obj/structure/cable/yellow{icon_state = "1-8"},/obj/machinery/atmospherics/components/unary/vent_pump/on{dir = 8},/obj/machinery/light{dir = 1; pixel_y = 16},/obj/item/twohanded/required/kirbyplants/photosynthetic{pixel_y = 10},/obj/machinery/turretid{control_area = "/area/ai_monitored/turret_protected/aisat/hallway"; name = "Chamber Hallway Turret Control"; pixel_x = 32; pixel_y = 24; req_access = null; req_access_txt = "65"},/obj/structure/extinguisher_cabinet{pixel_x = 27},/obj/effect/turf_decal/tile/blue{dir = 4},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/aisat/hallway)
"ulL" = (/obj/structure/cable/yellow{icon_state = "1-2"},/obj/structure/cable/yellow{icon_state = "1-8"},/obj/machinery/atmospherics/components/unary/vent_pump/on{dir = 8},/obj/machinery/light{dir = 1; pixel_y = 16},/obj/item/twohanded/required/kirbyplants/photosynthetic{pixel_y = 10},/obj/machinery/turretid{control_area = "/area/ai_monitored/turret_protected/aisat_interior"; name = "Chamber Hallway Turret Control"; pixel_x = 32; pixel_y = 24; req_access = null; req_access_txt = "65"},/obj/structure/extinguisher_cabinet{pixel_x = 27},/obj/effect/turf_decal/tile/blue{dir = 4},/turf/open/floor/plasteel/dark,/area/ai_monitored/turret_protected/aisat/hallway)
"ulM" = (/obj/machinery/vending/wardrobe/chem_wardrobe,/obj/effect/turf_decal/tile/yellow{dir = 1},/obj/effect/turf_decal/tile/yellow{dir = 8},/obj/effect/turf_decal/tile/yellow,/turf/open/floor/plasteel/white,/area/medical/chemistry)
"umu" = (/obj/effect/turf_decal/loading_area{dir = 1; icon_state = "drain"; name = "drain"},/turf/open/floor/plasteel/white,/area/medical/medbay/central)
"umv" = (/obj/structure/cable{icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{name = "scrubbers pipe"},/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{name = "air supply pipe"},/turf/open/floor/plasteel,/area/security/main)

View File

@@ -20,8 +20,8 @@
"t" = (/obj/structure/table/reinforced,/obj/effect/turf_decal/tile/bar,/obj/effect/turf_decal/tile/bar{dir = 1},/turf/open/floor/plasteel,/area/shuttle/escape)
"u" = (/obj/machinery/light{dir = 8},/turf/open/floor/wood,/area/shuttle/escape)
"v" = (/obj/structure/chair/office/dark,/turf/open/floor/wood,/area/shuttle/escape)
"w" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/drip,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/mob_spawn/human/corpse,/obj/item/gun/ballistic/automatic/pistol/m1911,/obj/machinery/light/small{dir = 8},/obj/item/reagent_containers/food/snacks/cakeslice/birthday,/turf/open/floor/carpet,/area/shuttle/escape)
"x" = (/obj/structure/bed,/obj/item/bedsheet/red,/obj/item/paper/fluff/shuttles/daniel,/turf/open/floor/carpet,/area/shuttle/escape)
"w" = (/obj/machinery/light/small{dir = 8},/mob/living/simple_animal/bot/hugbot,/turf/open/floor/carpet,/area/shuttle/escape)
"x" = (/obj/structure/bed,/obj/item/bedsheet/red,/turf/open/floor/carpet,/area/shuttle/escape)
"y" = (/obj/item/twohanded/required/kirbyplants,/turf/open/floor/wood,/area/shuttle/escape)
"z" = (/obj/structure/table/wood,/obj/item/papercutter,/turf/open/floor/wood,/area/shuttle/escape)
"A" = (/obj/structure/table/wood,/obj/machinery/computer/libraryconsole/bookmanagement,/turf/open/floor/wood,/area/shuttle/escape)

View File

@@ -80,6 +80,7 @@
#define ADMIN_PUNISHMENT_NUGGET "Nugget"
#define ADMIN_PUNISHMENT_BREADIFY ":b:read"
#define ADMIN_PUNISHMENT_BOOKIFY "Bookify"
#define ADMIN_PUNISHMENT_BONK "Bonk"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2

View File

@@ -28,7 +28,9 @@
#define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets.
#define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets.
#define ITEM_SLOT_NECK (1<<13)
#define ITEM_SLOT_SUITSTORE (1<<14)
#define ITEM_SLOT_HANDS (1<<14)
#define ITEM_SLOT_BACKPACK (1<<15)
#define ITEM_SLOT_SUITSTORE (1<<16)
//SLOTS
#define SLOT_BACK 1
@@ -86,6 +88,10 @@
. = ITEM_SLOT_ICLOTHING
if(SLOT_L_STORE, SLOT_R_STORE)
. = ITEM_SLOT_POCKET
if(SLOT_HANDS)
. = ITEM_SLOT_HANDS
if(SLOT_IN_BACKPACK)
. = ITEM_SLOT_BACKPACK
if(SLOT_S_STORE)
. = ITEM_SLOT_SUITSTORE

View File

@@ -158,6 +158,17 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
return FALSE
return TRUE
/mob/living/carbon/proc/is_butt_exposed(var/list/L)
if(!L)
L = get_equipped_items()
for(var/obj/item/I in L)
if(I.body_parts_covered & GROIN)
if(!I.do_not_cover_butt)
return FALSE
else
return TRUE
return TRUE
/mob/living/carbon/proc/is_chest_exposed(var/list/L)
if(!L)
L = get_equipped_items()

View File

@@ -183,6 +183,7 @@
"cock_shape" = pick(GLOB.cock_shapes_list),
"cock_length" = 6,
"belly_size" = 1,
"butt_size" = 1,
"cock_girth_ratio" = COCK_GIRTH_RATIO_DEF,
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_sheath" = FALSE,
@@ -192,6 +193,7 @@
"inflatable_belly" = FALSE,
"belly_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_balls" = FALSE,
"has_anus" = FALSE,
"balls_internal" = FALSE,
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"balls_amount" = 2,

View File

@@ -2,12 +2,13 @@
var/magic = FALSE
var/holy = FALSE
var/psychic = FALSE
var/allowed_slots = ~ITEM_SLOT_BACKPACK
var/charges = INFINITY
var/blocks_self = TRUE
var/datum/callback/reaction
var/datum/callback/expire
/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE, _psychic = FALSE, _charges, _blocks_self = TRUE, datum/callback/_reaction, datum/callback/_expire)
/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE, _psychic = FALSE, _allowed_slots, _charges, _blocks_self = TRUE, datum/callback/_reaction, datum/callback/_expire)
if(isitem(parent))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
@@ -19,6 +20,8 @@
magic = _magic
holy = _holy
psychic = _psychic
if(_allowed_slots)
allowed_slots = _allowed_slots
if(!isnull(_charges))
charges = _charges
blocks_self = _blocks_self
@@ -26,6 +29,9 @@
expire = _expire
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
if(!CHECK_BITFIELD(allowed_slots, slotdefine2slotbit(slot))) //Check that the slot is valid for antimagic
UnregisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC)
return
RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/protect, TRUE)
/datum/component/anti_magic/proc/on_drop(datum/source, mob/user)

View File

@@ -7,33 +7,24 @@
var/filter_x
var/filter_y
var/filter_size
var/filter_border
var/filter_color
/datum/component/wearertargeting/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _border = 0, _color = "#E62111", list/_valid_slots = list(SLOT_GLASSES))
/datum/component/wearertargeting/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _color = "#E62111", list/_valid_slots = list(SLOT_GLASSES))
. = ..()
if(. == COMPONENT_INCOMPATIBLE)
return
filter_x = _x
filter_y = _y
filter_size = _size
filter_border = _border
filter_color = _color
valid_slots = _valid_slots
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(datum/source, mob/user, combatmodestate)
if(istype(user))
var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
if(!combatmodestate)
user.filters -= thefilter
else
user.filters += thefilter
/datum/component/wearertargeting/phantomthief/proc/stripdesiredfilter(mob/user)
if(istype(user))
var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
user.filters -= thefilter
if(!combatmodestate)
user.remove_filter("phantomthief")
else
user.add_filter("phantomthief", 4, list(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, color = filter_color))
/datum/component/wearertargeting/phantomthief/on_drop(datum/source, mob/user)
. = ..()
stripdesiredfilter(user)
user.remove_filter("phantomthief")

View File

@@ -26,10 +26,10 @@
/datum/proc/vv_get_dropdown()
. = list()
. += "---"
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]"
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]"
.["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]"
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]"
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=\ref[src]"
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=\ref[src]"
.["Delete"] = "?_src_=vars;[HrefToken()];delete=\ref[src]"
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=\ref[src]"
/datum/proc/on_reagent_change(changetype)
@@ -54,7 +54,7 @@
return
var/title = ""
var/refid = REF(D)
var/refid = "\ref[D]"
var/icon/sprite
var/hash
@@ -62,8 +62,6 @@
if (!islist)
type = D.type
if(istype(D, /atom))
var/atom/AT = D
if(AT.icon && AT.icon_state)
@@ -411,7 +409,7 @@
/client/proc/vv_update_display(datum/D, span, content)
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
@@ -424,9 +422,9 @@
name = DA[name] //name is really the index until this line
else
value = DA[name]
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=[REF(DA)];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=[REF(DA)];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=[REF(DA)];index=[index]'>-</a>) "
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=\ref[DA];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=\ref[DA];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=\ref[DA];index=[index]'>-</a>) "
else
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=[REF(DA)];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=[REF(DA)];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=[REF(DA)];varnamemass=[name]'>M</a>) "
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=\ref[DA];varnamemass=[name]'>M</a>) "
else
header = "<li>"
@@ -441,7 +439,7 @@
#ifdef VARSICON
var/icon/I = new/icon(value)
var/rnd = rand(1,10000)
var/rname = "tmp[REF(I)][rnd].png"
var/rname = "tmp\ref[I][rnd].png"
usr << browse_rsc(I, rname)
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
#else
@@ -454,9 +452,9 @@
else if (istype(value, /datum))
var/datum/D = value
if ("[D]" != "[D.type]") //if the thing as a name var, lets use it.
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
else if (islist(value))
var/list/L = value
@@ -474,9 +472,9 @@
items += debug_variable(key, val, level + 1, sanitize = sanitize)
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
else if (name in GLOB.bitfields)
var/list/flags = list()
@@ -588,7 +586,7 @@
var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anything nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No")
if (prompt != "Yes" || !usr.client)
return
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=[REF(thing)]'>VV window</a>")
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=\ref[thing]'>VV window</a>")
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [thing]")
to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
C.debug_variables(thing)

View File

@@ -0,0 +1,28 @@
#define SHORT 5/7
#define TALL 7/5
/datum/element/squish
element_flags = ELEMENT_DETACH
/datum/element/squish/Attach(datum/target, duration)
. = ..()
if(!iscarbon(target))
return ELEMENT_INCOMPATIBLE
var/mob/living/carbon/C = target
var/was_lying = (C.lying != 0)
addtimer(CALLBACK(src, .proc/Detach, C, was_lying), duration)
C.transform = C.transform.Scale(TALL, SHORT)
/datum/element/squish/Detach(mob/living/carbon/C, was_lying)
. = ..()
if(istype(C))
var/is_lying = (C.lying != 0)
if(was_lying == is_lying)
C.transform = C.transform.Scale(SHORT, TALL)
else
C.transform = C.transform.Scale(TALL, SHORT)
#undef SHORT
#undef TALL

View File

@@ -223,7 +223,7 @@
/datum/status_effect/belligerent/proc/do_movement_toggle(force_damage)
var/number_legs = owner.get_num_legs(FALSE)
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check() && number_legs)
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check(chargecost = 0) && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
owner.Knockdown(20)
@@ -316,7 +316,7 @@
if(owner.confused)
owner.confused = 0
severity = 0
else if(!owner.anti_magic_check() && owner.stat != DEAD && severity)
else if(!owner.anti_magic_check(chargecost = 0) && owner.stat != DEAD && severity)
var/static/hum = get_sfx('sound/effects/screech.ogg') //same sound for every proc call
if(owner.getToxLoss() > MANIA_DAMAGE_TO_CONVERT)
if(is_eligible_servant(owner))

View File

@@ -78,6 +78,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/strip_delay = 40 //In deciseconds, how long an item takes to remove from another person
var/breakouttime = 0
var/list/materials
var/reskinned = FALSE
var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item
@@ -123,6 +124,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//Hyper economy
var/price = 0
//Hyper, for clothes that reveal your behind! butt stuff, you know how it is.
var/do_not_cover_butt = FALSE
/obj/item/Initialize()

View File

@@ -35,6 +35,24 @@
drop_sound = 'sound/items/handling/multitool_drop.ogg'
pickup_sound = 'sound/items/handling/multitool_pickup.ogg'
/obj/item/multitool/chaplain
name = "\improper hypertool"
desc = "Used for pulsing wires to test which to cut. Also emits microwaves to fry some brains!"
damtype = BRAIN
force = 18
armour_penetration = 35
hitsound = 'sound/effects/sparks4.ogg'
var/chaplain_spawnable = TRUE
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
throw_speed = 3
throw_range = 4
throwforce = 10
obj_flags = UNIQUE_RENAME
/obj/item/multitool/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/multitool/examine(mob/user)
. = ..()
if(selected_io)

View File

@@ -547,7 +547,9 @@ GENE SCANNER
var/turf/location = user.loc
if(!istype(location))
return
scan_turf(user, location)
/obj/item/analyzer/proc/scan_turf(mob/user, turf/location)
var/datum/gas_mixture/environment = location.return_air()
var/pressure = environment.return_pressure()
@@ -658,6 +660,20 @@ GENE SCANNER
amount += inaccurate
return DisplayTimeText(max(1,amount))
/obj/item/analyzer/ranged
desc = "A hand-held scanner which uses advanced spectroscopy and infrared readings to analyze gases as a distance. Alt-Click to use the built in barometer function."
name = "long-range analyzer"
icon = 'icons/obj/device.dmi'
icon_state = "ranged_analyzer"
/obj/item/analyzer/ranged/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(target.tool_act(user, src, tool_behaviour))
return
// Tool act didn't scan it, so let's get it's turf.
var/turf/location = get_turf(target)
scan_turf(user, location)
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
var/icon = target
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(src))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")

View File

@@ -229,12 +229,12 @@
throwforce = 10
w_class = WEIGHT_CLASS_TINY
obj_flags = UNIQUE_RENAME
var/reskinned = FALSE
var/chaplain_spawnable = TRUE
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
/obj/item/nullrod/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/nullrod/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!</span>")
@@ -248,7 +248,12 @@
if(GLOB.holy_weapon_type)
return
var/obj/item/holy_weapon
var/list/holy_weapons_list = subtypesof(/obj/item/nullrod)
var/list/holy_weapons_list = subtypesof(/obj/item/nullrod) + list(
/obj/item/twohanded/dualsaber/hypereutactic/chaplain,
/obj/item/gun/energy/laser/redtag/hitscan/chaplain,
/obj/item/multitool/chaplain,
/obj/item/melee/baseball_bat/chaplain
)
var/list/display_names = list()
var/list/nullrod_icons = list()
for(var/V in holy_weapons_list)
@@ -289,6 +294,13 @@
return FALSE
return TRUE
/obj/item/nullrod/proc/jedi_spin(mob/living/user)
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
user.setDir(i)
if(i == WEST)
user.emote("flip")
sleep(1)
/obj/item/nullrod/godhand
icon_state = "disintegrate"
item_state = "disintegrate"
@@ -344,7 +356,6 @@
sharpness = IS_SHARP
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
/obj/item/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
@@ -541,7 +552,6 @@
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_HUGE
attack_verb = list("smashed", "bashed", "hammered", "crunched")
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
/obj/item/nullrod/chainsaw
name = "chainsaw hand"
@@ -606,6 +616,7 @@
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
slot_flags = ITEM_SLOT_BELT
force = 12
reach = 2
attack_verb = list("whipped", "lashed")
hitsound = 'sound/weapons/chainhit.ogg'
@@ -682,6 +693,44 @@
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
/obj/item/nullrod/claymore/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
user.Knockdown(60)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD)
else
user.take_bodypart_damage(2*force)
return
if(iscyborg(target))
return ..()
if(!isliving(target))
return ..()
var/mob/living/carbon/C = target
if(C.stat || C.health < 0 || C.staminaloss > 130 )
to_chat(user, "<span class='warning'>It would be dishonorable to attack a foe while they cannot retaliate.</span>")
return
if(user.a_intent == INTENT_DISARM)
if(!ishuman(target))
return ..()
var/mob/living/carbon/human/H = target
var/list/fluffmessages = list("[user] clubs [H] with [src]!", \
"[user] smacks [H] with the butt of [src]!", \
"[user] broadsides [H] with [src]!", \
"[user] smashes [H]'s head with [src]!", \
"[user] beats [H] with front of [src]!", \
"[user] twirls and slams [H] with [src]!")
H.visible_message("<span class='warning'>[pick(fluffmessages)]</span>", \
"<span class='userdanger'>[pick(fluffmessages)]</span>")
playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1)
H.adjustStaminaLoss(rand(12,18))
if(prob(25))
(INVOKE_ASYNC(src, .proc/jedi_spin, user))
else
return ..()
/obj/item/nullrod/tribal_knife
icon_state = "crysknife"
item_state = "crysknife"
@@ -695,7 +744,6 @@
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
item_flags = SLOWS_WHILE_IN_HAND
total_mass = TOTAL_MASS_NORMAL_ITEM
/obj/item/nullrod/tribal_knife/Initialize(mapload)
. = ..()

View File

@@ -86,7 +86,7 @@
new /obj/item/multitool(src)
new /obj/item/stack/cable_coil(src,30,pick("red","yellow","orange"))
new /obj/item/extinguisher/mini(src)
new /obj/item/analyzer(src)
new /obj/item/analyzer/ranged(src)
//much roomier now that we've managed to remove two tools
/obj/item/storage/belt/utility/full/PopulateContents()

View File

@@ -517,6 +517,19 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
var/homerun_able = 0
total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google
/obj/item/melee/baseball_bat/chaplain
name = "blessed baseball bat"
desc = "There ain't a cult in the league that can withstand a swatter."
force = 14
throwforce = 14
obj_flags = UNIQUE_RENAME
var/chaplain_spawnable = TRUE
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
/obj/item/melee/baseball_bat/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/melee/baseball_bat/homerun
name = "home run bat"
desc = "This thing looks dangerous... Dangerously good at baseball, that is."

View File

@@ -65,6 +65,8 @@
var/mob/M = AM
if(M.mind in immune_minds)
return
if(M.anti_magic_check())
flare()
if(charges <= 0)
return
flare()

View File

@@ -1274,7 +1274,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
ADMIN_PUNISHMENT_FAKEBWOINK,
ADMIN_PUNISHMENT_NUGGET,
ADMIN_PUNISHMENT_BREADIFY,
ADMIN_PUNISHMENT_BOOKIFY)
ADMIN_PUNISHMENT_BOOKIFY,
ADMIN_PUNISHMENT_BONK)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
@@ -1393,6 +1394,10 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
addtimer(CALLBACK(GLOBAL_PROC, .proc/bookify, target), BOOKIFY_TIME)
playsound(target, 'hyperstation/sound/misc/bookify.ogg', 60, 1)
#undef BOOKIFY_TIME
if(ADMIN_PUNISHMENT_BONK)
playsound(target, 'hyperstation/sound/misc/bonk.ogg', 100, 1)
target.AddElement(/datum/element/squish, 60 SECONDS)
to_chat(target, "<span class='warning big'>Bonk.</span>")
punish_log(target, punishment)

View File

@@ -343,8 +343,8 @@
if(QDELETED(G))
return
if(istype(C.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>Your target seems to have some sort of protective headgear on, blocking the message from being sent!</span>")
if(C.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>Your target seems to have some sort of tinfoil protection on, blocking the message from being sent!</span>")
return
G.mind_control(command, user)
@@ -520,10 +520,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
if(L.incapacitated(TRUE, TRUE))
if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>The specimen's protective headgear is interfering with the sleep inducement!</span>")
L.visible_message("<span class='danger'>[user] tried to induced sleep in [L] with [src], but [L.p_their()] headgear protected [L.p_them()]!</span>", \
"<span class='userdanger'>You feel a strange wave of heavy drowsiness wash over you, but your headgear deflects most of it!</span>")
if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>The specimen's tinfoil protection is interfering with the sleep inducement!</span>")
L.visible_message("<span class='danger'>[user] tried to induced sleep in [L] with [src], but [L.p_their()] tinfoil protected [L.p_them()]!</span>", \
"<span class='userdanger'>You feel a strange wave of heavy drowsiness wash over you, but your tinfoil protection deflects most of it!</span>")
L.drowsyness += 2
return
L.visible_message("<span class='danger'>[user] has induced sleep in [L] with [src]!</span>", \
@@ -532,10 +532,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
L.Sleeping(1200)
log_combat(user, L, "put to sleep")
else
if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>The specimen's protective headgear is completely blocking our sleep inducement methods!</span>")
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src], but [L.p_their()] headgear completely protected [L.p_them()]!</span>", \
"<span class='userdanger'>Any sense of drowsiness is quickly diminished as your headgear deflects the effects!</span>")
if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>The specimen's tinfoil protection is completely blocking our sleep inducement methods!</span>")
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src], but [L.p_their()] tinfoil completely protected [L.p_them()]!</span>", \
"<span class='userdanger'>Any sense of drowsiness is quickly diminished as your tinfoil protection deflects the effects!</span>")
return
L.drowsyness += 1
to_chat(user, "<span class='warning'>Sleep inducement works fully only on stunned specimens! </span>")

View File

@@ -178,8 +178,8 @@
c.console = src
/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
if(istype(target.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
say("Subject wearing specialized protective headgear, unable to get a proper scan!")
if(target.anti_magic_check(FALSE, FALSE, TRUE, 0))
say("Subject wearing specialized protective tinfoil gear, unable to get a proper scan!")
return
var/datum/icon_snapshot/entry = new
entry.name = target.name

View File

@@ -35,7 +35,7 @@
/obj/item/clockwork/weapon/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check() && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check(chargecost = 0) && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
var/bonus_damage = bonus_burn //normally a total of 20 damage, 30 with ratvar
if(issilicon(target))
target.visible_message("<span class='warning'>[target] shudders violently at [src]'s touch!</span>", "<span class='userdanger'>ERROR: Temperature rising!</span>")

View File

@@ -190,8 +190,8 @@
for(var/mob/living/L in range(1, src))
if(is_servant_of_ratvar(L))
continue
if(L.anti_magic_check())
var/atom/I = L.anti_magic_check()
var/atom/I = L.anti_magic_check()
if(I)
if(isitem(I))
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")

View File

@@ -60,7 +60,7 @@
else
if(isliving(target))
var/mob/living/L = target
if(!L.anti_magic_check())
if(!L.anti_magic_check(chargecost = 0))
if(isrevenant(L))
var/mob/living/simple_animal/revenant/R = L
if(R.revealed)

View File

@@ -53,7 +53,7 @@
/obj/structure/destructible/clockwork/taunting_trail/proc/affect_mob(mob/living/L)
if(istype(L) && !is_servant_of_ratvar(L))
if(!L.anti_magic_check())
if(!L.anti_magic_check(chargecost = 0))
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)

View File

@@ -62,8 +62,8 @@ Runes can either be invoked by one's self or with many different cultists. Each
if(do_after(user, 15, target = src))
to_chat(user, "<span class='notice'>You carefully erase the [lowertext(cultist_name)] rune.</span>")
qdel(src)
else if(istype(I, /obj/item/nullrod))
user.say("BEGONE FOUL MAGIKS!!", forced = "nullrod")
else if(istype(I, /obj/item/storage/book/bible) || istype(I, /obj/item/nullrod))
user.say("BEGONE FOUL MAGICKS!!", forced = "bible")
to_chat(user, "<span class='danger'>You disrupt the magic of [src] with [I].</span>")
qdel(src)
@@ -238,7 +238,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(M, "<span class='warning'>You need at least two invokers to convert [convertee]!</span>")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed
if(convertee.anti_magic_check(TRUE, TRUE, chargecost = 0)) //Not major because it can be spammed
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [convertee]'s mind!</span>")
log_game("Offer rune failed - convertee had anti-magic")
@@ -772,7 +772,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
var/atom/I = L.anti_magic_check()
var/atom/I = L.anti_magic_check(chargecost = 0)
if(I)
if(isitem(I))
to_chat(L, "<span class='userdanger'>[I] suddenly burns hotly before returning to normal!</span>")
@@ -802,7 +802,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
if(L.anti_magic_check())
if(L.anti_magic_check(chargecost = 0))
continue
L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)
if(is_servant_of_ratvar(L))

View File

@@ -65,7 +65,7 @@
if(target.anti_magic_check(FALSE, TRUE))
to_chat(src, "<span class='revenminor'>Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable!</span>")
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
"<span class='revenwarning'>Violet lights, dancing in your vision, receding--</span>")
draining = FALSE
return
var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY)
@@ -112,7 +112,8 @@
action_background_icon_state = "bg_revenant"
notice = "revennotice"
boldnotice = "revenboldnotice"
holy_check = TRUE
tinfoil_check = FALSE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0

View File

@@ -208,7 +208,7 @@
/datum/supply_pack/science/hev
name = "Hazard Suit Crate"
desc = "A familiar suit from the times of interdimensional exploring. Research Directors might prefer these due to their superior radioactive protection over the standard RD suit."
cost = 10000
cost = 15000
access = ACCESS_RD
contains = list(/obj/item/clothing/suit/space/hardsuit/rd/hev)
crate_name = "hazard suit crate"

View File

@@ -134,6 +134,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"cock_shape" = "Human",
"cock_length" = 6,
"belly_size" = 1,
"butt_size" = 1,
"cock_girth_ratio" = COCK_GIRTH_RATIO_DEF,
"cock_color" = "fff",
"has_sheath" = FALSE,
@@ -142,6 +143,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"hide_belly" = FALSE,
"inflatable_belly" = FALSE,
"belly_color" = "fff",
"has_anus" = FALSE,
"has_balls" = FALSE,
"balls_internal" = FALSE,
"balls_color" = "fff",
@@ -920,6 +922,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Inflation (Climax With):</b><a style='display:block;width:50px' href='?_src_=prefs;preference=inflatable_belly'>[features["inflatable_belly"] == 1 ? "Yes" : "No"]</a>"
dat += "</td>"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "<h3>Butt</h3>"
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_anus'>[features["has_anus"] == TRUE ? "Yes" : "No"]</a>"
if(features["has_anus"])
dat += "<b>Butt Size:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=butt_size;task=input'>[features["butt_size"]]</a>"
dat += "</td>"
dat += "</td>"
dat += "</tr></table>"
@@ -2340,6 +2350,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_bellysize)
features["belly_size"] = clamp(new_bellysize, 1, 3)
if("butt_size")
var/new_buttsize = input(user, "Butt size :\n(0-4)", "Character Preference") as num|null
features["butt_size"] = clamp(new_buttsize, 0, 4)
if("vag_shape")
var/new_shape
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
@@ -2502,6 +2516,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(features["has_vag"] == FALSE)
features["has_womb"] = FALSE
features["can_get_preg"] = FALSE
if("has_anus")
features["has_anus"] = !features["has_anus"]
if(features["has_anus"] == FALSE)
features["butt_size"] = 0
if("has_womb")
features["has_womb"] = !features["has_womb"]
if("can_get_preg")

View File

@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 23
#define SAVEFILE_VERSION_MAX 24
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -402,6 +402,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_has_sheath"] >> features["sheath_color"]
//belly size
S["feature_belly_size"] >> features["belly_size"]
//belly size
S["feature_butt_size"] >> features["butt_size"]
//balls features
S["feature_has_balls"] >> features["has_balls"]
S["feature_balls_color"] >> features["balls_color"]
@@ -423,11 +425,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//womb features
S["feature_has_womb"] >> features["has_womb"]
S["feature_can_get_preg"] >> features["can_get_preg"] //hyperstation 13
//balls features
//belly features
S["feature_has_belly"] >> features["has_belly"]
S["feature_belly_color"] >> features["belly_color"]
S["feature_hide_belly"] >> features["hide_belly"]
S["feature_inflatable_belly"] >> features["inflatable_belly"]
//anus features
S["feature_has_anus"] >> features["has_anus"]
//flavor text
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:

View File

@@ -238,26 +238,62 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
equip_delay_other = 140
var/datum/brain_trauma/mild/phobia/paranoia
var/warped = FALSE
clothing_flags = IGNORE_HAT_TOSS
/obj/item/clothing/head/foilhat/Initialize(mapload)
. = ..()
if(!warped)
AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, 6, TRUE, null, CALLBACK(src, .proc/warp_up))
else
warp_up()
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
..()
if(slot == SLOT_HEAD)
if(paranoia)
QDEL_NULL(paranoia)
paranoia = new()
user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
to_chat(user, "<span class='warning'>As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. </span>")
. = ..()
if(slot != SLOT_HEAD || warped)
return
if(paranoia)
QDEL_NULL(paranoia)
paranoia = new()
user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
to_chat(user, "<span class='warning'>As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. </span>")
/obj/item/clothing/head/foilhat/MouseDrop(atom/over_object)
//God Im sorry
if(!warped && iscarbon(usr))
var/mob/living/carbon/C = usr
if(src == C.head)
to_chat(C, "<span class='userdanger'>Why would you want to take this off? Do you want them to get into your mind?!</span>")
return
return ..()
/obj/item/clothing/head/foilhat/dropped(mob/user)
..()
. = ..()
if(paranoia)
QDEL_NULL(paranoia)
/obj/item/clothing/head/foilhat/proc/warp_up()
name = "scorched tinfoil hat"
desc = "A badly warped up hat. Quite unprobable this will still work against any of fictional and contemporary dangers it used to."
warped = TRUE
if(!isliving(loc) || !paranoia)
return
var/mob/living/target = loc
if(target.get_item_by_slot(SLOT_HEAD) != src)
return
QDEL_NULL(paranoia)
if(!target.IsUnconscious())
to_chat(target, "<span class='warning'>Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.</span>")
/obj/item/clothing/head/foilhat/attack_hand(mob/user)
if(iscarbon(user))
if(!warped && iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.head)
to_chat(user, "<span class='userdanger'>Why would you want to take this off? Do you want them to get into your mind?!</span>")
return
..()
return ..()
/obj/item/clothing/head/foilhat/microwave_act(obj/machinery/microwave/M)
. = ..()
if(!warped)
warp_up()

View File

@@ -432,7 +432,7 @@
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, FALSE)
AddComponent(/datum/component/anti_magic, TRUE, FALSE, FALSE, ITEM_SLOT_OCLOTHING, INFINITY, FALSE)
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical

View File

@@ -368,6 +368,10 @@ Contains:
resistance_flags = FIRE_PROOF
mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD)
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
name = "paranormal response team suit"
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
@@ -380,7 +384,7 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING)
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor
name = "inquisitor's hardsuit"

View File

@@ -133,6 +133,7 @@
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
if(L.anti_magic_check(check_anti_magic, check_holy))
immune += L
return
L.Stun(20, 1, 1)
frozen_mobs[L] = L.anchored

View File

@@ -64,14 +64,14 @@
var/uses = 1
if(seed)
uses = round(seed.potency / 20)
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, uses, TRUE, CALLBACK(src, .proc/block_magic), CALLBACK(src, .proc/expire)) //deliver us from evil o melon god
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_HANDS, uses, TRUE, CALLBACK(src, .proc/block_magic), CALLBACK(src, .proc/expire)) //deliver us from evil o melon god
/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/block_magic(mob/user, major)
if(major)
visible_message("<span class='warning'>[src] hums slightly, and seems to decay a bit.</span>")
to_chat(user, "<span class='warning'>[src] hums slightly, and seems to decay a bit.</span>")
/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/expire(mob/user)
visible_message("<span class='warning'>[src] rapidly turns into ash!</span>")
to_chat(user, "<span class='warning'>[src] rapidly turns into ash!</span>")
qdel(src)
new /obj/effect/decal/cleanable/ash(drop_location())

View File

@@ -12,6 +12,7 @@ Chaplain
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#dddddd"
custom_spawn_text = "You're playing a job that is essential for when the station deals with paranormal threats. While you have access to weapons, armor and tools such as your nullrod and bible, this does not mean you should hunt those threats unless warranted. If you have any questions, don't hesitate to ask mentors."
outfit = /datum/outfit/job/chaplain

View File

@@ -95,8 +95,14 @@ Doesn't work on other aliens/AI.*/
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
if(!M)
return 0
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='noticealien'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return FALSE
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...</span>[msg]")
to_chat(user, "<span class='noticealien'>You said: \"[msg]\" to [M]</span>")

View File

@@ -603,6 +603,8 @@
return FALSE
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
return FALSE
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
return FALSE
if(M in linked_mobs)
return FALSE
linked_mobs.Add(M)
@@ -688,9 +690,14 @@
var/mob/living/M = input("Select who to send your message to:","Send thought to?",null) as null|mob in options
if(!M)
return
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
var/msg = sanitize(input("Message:", "Telepathy") as text|null)
if(msg)
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
log_directed_talk(H, M, msg, LOG_SAY, "slime telepathy")
to_chat(M, "<span class='notice'>You hear an alien voice in your head... </span><font color=#008CA2>[msg]</font>")
to_chat(H, "<span class='notice'>You telepathically said: \"[msg]\" to [M]</span>")

View File

@@ -88,7 +88,7 @@
to_chat(H, "<span class='notice'>[victim] doesn't have blood!</span>")
return
V.drain_cooldown = world.time + 30
if(victim.anti_magic_check(FALSE, TRUE))
if(victim.anti_magic_check(FALSE, TRUE, FALSE, 0))
to_chat(victim, "<span class='warning'>[H] tries to bite you, but stops before touching you!</span>")
to_chat(H, "<span class='warning'>[victim] is blessed! You stop just in time to avoid catching fire.</span>")
return

View File

@@ -976,7 +976,7 @@
apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), EFFECT_IRRADIATE, blocked)
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE)
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE, chargecost = 1, self = FALSE)
. = ..()
if(.)
return

View File

@@ -804,15 +804,17 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
if(client)
client << output(null, "statbrowser:check_spells")
/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE)
if(!magic && !holy)
/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE, tinfoil = FALSE, chargecost = 1, self = FALSE)
if(!magic && !holy && !tinfoil)
return
var/list/protection_sources = list()
if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, magic, holy, protection_sources) & COMPONENT_BLOCK_MAGIC)
if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, src, magic, holy, tinfoil, chargecost, self, protection_sources) & COMPONENT_BLOCK_MAGIC)
if(protection_sources.len)
return pick(protection_sources)
else
return src
if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
return src
//You can buckle on mobs if you're next to them since most are dense
/mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)

View File

@@ -59,6 +59,9 @@
/obj/item/ammo_casing/energy/laser/redtag/hitscan
projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan
/obj/item/ammo_casing/energy/laser/redtag/hitscan/holy
projectile_type = /obj/item/projectile/beam/lasertag/redtag/hitscan/holy
/obj/item/ammo_casing/energy/xray
projectile_type = /obj/item/projectile/beam/xray
e_cost = 50

View File

@@ -159,3 +159,65 @@
/obj/item/gun/energy/laser/redtag/hitscan
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan)
/obj/item/gun/energy/laser/redtag/hitscan/chaplain
name = "\improper holy lasrifle"
desc = "A lasrifle from the old Imperium. This one seems to be blessed by techpriests."
icon_state = "LaserAK"
item_state = null
force = 14
pin = /obj/item/firing_pin/holy
icon = 'modular_citadel/icons/obj/guns/VGguns.dmi'
ammo_x_offset = 4
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan/holy)
lefthand_file = 'modular_citadel/icons/mob/citadel/guns_lefthand.dmi'
righthand_file = 'modular_citadel/icons/mob/citadel/guns_righthand.dmi'
var/chaplain_spawnable = TRUE
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
throw_speed = 3
throw_range = 4
throwforce = 10
obj_flags = UNIQUE_RENAME
/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/gun/energy/laser/redtag/hitscan/chaplain/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
return
if(semicd)
return
if(user == target)
target.visible_message("<span class='warning'>[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger...</span>", \
"<span class='userdanger'>You stick [src] in your mouth, ready to pull the trigger...</span>")
else
target.visible_message("<span class='warning'>[user] points [src] at [target]'s head, ready to pull the trigger...</span>", \
"<span class='userdanger'>[user] points [src] at your head, ready to pull the trigger...</span>")
semicd = TRUE
if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
if(user)
if(user == target)
user.visible_message("<span class='notice'>[user] decided not to shoot.</span>")
else if(target && target.Adjacent(user))
target.visible_message("<span class='notice'>[user] has decided to spare [target]</span>", "<span class='notice'>[user] has decided to spare your life!</span>")
semicd = FALSE
return
semicd = FALSE
target.visible_message("<span class='warning'>[user] pulls the trigger!</span>", "<span class='userdanger'>[user] pulls the trigger!</span>")
playsound('sound/weapons/dink.ogg', 30, 1)
if((iscultist(target)) || (is_servant_of_ratvar(target)))
chambered.BB.damage *= 1500
else if(chambered && chambered.BB)
chambered.BB.damage *= 5
process_fire(target, user, TRUE, params)

View File

@@ -9,6 +9,7 @@
fire_sound = 'sound/weapons/emitter.ogg'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_HUGE
var/checks_antimagic = FALSE
var/max_charges = 6
var/charges = 0
var/recharge_rate = 4
@@ -31,6 +32,9 @@
return
else
no_den_usage = 0
if(checks_antimagic && user.anti_magic_check(TRUE, FALSE, FALSE, 0, TRUE))
to_chat(user, "<span class='warning'>Something is interfering with [src].</span>")
return
. = ..()
/obj/item/gun/magic/can_shoot()

View File

@@ -87,14 +87,17 @@
max_charges = 10 //10, 5, 5, 4
/obj/item/gun/magic/wand/resurrection/zap_self(mob/living/user)
..()
charges--
if(user.anti_magic_check())
user.visible_message("<span class='warning'>[src] has no effect on [user]!</span>")
return
user.revive(full_heal = 1)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.regenerate_limbs()
C.regenerate_organs()
to_chat(user, "<span class='notice'>You feel great!</span>")
charges--
..()
/obj/item/gun/magic/wand/resurrection/debug //for testing
name = "debug wand of healing"

View File

@@ -186,6 +186,15 @@
desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link. It has a small explosive charge on it."
selfdestruct = TRUE
/obj/item/firing_pin/holy
name = "blessed pin"
desc = "A firing pin that only responds to those who are holier than thou."
/obj/item/firing_pin/holy/pin_auth(mob/living/user)
if(user.mind.isholy)
return TRUE
return FALSE
// Laser tag pins
/obj/item/firing_pin/tag
name = "laser tag firing pin"

View File

@@ -151,6 +151,11 @@
/obj/item/projectile/beam/lasertag/redtag/hitscan
hitscan = TRUE
/obj/item/projectile/beam/lasertag/redtag/hitscan/holy
name = "lasrifle beam"
damage = 0.1
damage_type = BURN
/obj/item/projectile/beam/lasertag/bluetag
icon_state = "bluelaser"
suit_types = list(/obj/item/clothing/suit/redtag)

View File

@@ -93,7 +93,7 @@
/datum/design/medkit
name = "Medkit Cabinent"
name = "Medkit Cabinet"
id = "medkit_cabinet"
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 4000)

View File

@@ -483,6 +483,16 @@
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/ranged_analyzer
name = "Long-range Analyzer"
desc = "A new advanced atmospheric analyzer design, capable of performing scans at long range."
id = "ranged_analyzer"
build_type = PROTOLATHE
materials = list(MAT_METAL = 400, MAT_GLASS = 1000, MAT_URANIUM = 800, MAT_GOLD = 200, MAT_PLASTIC = 200)
build_path = /obj/item/analyzer/ranged
category = list("Equipment")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
/datum/design/rcd_loaded
name = "Rapid Construction Device (RCD)"
desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly."

View File

@@ -636,7 +636,7 @@
id = "exp_tools"
display_name = "Experimental Tools"
description = "Highly advanced construction tools."
design_ids = list("exwelder", "jawsoflife", "handdrill")
design_ids = list("exwelder", "jawsoflife", "handdrill", "ranged_analyzer")
prereq_ids = list("adv_engi")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750)
export_price = 5000

View File

@@ -115,6 +115,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/nonabstract_req = 0 //spell can only be cast by mobs that are physical entities
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/phase_allowed = 0 // If true, the spell can be cast while phased, eg. blood crawling, ethereal jaunting
var/antimagic_allowed = TRUE // If false, the spell cannot be cast while under the effect of antimagic
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
var/invocation_emote_self = null
var/invocation_type = "none" //can be none, whisper, emote and shout
@@ -147,27 +148,36 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(player_lock)
if(!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list))
to_chat(user, "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>")
return 0
return FALSE
else
if(!(src in user.mob_spell_list))
return 0
return FALSE
var/turf/T = get_turf(user)
if(is_centcom_level(T.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
to_chat(user, "<span class='notice'>You can't cast this spell here.</span>")
return 0
return FALSE
if(!skipcharge)
if(!charge_check(user))
return 0
return FALSE
if(user.stat && !stat_allowed)
to_chat(user, "<span class='notice'>Not when you're incapacitated.</span>")
return 0
return FALSE
if(!antimagic_allowed)
var/antimagic = user.anti_magic_check(TRUE, FALSE, chargecost = 0, self = TRUE)
if(antimagic)
if(isitem(antimagic))
to_chat(user, "<span class='notice'>[antimagic] is interfering with your magic.</span>")
else
to_chat(user, "<span class='notice'>Magic seems to flee from you, you can't gather enough power to cast this spell.</span>")
return FALSE
if(!phase_allowed && istype(user.loc, /obj/effect/dummy))
to_chat(user, "<span class='notice'>[name] cannot be cast unless you are completely manifested in the material plane.</span>")
return 0
return FALSE
if(ishuman(user))
@@ -175,7 +185,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if((invocation_type == "whisper" || invocation_type == "shout") && !H.can_speak_vocal())
to_chat(user, "<span class='notice'>You can't get the words out!</span>")
return 0
return FALSE
var/list/casting_clothes = typecacheof(list(/obj/item/clothing/suit/wizrobe,
/obj/item/clothing/suit/space/hardsuit/wizard,
@@ -187,24 +197,24 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(clothes_req) //clothes check
if(!is_type_in_typecache(H.wear_suit, casting_clothes))
to_chat(H, "<span class='notice'>I don't feel strong enough without my robe.</span>")
return 0
return FALSE
if(!is_type_in_typecache(H.head, casting_clothes))
to_chat(H, "<span class='notice'>I don't feel strong enough without my hat.</span>")
return 0
return FALSE
if(cult_req) //CULT_REQ CLOTHES CHECK
if(!istype(H.wear_suit, /obj/item/clothing/suit/magusred) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/cult))
to_chat(H, "<span class='notice'>I don't feel strong enough without my armor.</span>")
return 0
return FALSE
if(!istype(H.head, /obj/item/clothing/head/magus) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/cult))
to_chat(H, "<span class='notice'>I don't feel strong enough without my helmet.</span>")
return 0
return FALSE
else
if(clothes_req || human_req)
to_chat(user, "<span class='notice'>This spell can only be cast by humans!</span>")
return 0
return FALSE
if(nonabstract_req && (isbrain(user) || ispAI(user)))
to_chat(user, "<span class='notice'>This spell can only be cast by physical beings!</span>")
return 0
return FALSE
if(!skipcharge)
@@ -499,6 +509,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(user.stat && !stat_allowed)
return FALSE
if(!antimagic_allowed && user.anti_magic_check(TRUE, FALSE, chargecost = 0, self = TRUE))
return FALSE
if(!ishuman(user))
if(clothes_req || human_req)
return FALSE

View File

@@ -35,6 +35,6 @@
return TRUE
if(ismob(mover))
var/mob/M = mover
if(M.anti_magic_check())
if(M.anti_magic_check(chargecost = 0))
return TRUE
return FALSE

View File

@@ -86,7 +86,7 @@
/obj/effect/cross_action/spacetime_dist/proc/walk_link(atom/movable/AM)
if(ismob(AM))
var/mob/M = AM
if(M.anti_magic_check())
if(M.anti_magic_check(chargecost = 0))
return
if(linked_dist && walks_left > 0)
flick("purplesparkles", src)

View File

@@ -10,9 +10,11 @@
action_background_icon_state = "bg_spell"
var/notice = "notice"
var/boldnotice = "boldnotice"
var/magic_check = TRUE
var/magic_check = FALSE
var/holy_check = FALSE
var/tinfoil_check = TRUE
/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/user = usr)
for(var/mob/living/M in targets)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
@@ -20,11 +22,11 @@
return
log_directed_talk(user, M, msg, LOG_SAY, "[name]")
to_chat(user, "<span class='[boldnotice]'>You transmit to [M]:</span> <span class='[notice]'>[msg]</span>")
if(!magic_check || !M.anti_magic_check(FALSE, TRUE)) //hear no evil
if(!M.anti_magic_check(magic_check, holy_check, tinfoil_check, 0)) //hear no evil
to_chat(M, "<span class='[boldnotice]'>You hear something behind you talking...</span> <span class='[notice]'>[msg]</span>")
for(var/ded in GLOB.dead_mob_list)
if(!isobserver(ded))
continue
var/follow_rev = FOLLOW_LINK(ded, user)
var/follow_whispee = FOLLOW_LINK(ded, M)
to_chat(ded, "[follow_rev] <span class='[boldnotice]'>[user] [name]:</span> <span class='[notice]'>\"[msg]\" to</span> [follow_whispee] <span class='name'>[M]</span>")
to_chat(ded, "[follow_rev] <span class='[boldnotice]'>[user] [name]:</span> <span class='[notice]'>\"[msg]\" to</span> [follow_whispee] <span class='name'>[M]</span>")

View File

@@ -1,14 +1,14 @@
/mob/living/simple_animal/hostile/hs13mimic
name = "Mimic"
icon = 'hyperstation/icons/mobs/mimic.dmi'
desc = "What the fuck is that?"
desc = "A writhing mass of black flesh, unlikely to be happy to see you."
icon_state = "mimic"
icon_living = "mimic"
icon_dead = "mimic_dead"
gender = NEUTER
speak_chance = 0
maxHealth = 38
health = 38
maxHealth = 35
health = 35
turns_per_move = 5
move_to_delay = 1
speed = 0
@@ -21,14 +21,14 @@
response_harm = "smacks"
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "glomps"
attack_sound = 'sound/effects/blobattack.ogg'
attacktext = "stings"
attack_sound = 'hyperstation/sound/creatures/mimic/mimic_attack.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
ventcrawler = VENTCRAWLER_ALWAYS
blood_volume = 0
faction = list("mimic")
gold_core_spawnable = NO_SPAWN
vision_range = 2
vision_range = 1
aggro_vision_range = 9
wander = TRUE
minbodytemp = 250 //weak to cold
@@ -43,6 +43,7 @@
/obj/item/projectile,
/obj/item/radio/intercom,
/mob/living/simple_animal/bot))
var/transformsound = 'hyperstation/sound/creatures/mimic/mimic_transform.ogg'
var/playstyle_string = "<span class='boldannounce'>You are a mimic</span></b>, a tricky creature that can take the form of \
almost any item nearby by shift-clicking it. While morphed, you move slowly and do less damage. \
Finally, you can restore yourself to your original form while morphed by shift-clicking yourself. \
@@ -139,10 +140,10 @@
icon_state = "yellow"
desc = "These gloves will protect the wearer from electric shock."
if(21 to 30)
name = "Private Security Officer"
desc = "A cardboard cutout of a private security officer."
icon = 'icons/obj/cardboard_cutout.dmi'
icon_state = "cutout_ntsec"
name = "stunbaton"
desc = "A stun baton for incapacitating people with."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "stunbaton"
if(31 to 40)
name = "pen"
icon = 'icons/obj/bureaucracy.dmi'
@@ -154,10 +155,10 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "newspaper"
if(51 to 60)
name = "toolbox"
desc = "Danger. Very robust."
icon = 'icons/obj/storage.dmi'
icon_state = "red"
name = "stechkin pistol" //greytider bait
desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "pistol"
if(61 to 70)
name = "emergency oxygen tank"
desc = "Used for emergencies. Contains very little oxygen, so try to conserve it until you actually need it."
@@ -212,7 +213,7 @@
if(stealthed && stat == CONSCIOUS)
visible_message("<span class='danger'>The [src] Reveals itself to be a Mimic!</span>")
restore()
playsound(loc, 'hyperstation/sound/creatures/mimictransform.ogg', 75, TRUE)
playsound(loc, transformsound, 75, TRUE)
triggerOthers(target) // Friends too!
/mob/living/simple_animal/hostile/hs13mimic/proc/triggerOthers(passtarget) //
@@ -242,6 +243,48 @@
/mob/living/simple_animal/hostile/hs13mimic/proc/allowed(atom/movable/A)
return !is_type_in_typecache(A, mimic_blacklisted_transform_items) && (isitem(A) || isanimal(A))
//One leader mimic spawns per mimic event spawn, they are able to consume and transform themselves into the station's dead pets. Buckle up.
/mob/living/simple_animal/hostile/hs13mimic/leader
var/mob/living/consumptionTarget = null
var/consuming = FALSE
health = 38 //They have a teeeny tiny more health.
maxHealth = 38
/mob/living/simple_animal/hostile/hs13mimic/leader/Life()
. = ..()
if(!consuming)
if(!consumptionTarget)
for(var/mob/living/simple_animal/pet/A in oview(5, src))
if(A.stat == DEAD)
consumptionTarget = A
break
if(!target && consumptionTarget) //Don't try to consume anything if we're currently attacking something.
var/target_distance = get_dist(targets_from, consumptionTarget)
if(target_distance > minimum_distance)
Goto(consumptionTarget,move_to_delay,minimum_distance)
else
tryConsume(consumptionTarget)
/mob/living/simple_animal/hostile/hs13mimic/leader/proc/tryConsume(var/mob/living/simple_animal/pet/A)
src.visible_message("<span class='warning'>[A] is being consumed...</span>",
"<span class='notice'>You start to consume the dead [A]...</span>", "You hear strange fleshy sounds.")
consuming = TRUE
if(do_after(src, 100, target = A))
stealthed = TRUE
speed = 5
wander = TRUE
name = A.name
desc = A.desc
icon = A.icon
icon_state = A.icon_living
desc += "<span class='warning'> But something about it seems wrong...</span>"
qdel(A)
consuming = FALSE
consumptionTarget = FALSE
return TRUE
consuming = FALSE
return FALSE
//Player control code
/mob/living/simple_animal/hostile/hs13mimic/ShiftClickOn(atom/movable/A)
@@ -252,7 +295,7 @@
return
if(istype(A) && allowed(A))
stealthed = TRUE
SEND_SOUND(src, sound('hyperstation/sound/creatures/mimictransform.ogg',volume=50))
SEND_SOUND(src, sound(transformsound,volume=50))
name = A.name
icon = A.icon
icon_state = A.icon_state
@@ -297,6 +340,7 @@
/area/asteroid/nearstation,
/area/science/server,
/area/science/explab,
/area/science/xenobiology,
/area/security/processing)
var/spawncount = 1
fakeable = FALSE
@@ -359,8 +403,12 @@
notify_ghosts("A group of mimics has spawned in [pickedArea]!", source=pickedArea, action=NOTIFY_ATTACK, flashwindow = FALSE)
while(spawncount > 0 && validTurfs.len)
var/turf/pickedTurf = pick_n_take(validTurfs)
var/spawn_type = /mob/living/simple_animal/hostile/hs13mimic
spawn_atom_to_turf(spawn_type, pickedTurf, 1, FALSE)
spawncount--
var/turf/pickedTurf = pick_n_take(validTurfs)
if(spawncount != 0)
var/spawn_type = /mob/living/simple_animal/hostile/hs13mimic
spawn_atom_to_turf(spawn_type, pickedTurf, 1, FALSE)
else
var/spawn_type = /mob/living/simple_animal/hostile/hs13mimic/leader
spawn_atom_to_turf(spawn_type, pickedTurf, 1, FALSE)
return SUCCESSFUL_SPAWN

View File

@@ -9,8 +9,9 @@
var/mob/living/carbon/U = user
for(var/obj/item/organ/genital/G in U.internal_organs)
if(!G.dontlist)
dat += "<a href='byond://?src=[REF(src)];hide[G.name]=1'>[G.mode == "hidden" ? "[G.name] <font color='red'>(Hidden)</font>" : (G.mode == "clothes" ? "[G.name] <font color='yellow'>(Hidden by Clothes)</font>" : (G.mode == "visable" ? "[G.name] <font color='green'>(Visable)</font>" : "[G.name] <font color='green'>(Visable)</font>"))]</a><BR>"
if(!G.nochange)
if(!G.dontlist)
dat += "<a href='byond://?src=[REF(src)];hide[G.name]=1'>[G.mode == "hidden" ? "[G.name] <font color='red'>(Hidden)</font>" : (G.mode == "clothes" ? "[G.name] <font color='yellow'>(Hidden by Clothes)</font>" : (G.mode == "visable" ? "[G.name] <font color='green'>(Visable)</font>" : "[G.name] <font color='green'>(Visable)</font>"))]</a><BR>"
dat += {"<BR><B>Contexual Options</B><BR><HR>"}
var/obj/item/organ/genital/penis/P = user.getorganslot("penis")
@@ -237,6 +238,13 @@
usr.put_in_hands(I)
O.equipment = null
if(href_list["removeequipmentanus"])
var/obj/item/organ/genital/anus/O = usr.getorganslot("anus")
var/obj/item/I = O.equipment
usr.put_in_hands(I)
O.equipment = null
if(href_list["omenu"])
usr << browse(null, "window=arousal") //closes the window
H.mob_climax()

View File

@@ -100,7 +100,7 @@
/obj/item/portallight/examine(mob/user)
. = ..()
if(!portalunderwear)
. += "<span class='notice'>The device is unpaired, to pair, swipe against a pair of portal panties(TM). </span>"
. += "<span class='notice'>The device is unpaired, to pair, swipe against a pair of portal panties. </span>"
else
. += "<span class='notice'>The device is paired, and awaiting input. </span>"
@@ -117,12 +117,12 @@
else
option = "Fuck"
var/obj/item/organ/genital/vagina/V
if(istype(portalunderwear.loc, /obj/item/organ/genital/vagina)) //Sanity check. Without this it will runtime.
V = portalunderwear.loc
if(!V)
var/obj/item/organ/genital/G
if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime error.
G = portalunderwear.loc
if(!G)
return
var/mob/living/carbon/human/M = V.owner
var/mob/living/carbon/human/M = G.owner
if(option == "Fuck"&&!P.is_exposed()) //we are trying to fuck with no penis!
to_chat(user, "<span class='notice'>You don't see anywhere to use this on.</span>")
@@ -156,7 +156,7 @@
M.emote("moan")
if(option == "Fuck")// normal fuck
to_chat(M, "<span class='love'>You feel a [P.shape] shaped penis pumping through the portal into your vagina.</span>")//message your partner and kinky!
to_chat(M, "<span class='love'>You feel a [P.length] inch, [P.shape] shaped penis pumping through the portal into your [G.name].</span>")//message your partner, and kinky!
if(prob(30)) //30% chance to make them moan.
C.emote("moan")
if(prob(30)) //30% chance to make your partner moan.
@@ -166,10 +166,10 @@
M.do_jitter_animation() //make your partner shake too!
if (M.getArousalLoss() >= 100 && ishuman(M) && prob(5))//Why not have a probability to cum when someone's getting nailed with max arousal?~
if(V.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
M.mob_climax_outside(V, spillage = TRUE)
if(G.is_exposed()) //Oh yea, if vagina is not exposed, the climax will not cause a spill
M.mob_climax_outside(G, spillage = TRUE)
else
M.mob_climax_outside(V, spillage = FALSE)
M.mob_climax_outside(G, spillage = FALSE)
if (C.getArousalLoss() >= 100 && ishuman(C) && C.has_dna())
var/mob/living/carbon/human/O = C
@@ -180,10 +180,10 @@
O.mob_climax_partner(P, M, FALSE, TRUE, FALSE, TRUE) //climax with their partner remotely, and impreg because people keep asking!
if(option == "Lick")
to_chat(M, "<span class='love'>You feel a tongue lick you through the portal against your vagina.</span>")
to_chat(M, "<span class='love'>You feel a tongue lick you through the portal against your [G.name].</span>")
M.adjustArousalLoss(10)
if(option == "Touch")
to_chat(M, "<span class='love'>You feel someone touching your vagina through the portal.</span>")
to_chat(M, "<span class='love'>You feel someone touching your [G.name] through the portal.</span>")
M.adjustArousalLoss(5)
return
@@ -193,13 +193,14 @@
//get their looks and vagina colour!
cut_overlays()//remove current overlays
var/obj/item/organ/genital/vagina/V
if(istype(portalunderwear.loc, /obj/item/organ/genital/vagina)) //Sanity check. Without this it will runtime.
V = portalunderwear.loc
if(!V)
var/obj/item/organ/genital/G
if(istype(portalunderwear.loc, /obj/item/organ/genital)) //Sanity check. Without this it will runtime.
G = portalunderwear.loc
if(!G)
useable = FALSE
return
var/mob/living/carbon/human/H = V.owner
var/mob/living/carbon/human/H = G.owner
if(H) //if the portal panties are on someone.
sleeve = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_sleeve_normal")
@@ -215,8 +216,12 @@
sleeve.color = "#" + H.dna.features["mcolor"]
add_overlay(sleeve)
organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
organ.color = portalunderwear.loc.color
if(G.name == "vagina")
organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_vag")
organ.color = portalunderwear.loc.color
if(G.name == "anus")
organ = mutable_appearance('hyperstation/icons/obj/fleshlight.dmi', "portal_anus")
organ.color = "#" + H.dna.features["mcolor"]
useable = TRUE
add_overlay(organ)
@@ -224,7 +229,7 @@
useable = FALSE
//Hyperstation 13 portal underwear
//can be attached to vagina, just like the vibrator, still requires pairing with the portallight
//can be attached to vagina or anus, just like the vibrator, still requires pairing with the portallight
/obj/item/portalpanties
name = "portal panties"
@@ -235,6 +240,7 @@
w_class = WEIGHT_CLASS_SMALL
var/obj/item/portallight
var/attached = FALSE
var/shapetype = "vagina"
/obj/item/portalpanties/examine(mob/user)
. = ..()
@@ -267,33 +273,34 @@
var/obj/item/organ/genital/picked_organ
var/mob/living/carbon/human/S = user
var/mob/living/carbon/human/T = C
picked_organ = S.target_genitals(T) //allowing to pick organ for anus down the line
picked_organ = S.target_genitals(T)
if(picked_organ)
C.visible_message("<span class='warning'>[user] is trying to attach [src] to [T]!</span>",\
"<span class='warning'>[user] is trying to put [src] on you!</span>")
if(!do_mob(user, C, 5 SECONDS))//warn them and have a delay of 5 seconds to apply.
if(!do_mob(user, C, 3 SECONDS))//warn them and have a delay of 5 seconds to apply.
return
if(!(picked_organ.name == "vagina")) //only fits on a vagina
to_chat(user, "<span class='warning'>[src] can only be attached to a vagina.</span>")
return
if((picked_organ.name == "vagina")||(picked_organ.name == "anus")) //only fits on a vagina or anus
if(!picked_organ.equipment)
to_chat(user, "<span class='love'>You wrap [src] around [T]'s [picked_organ.name].</span>")
src.shapetype = picked_organ.name
if(!picked_organ.equipment)
to_chat(user, "<span class='love'>You wrap [src] around [T]'s [picked_organ.name].</span>")
else
to_chat(user, "<span class='notice'>They already have [picked_organ.equipment.name] there.</span>")
return
if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
return
src.attached = TRUE
picked_organ.equipment = src
var/obj/item/portallight/P = portallight
//now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
if(P) //just to make sure
P.updatesleeve()
else
to_chat(user, "<span class='notice'>They already have a [picked_organ.equipment.name] there.</span>")
to_chat(user, "<span class='warning'>[src] can only be attached to a vagina or anus.</span>")
return
if(!user.transferItemToLoc(src, picked_organ)) //check if you can put it in
return
src.attached = TRUE
picked_organ.equipment = src
var/obj/item/portallight/P = portallight
//now we need to send what they look like, but saddly if the person changes colour for what ever reason, it wont update. but dont tell people shh.
if(P) //just to make sure
P.updatesleeve()
else
to_chat(user, "<span class='notice'>You don't see anywhere to attach this.</span>")

View File

@@ -86,6 +86,7 @@ obj/item/clothing/neck/stole/black
item_state = "r_suit"
can_adjust = FALSE
mutantrace_variation = NO_MUTANTRACE_VARIATION
do_not_cover_butt = TRUE
/obj/item/clothing/under/sexynursesuit
name = "Sexy nurse outfit"

View File

@@ -115,12 +115,10 @@ Code:
if(G)
switch(G.name) //just being fancy
if("penis")
to_chat(U, "<span class='love'>[src] vibrates against your [G.name]!</span>")
if("breasts")
to_chat(U, "<span class='love'>[src] vibrates against your nipples!</span>")
if("vagina")
to_chat(U, "<span class='love'>[src] vibrates inside you!</span>")
else
to_chat(U, "<span class='love'>[src] vibrates against your [G.name]!</span>")
var/intencity = 6*mode
U.adjustArousalLoss(intencity) //give pleasure

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -30,24 +30,16 @@
"<span class='info'>You kneel[M == user ? null : " next to [M]"] and begin a prayer to [deity_name].</span>")
praying = TRUE
if(do_after(user, 100, target = M))
if(do_after(user, 20, target = M))
if(istype(M, /mob/living/carbon/human)) // This probably should not work on catpeople. They're unholy abominations.
var/mob/living/carbon/human/target = M
if(iscultist(M) || is_servant_of_ratvar(M)) //ripped from holywater code.
if(iscultist(M))
SSticker.mode.remove_cultist(M.mind, FALSE, TRUE)
else if(is_servant_of_ratvar(M))
remove_servant_of_ratvar(M)
M.reagents.add_reagent("holywater", 5)
to_chat(target, "<span class='notice'>[user]'s prayer to [deity_name] has eased your pain!</span>")
target.adjustToxLoss(-5, TRUE, TRUE)
target.adjustOxyLoss(-5)
target.adjustBruteLoss(-5)
target.adjustFireLoss(-5)
praying = FALSE
else
to_chat(user, "<span class='notice'>Your prayer to [deity_name] was interrupted.</span>")
praying = FALSE

View File

@@ -275,7 +275,7 @@
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
return FALSE

View File

@@ -78,6 +78,9 @@
amt_nude++
if(getorganslot("vagina"))
amt_nude++
if(is_butt_exposed())
if(getorganslot("anus"))
amt_nude++
if(amt_nude)
var/watchers = 0
for(var/mob/_M in view(world.view, src))
@@ -321,7 +324,7 @@
src.visible_message("<span class='love'>[src] orgasms with [p_their()] [G.name]!</span>", \
"<span class='userlove'>You climax with your [G.name].</span>", \
"<span class='userlove'>You climax using your [G.name].</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
if(G.can_climax)
setArousalLoss(min_arousal)
@@ -522,10 +525,9 @@
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in T.internal_organs)
if(G.can_climax) //filter out what you can't masturbate with
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
if(!G.dontlist)
genitals_list += G
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
if(!G.dontlist)
genitals_list += G
if(genitals_list.len)
ret_organ = input(src, "", "Genitals", null) as null|obj in genitals_list
return ret_organ

View File

@@ -0,0 +1,36 @@
/obj/item/organ/genital/anus
name = "anus"
desc = "You see a butt."
icon_state = "butt"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
zone = "anus"
slot = "anus"
w_class = 3
size = 0
var/statuscheck = FALSE
shape = "Pair"
masturbation_verb = "massage"
can_climax = FALSE
/obj/item/organ/genital/anus/on_life()
if(QDELETED(src))
return
if(!owner)
return
/obj/item/organ/genital/anus/update_appearance()
var/string
if(owner)
var/mob/living/carbon/human/H = owner
color = "#[skintone2hex(H.skin_tone)]"
if(ishuman(owner))
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)

View File

@@ -25,6 +25,7 @@
var/mode = "clothes"
var/obj/item/equipment //for fun stuff that goes on the gentials/maybe rings down the line
var/dontlist = FALSE
var/nochange = FALSE //stops people changing visablity.
/obj/item/organ/genital/Initialize()
. = ..()
@@ -67,6 +68,8 @@
return owner.is_chest_exposed()
if("groin")
return owner.is_groin_exposed()
if("anus")
return owner.is_butt_exposed()
return FALSE
@@ -150,6 +153,8 @@
if (NOGENITALS in dna.species.species_traits)
return
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
if(dna.features["has_anus"])
give_anus()
if(dna.features["has_vag"])
give_vagina()
if(dna.features["has_womb"])
@@ -239,6 +244,20 @@
if(dna.features["inflatable_belly"]) //autohide bellies if they have the option ticked.
B.inflatable = TRUE
/mob/living/carbon/human/proc/give_anus()
if(!dna)
return FALSE
if(NOGENITALS in dna.species.species_traits)
return FALSE
if(!getorganslot("anus"))
var/obj/item/organ/genital/anus/A = new
if(dna.features["butt_size"])
A.size = dna.features["butt_size"]
A.Insert(src)
if(A)
A.color = "#[skintone2hex(skin_tone)]"
A.update()
/mob/living/carbon/human/proc/give_breasts()
@@ -426,6 +445,8 @@
S = GLOB.breasts_shapes_list[G.shape]
if(/obj/item/organ/genital/belly)
S = GLOB.breasts_shapes_list[G.shape]
if(/obj/item/organ/genital/anus)
S = GLOB.breasts_shapes_list[G.shape]
if(!S || S.icon_state == "none")
continue
@@ -444,11 +465,24 @@
//Get the icon
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
colourcode = S.color_src
if(G.slot == "belly") //we have a different size system
genital_overlay.icon = 'hyperstation/icons/obj/genitals/belly.dmi'
genital_overlay.icon_state = "belly_[size]"
colourcode = "belly_color"
if(G.slot == "anus") //we have a different size system
genital_overlay.icon = 'hyperstation/icons/obj/genitals/butt.dmi'
genital_overlay.icon_state = "butt_[size]"
genital_overlay.layer = -FRONT_MUTATIONS_LAYER
colourcode = "butt_color"
if(use_skintones) //butts are forced a colour, either skin tones, or main colour. how ever, mutants use a darker version, because of their body tone.
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
genital_overlay.icon_state = "butt_[size]"
else
genital_overlay.color = "#[H.dna.features["mcolor"]]"
genital_overlay.icon_state = "butt_[size]_m"
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
@@ -471,6 +505,7 @@
if("belly_color")
genital_overlay.color = "#[H.dna.features["belly_color"]]"
standing += genital_overlay
if(LAZYLEN(standing))

View File

@@ -136,7 +136,7 @@
icon_state = "gaping"
name = "Gaping"
//BREASTS BE HERE
//BELLY BE HERE
/datum/sprite_accessory/belly
icon = 'hyperstation/icons/obj/genitals/belly.dmi'
icon_state = "belly"
@@ -145,6 +145,15 @@
color_src = "belly_color"
locked = 0
//BUTT BE HERE
/datum/sprite_accessory/anus
icon = 'hyperstation/icons/obj/genitals/butt.dmi'
icon_state = "butt"
name = "butt"
gender_specific = 0
color_src = "butt_color"
locked = 0
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'

View File

@@ -63,6 +63,8 @@
WRITE_FILE(S["feature_has_sheath"], features["sheath_color"])
//belly feature
WRITE_FILE(S["feature_belly_size"], features["belly_size"])
//butt feature
WRITE_FILE(S["feature_butt_size"], features["butt_size"])
//balls features
WRITE_FILE(S["feature_has_balls"], features["has_balls"])
WRITE_FILE(S["feature_balls_color"], features["balls_color"])
@@ -96,6 +98,8 @@
WRITE_FILE(S["feature_belly_color"], features["belly_color"])
WRITE_FILE(S["feature_hide_belly"], features["hide_belly"])
WRITE_FILE(S["feature_inflatable_belly"], features["inflatable_belly"])
//anus
WRITE_FILE(S["feature_has_anus"], features["has_anus"])
//gear loadout
if(islist(chosen_gear))

View File

@@ -144,6 +144,7 @@
primary_color = "#FFFFFF" //RGB in hexcode
secondary_color = "#8CC6FF"
body_parts_covered = GROIN
do_not_cover_butt = TRUE
/obj/item/clothing/under/polychromic/bottomless
name = "polychromic bottomless shirt"
@@ -177,6 +178,7 @@
primary_color = "#808080" //RGB in hexcode
secondary_color = "#FFFFFF"
body_parts_covered = CHEST|GROIN
do_not_cover_butt = TRUE
/obj/item/clothing/under/polychromic/stripper
name = "polychromic stripper outfit"
@@ -188,6 +190,7 @@
primary_color = "#808080" //RGB in hexcode
secondary_color = "#FFFFFF"
body_parts_covered = CHEST|GROIN
do_not_cover_butt = TRUE
/obj/item/clothing/under/polychromic/bulge
name = "polychromic voluminous thong"
@@ -199,6 +202,7 @@
primary_color = "#808080" //RGB in hexcode
secondary_color = "#FF3535"
body_parts_covered = GROIN
do_not_cover_butt = TRUE
/obj/item/clothing/under/polychromic/shortsbra
name = "Kromatic Shorts and Top"
@@ -231,4 +235,5 @@
primary_color = "#010052" //RGB in hexcode
secondary_color = "#eb7a7a"
tertiary_color = "#ffffff"
body_parts_covered = CHEST|GROIN
body_parts_covered = CHEST|GROIN
do_not_cover_butt = TRUE

View File

@@ -476,6 +476,7 @@
#include "code\datums\elements\flavor_text.dm"
#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\elements\mob_holder.dm"
#include "code\datums\elements\squish.dm"
#include "code\datums\elements\swimming.dm"
#include "code\datums\elements\wuv.dm"
#include "code\datums\helper_datums\events.dm"
@@ -3238,6 +3239,7 @@
#include "modular_citadel\code\modules\admin\holder2.dm"
#include "modular_citadel\code\modules\admin\secrets.dm"
#include "modular_citadel\code\modules\arousal\arousal.dm"
#include "modular_citadel\code\modules\arousal\organs\anus.dm"
#include "modular_citadel\code\modules\arousal\organs\belly.dm"
#include "modular_citadel\code\modules\arousal\organs\breasts.dm"
#include "modular_citadel\code\modules\arousal\organs\eggsack.dm"