This commit is contained in:
Jerry Wester
2023-01-20 17:10:49 -07:00
340 changed files with 3205 additions and 2267 deletions
@@ -997,14 +997,14 @@
/turf/open/floor/plasteel/freezer,
/area/mine/living_quarters)
"qh" = (
/obj/structure/sink{
dir = 8;
pixel_x = 11
},
/obj/effect/turf_decal/tile/bar,
/obj/effect/turf_decal/tile/bar{
dir = 1
},
/obj/structure/sink{
dir = 4;
pixel_x = 12
},
/turf/open/floor/plasteel,
/area/mine/living_quarters)
"qm" = (
@@ -2504,13 +2504,13 @@
/turf/open/floor/plasteel/white,
/area/mine/laborcamp)
"Mj" = (
/obj/structure/sink{
dir = 4;
pixel_x = -12
},
/obj/structure/mirror{
pixel_x = -28
},
/obj/structure/sink{
dir = 8;
pixel_x = -12
},
/turf/open/floor/plasteel/freezer,
/area/mine/living_quarters)
"Mk" = (
+35 -32
View File
@@ -91,13 +91,13 @@
},
/area/holodeck/rec_center/lounge)
"ap" = (
/turf/open/floor/holofloor/plating,
/turf/open/floor/holofloor/basalt,
/area/holodeck/rec_center/wildlife)
"aq" = (
/turf/open/floor/holofloor/plating,
/area/holodeck/rec_center/offline)
"ar" = (
/turf/open/floor/holofloor/plating/burnmix,
/turf/open/indestructible/binary,
/area/holodeck/rec_center/burn)
"as" = (
/obj/effect/turf_decal/tile/red{
@@ -178,12 +178,12 @@
},
/area/holodeck/rec_center/lounge)
"aB" = (
/obj/effect/holodeck_effect/mobspawner,
/turf/open/floor/holofloor/plating,
/obj/effect/holodeck_effect/mobspawner/funclaw,
/turf/open/floor/holofloor/basalt,
/area/holodeck/rec_center/wildlife)
"aC" = (
/obj/effect/holodeck_effect/sparks,
/turf/open/floor/holofloor/plating/burnmix,
/turf/open/indestructible/binary,
/area/holodeck/rec_center/burn)
"aD" = (
/obj/effect/turf_decal/tile/red{
@@ -413,7 +413,7 @@
/turf/closed/indestructible/riveted,
/area/space)
"bk" = (
/obj/effect/holodeck_effect/mobspawner/bee,
/obj/effect/holodeck_effect/mobspawner/bumbles,
/turf/open/floor/holofloor/asteroid,
/area/holodeck/rec_center/anthophila)
"bl" = (
@@ -752,7 +752,7 @@
},
/area/holodeck/rec_center/medical)
"ce" = (
/obj/effect/holodeck_effect/mobspawner/bee,
/obj/effect/holodeck_effect/mobspawner/bumbles,
/obj/item/clothing/head/beekeeper_head,
/turf/open/floor/holofloor/asteroid,
/area/holodeck/rec_center/anthophila)
@@ -856,13 +856,13 @@
/turf/open/floor/holofloor,
/area/holodeck/rec_center/dodgeball)
"cq" = (
/obj/effect/holodeck_effect/mobspawner/bee,
/obj/effect/holodeck_effect/mobspawner/bumbles,
/obj/effect/decal/remains/human,
/obj/item/clothing/suit/beekeeper_suit,
/turf/open/floor/holofloor/asteroid,
/area/holodeck/rec_center/anthophila)
"cr" = (
/obj/effect/holodeck_effect/mobspawner/bee,
/obj/effect/holodeck_effect/mobspawner/bumbles,
/obj/item/melee/flyswatter,
/turf/open/floor/holofloor/asteroid,
/area/holodeck/rec_center/anthophila)
@@ -20270,6 +20270,9 @@
},
/turf/open/space,
/area/space)
"Vy" = (
/turf/open/chasm/lavaland,
/area/holodeck/rec_center/wildlife)
"Vz" = (
/obj/machinery/vending/wallmed{
name = "Emergency NanoMed";
@@ -80911,16 +80914,16 @@ aa
"}
(232,1,1) = {"
ac
Vy
Vy
Vy
ap
ap
ap
ap
ap
ap
ap
ap
ap
ap
Vy
Vy
Vy
bj
bt
bI
@@ -81168,7 +81171,7 @@ aa
"}
(233,1,1) = {"
ac
ap
Vy
aB
ap
ap
@@ -81177,7 +81180,7 @@ ap
ap
ap
aB
ap
Vy
bj
Xg
TF
@@ -81425,7 +81428,7 @@ aa
"}
(234,1,1) = {"
ac
ap
Vy
ap
ap
ap
@@ -81434,7 +81437,7 @@ aB
ap
ap
ap
ap
Vy
bj
bu
bJ
@@ -81682,16 +81685,16 @@ aa
"}
(235,1,1) = {"
ac
ap
aB
Vy
ap
ap
ap
ap
ap
ap
aB
ap
ap
Vy
bj
bv
bK
@@ -81939,16 +81942,16 @@ aa
"}
(236,1,1) = {"
ac
ap
ap
ap
ap
ap
ap
ap
ap
ap
ap
Vy
Vy
Vy
Vy
Vy
Vy
Vy
Vy
Vy
Vy
bj
RD
Va
@@ -0,0 +1,4 @@
///from base of atom/experience_pressure_difference(): (pressure_difference, direction, pressure_resistance_prob_delta)
#define COMSIG_MOVABLE_PRE_PRESSURE_PUSH "atom_pre_pressure_push"
///prevents pressure movement
#define COMSIG_MOVABLE_BLOCKS_PRESSURE (1<<0)
+7 -3
View File
@@ -279,9 +279,13 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
#define PDA_SKIN_MODERN "Modern"
#define PDA_SKIN_MINIMAL "Minimal"
GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_SKIN_ALT = 'icons/obj/pda_alt.dmi',
PDA_SKIN_RUGGED = 'icons/obj/pda_rugged.dmi', PDA_SKIN_MODERN = 'icons/obj/pda_modern.dmi',
PDA_SKIN_MINIMAL = 'icons/obj/pda_minimal.dmi'))
GLOBAL_LIST_INIT(pda_reskins, list(
PDA_SKIN_CLASSIC = list("icon" = 'icons/obj/pda.dmi'),
PDA_SKIN_ALT = list("icon" = 'icons/obj/pda_alt.dmi'),
PDA_SKIN_RUGGED = list("icon" = 'icons/obj/pda_rugged.dmi'),
PDA_SKIN_MODERN = list("icon" = 'icons/obj/pda_modern.dmi'),
PDA_SKIN_MINIMAL = list("icon" = 'icons/obj/pda_minimal.dmi')
))
/////////////////////////////////////
// atom.appearence_flags shortcuts //
-3
View File
@@ -114,6 +114,3 @@
#define span_warning(str) ("<span class='warning'>" + str + "</span>")
#define span_yell(str) ("<span class='yell'>" + str + "</span>")
#define span_yellowteamradio(str) ("<span class='yellowteamradio'>" + str + "</span>")
//SANDSTORM DEFINES
#define span_love(str) ("<span class='love'>" + str + "</span>")
+3
View File
@@ -0,0 +1,3 @@
#define span_lewd(str) ("<span class='lewd'>" + str + "</span>")
#define span_love(str) ("<span class='love'>" + str + "</span>")
#define span_userlove(str) ("<span class='userlove'>" + str + "</span>")
+5 -2
View File
@@ -1,2 +1,5 @@
#define span_userlove(str) ("<span class='userlove'>" + str + "</span>")
#define span_lewd(str) ("<span class='lewd'>" + str + "</span>")
// This file is maintained for exotic span types
#define span_reallybig_hypnophrase(str) ("<span class='reallybig hypnophrase'>" + str + "</span>")
#define span_big_warning(str) ("<span class='big warning'>" + str + "</span>")
#define span_header(str) ("<span class='header'>" + str + "</span>")
#define span_umbra(str) ("<span class='umbra'>" + str + "</span>")
+3 -37
View File
@@ -209,7 +209,8 @@ GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, //everything
"Grey Satchel" = /obj/item/storage/backpack/satchel,
"Grey Duffel Bag" = /obj/item/storage/backpack/duffelbag,
"Leather Satchel" = /obj/item/storage/backpack/satchel/leather,
"Snail Shell" = /obj/item/storage/backpack/snail))
"Snail Shell" = /obj/item/storage/backpack/snail,
"Sloog Shell" = /obj/item/storage/backpack/sloogshell))
//Suit/Skirt
#define PREF_SUIT "Jumpsuit"
@@ -339,46 +340,11 @@ GLOBAL_LIST_INIT(greyscale_limb_types, list("human","moth","lizard","pod","plant
//body ids that have prosthetic sprites
GLOBAL_LIST_INIT(prosthetic_limb_types, list("xion","bishop","cybersolutions","grayson","hephaestus","nanotrasen","talon"))
//FAMILY HEIRLOOM LIST
//this works by using the first number for the species as a probability to choose one of the items in the following list for their family heirloom
//if the probability fails, or the species simply isn't in the list, then it defaults to the next global list, which has its own list of items for each job
//the first item in the list is for if your job isn't in that list
//species-heirloom list (we categorise them by the species id var)
GLOBAL_LIST_INIT(species_heirlooms, list(
"dwarf" = list(25, list(/obj/item/reagent_containers/food/drinks/dwarf_mug)), //example: 25% chance for dwarves to get a dwarf mug as their heirloom (normal container but has manly dorf icon)
"insect" = list(25, list(/obj/item/flashlight/lantern/heirloom_moth)),
"ipc" = list(25, list(/obj/item/stock_parts/cell/family)), //gives a broken powercell for flavor text!
"synthliz" = list(25, list(/obj/item/stock_parts/cell/family)), //they're also robots
"slimeperson" = list(25, list(/obj/item/toy/plush/slimeplushie)),
"lizard" = list(25, list(/obj/item/toy/plush/lizardplushie)),
))
//job-heirloom list
GLOBAL_LIST_INIT(job_heirlooms, list(
"NO_JOB" = list(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20),
"Clown" = list(/obj/item/paint/anycolor, /obj/item/bikehorn/golden),
"Mime" = list(/obj/item/paint/anycolor, /obj/item/toy/dummy),
"Cook" = list(/obj/item/kitchen/knife/scimitar),
"Botanist" = list(/obj/item/cultivator, /obj/item/reagent_containers/glass/bucket, /obj/item/storage/bag/plants, /obj/item/toy/plush/beeplushie),
"Medical Doctor" = list(/obj/item/healthanalyzer),
"Paramedic" = list(/obj/item/lighter), //..why?
"Station Engineer" = list(/obj/item/wirecutters/brass/family, /obj/item/crowbar/brass/family, /obj/item/screwdriver/brass/family, /obj/item/wrench/brass/family), //brass tools but without the tool speed modifier
"Atmospheric Technician" = list(/obj/item/extinguisher/mini/family),
"Lawyer" = list(/obj/item/storage/briefcase/lawyer/family),
"Janitor" = list(/obj/item/mop),
"Scientist" = list(/obj/item/toy/plush/slimeplushie),
"Assistant" = list(/obj/item/clothing/gloves/cut/family),
"Prisoner" = list (/obj/item/pen/blue),
"Chaplain" = list(/obj/item/camera/spooky/family),
"Head of Personnel" = list(/obj/item/pinpointer/ian)
))
//body ids that have non-gendered bodyparts
GLOBAL_LIST_INIT(nongendered_limb_types, list("fly", "zombie" ,"synth", "shadow", "cultgolem", "agent", "plasmaman", "clockgolem", "clothgolem"))
//list of eye types, corresponding to a respective left and right icon state for the set of eyes
GLOBAL_LIST_INIT(eye_types, list("normal", "insect", "moth", "double", "double2", "double3", "spider", "cyclops", "third", "spectre", "shadekin"))
GLOBAL_LIST_INIT(eye_types, list("normal", "insect", "moth", "double", "double2", "double3", "spider", "cyclops", "third", "spectre", "shadekin", "none"))
//list linking bodypart bitflags to their actual names
GLOBAL_LIST_INIT(bodypart_names, list(num2text(HEAD) = "Head", num2text(CHEST) = "Chest", num2text(LEG_LEFT) = "Left Leg", num2text(LEG_RIGHT) = "Right Leg", num2text(ARM_LEFT) = "Left Arm", num2text(ARM_RIGHT) = "Right Arm"))
+1 -1
View File
@@ -405,7 +405,7 @@
return
/atom/proc/CtrlShiftClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT, user)
return
/*
+7 -2
View File
@@ -171,9 +171,14 @@
stress = max(stress - 4, 0)
/datum/brain_trauma/severe/monophobia/proc/check_alone()
//SANDSTORM EDIT
var/check_radius = 7
if(istype(owner.loc, /obj/belly))
return FALSE
if(HAS_TRAIT(owner, TRAIT_BLIND))
return TRUE
for(var/mob/M in oview(owner, 7))
check_radius = 1
for(var/mob/M in oview(owner, check_radius))
//SANDSTORM EDIT END
if(!isliving(M)) //ghosts ain't people
continue
if((istype(M, /mob/living/simple_animal/pet)) || M.ckey)
+104
View File
@@ -0,0 +1,104 @@
/*
* # Element: Object Reskinning
*
* Allows players to modify the appearance of their object (and other attributes if possible)
* PLEASE DO NOT HAVE INVALID VALUES IN unique_reskin I DON'T EVEN WANT TO KNOW WHAT HAPPENS.
* USAGE:
* unique_reskins = list(
* "skin 1" = list(
* "desc" = "very cool description",
* "icon" = 'very_cool_icon.dmi'
* ),
* "skin 2" = list(
* "desc" = "not as cool description",
* "icon" = 'the_boring_skin.dmi'
* )
* )
*/
/datum/element/object_reskinning
element_flags = ELEMENT_DETACH
/datum/element/object_reskinning/Attach(datum/target)
. = ..()
var/obj/the_obj = target
if(!istype(the_obj))
return ELEMENT_INCOMPATIBLE
if(!islist(the_obj.unique_reskin) || !length(the_obj.unique_reskin))
message_admins("[src] was given to an object without any unique reskins, if you really need to, give it a couple skins first.")
return ELEMENT_INCOMPATIBLE
RegisterSignal(the_obj, COMSIG_PARENT_EXAMINE, .proc/on_examine)
RegisterSignal(the_obj, the_obj.reskin_binding, .proc/reskin)
/datum/element/object_reskinning/Detach(datum/source, force)
var/obj/being_deleted = source
UnregisterSignal(source, list(COMSIG_PARENT_EXAMINE, being_deleted.reskin_binding))
return ..()
/datum/element/object_reskinning/proc/on_examine(obj/obj, mob/user, list/examine_list)
examine_list += span_notice("[capitalize(replacetext(obj.reskin_binding, "_", "-"))] to reskin it ([length(obj.unique_reskin)] possible styles).")
if(obj.always_reskinnable)
examine_list += span_notice("It has no limit to reskinning.")
/*
* Reskins an object according to user's choice.
* Will detach itself if there's no skins or if done successfully but not always reskinnable.
*
* Arguments:
* * to_reskin The object we will be reskinning
* * user The user who wants to choose a skin for the object
*/
/datum/element/object_reskinning/proc/reskin(obj/to_reskin, mob/user)
// Just stop early
if(!LAZYLEN(to_reskin.unique_reskin))
message_admins("[ADMIN_LOOKUPFLW(user)] attempted to reskin an object that has no skins!")
Detach(to_reskin)
return FALSE
// Can't use
if(!user.canUseTopic(to_reskin, BE_CLOSE, NO_DEXTERY, NO_TK))
return FALSE
// Get our choices
var/list/items = list()
for(var/reskin_option in to_reskin.unique_reskin)
var/image/item_image = image(
icon = to_reskin.unique_reskin[reskin_option]["icon"] ? to_reskin.unique_reskin[reskin_option]["icon"] : to_reskin.icon,
icon_state = to_reskin.unique_reskin[reskin_option]["icon_state"] ? to_reskin.unique_reskin[reskin_option]["icon_state"] : to_reskin.icon_state)
items += list("[reskin_option]" = item_image)
sortList(items)
// Display to the user
var/pick = show_radial_menu(user, to_reskin, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, user, to_reskin), radius = 38, require_near = TRUE)
if(!pick)
return FALSE
// Finish the work
to_reskin.current_skin = pick
for(var/reskin_var in to_reskin.unique_reskin[pick])
to_reskin.vars[reskin_var] = to_reskin.unique_reskin[pick][reskin_var]
to_chat(user, "[to_reskin] is now skinned as '[pick].'")
to_reskin.reskin_obj(user)
// Only once or always?
if(!to_reskin.always_reskinnable)
Detach(to_reskin)
return TRUE
/**
* Checks if we are allowed to interact with a radial menu for reskins
*
* Arguments:
* * user The mob interacting with the menu
* * obj The obj to be checking against
*/
/datum/element/object_reskinning/proc/check_reskin_menu(mob/user, obj/obj)
if(QDELETED(obj))
return FALSE
if(!obj.always_reskinnable && obj.current_skin)
return FALSE
if(!istype(user))
return FALSE
if(user.incapacitated())
return FALSE
return TRUE
+31 -3
View File
@@ -181,10 +181,10 @@
/datum/quirk/trandening
name = "High Luminosity Eyes"
desc = "When the next big fancy implant came out you had to buy one on impluse!"
desc = "When the next big fancy implant came out you had to buy one on impulse! You start the shift with emissive cybernetic eyes that can emit colored beams of light."
value = 1
gain_text = "<span class='notice'>You have to keep up with the next big thing!.</span>"
lose_text = "<span class='danger'>High-tech gizmos are a scam...</span>"
gain_text = "<span class='notice'>You've been keeping up with the latest cybernetic trends!</span>"
lose_text = "<span class='danger'>High powered eye lasers? What were you thinking...</span>"
/datum/quirk/trandening/on_spawn()
// Get targets
@@ -195,6 +195,34 @@
qdel(old_eyes)
new_eyes.Insert(quirk_holder)
/datum/quirk/trandening/remove()
// Get targets
var/obj/item/organ/eyes/old_eyes = quirk_holder.getorganslot(ORGAN_SLOT_EYES)
var/mob/living/carbon/human/qurk_mob = quirk_holder
// Check for eyes existing
if(!old_eyes)
return
// Check for quirk eyes
if(!istype(old_eyes, /obj/item/organ/eyes/robotic/glow))
return
// Define new eyes
var/species_eyes = /obj/item/organ/eyes
// Check for mutant eyes
if(qurk_mob.dna.species && qurk_mob.dna.species.mutanteyes)
// Set eyes to mutant type
species_eyes = qurk_mob.dna.species.mutanteyes
// Create new eyes item
var/obj/item/organ/eyes/new_eyes = new species_eyes()
// Replace eyes
qdel(old_eyes)
new_eyes.Insert(quirk_holder)
/datum/quirk/bloodpressure
name = "Polycythemia vera"
desc = "You've a treated form of Polycythemia vera that increases the total blood volume inside of you as well as the rate of replenishment!"
+36 -13
View File
@@ -43,27 +43,38 @@
GLOBAL_LIST_EMPTY(family_heirlooms)
/datum/quirk/family_heirloom/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
/datum/quirk/family_heirloom/on_spawn()
// Define holder and type
var/mob/living/carbon/human/human_holder = quirk_holder
var/obj/item/heirloom_type
var/species_heirloom_entry = GLOB.species_heirlooms[H.dna.species.id]
if(species_heirloom_entry)
if(prob(species_heirloom_entry[1]))
heirloom_type = pick(species_heirloom_entry[2])
// The quirk holder's species - we have a 50% chance, if we have a species with a set heirloom, to choose a species heirloom.
var/datum/species/holder_species = human_holder.dna?.species
if(holder_species && LAZYLEN(holder_species.family_heirlooms) && prob(50))
heirloom_type = pick(holder_species.family_heirlooms)
else
// Our quirk holder's job
var/datum/job/holder_job = SSjob.GetJob(human_holder.last_mind?.assigned_role)
if(holder_job && LAZYLEN(holder_job.family_heirlooms))
heirloom_type = pick(holder_job.family_heirlooms)
// If we didn't find an heirloom somehow, throw them a generic one
if(!heirloom_type)
var/job_heirloom_entry = GLOB.job_heirlooms[quirk_holder.mind.assigned_role]
if(!job_heirloom_entry)
heirloom_type = pick(GLOB.job_heirlooms["NO_JOB"]) //consider: should this be a define?
else
heirloom_type = pick(job_heirloom_entry)
heirloom_type = pick(/obj/item/toy/cards/deck, /obj/item/lighter, /obj/item/dice/d20)
// Create the heirloom item
heirloom = new heirloom_type(get_turf(quirk_holder))
// Add to global list
GLOB.family_heirlooms += heirloom
// Determine and assign item location
var/list/slots = list(
"in your left pocket" = ITEM_SLOT_LPOCKET,
"in your right pocket" = ITEM_SLOT_RPOCKET,
"in your backpack" = ITEM_SLOT_BACKPACK
)
where = H.equip_in_one_of_slots(heirloom, slots, FALSE) || "at your feet"
where = human_holder.equip_in_one_of_slots(heirloom, slots, FALSE) || "at your feet"
/datum/quirk/family_heirloom/post_add()
if(where == "in your backpack")
@@ -75,13 +86,25 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]"
/datum/quirk/family_heirloom/on_process()
if(heirloom in quirk_holder.GetAllContents())
// Ignore for dead holder
if(quirk_holder.stat == DEAD)
return
// When held: Positive mood
if(heirloom && (heirloom in quirk_holder.GetAllContents()))
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
// When not held: Negative mood
else
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom")
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
/datum/quirk/item_quirk/family_heirloom/remove()
// Clear mood events when removing this quirk
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom")
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
/datum/quirk/family_heirloom/clone_data()
return heirloom
+1 -16
View File
@@ -165,22 +165,7 @@
lose_text = "<span class='notice'>You no longer feel like you should be eating trash.</span>"
mob_trait = TRAIT_TRASHCAN
/datum/quirk/colorist
name = "Colorist"
desc = "You like carrying around a hair dye spray to quickly apply color patterns to your hair."
value = 0
medical_record_text = "Patient enjoys dyeing their hair with pretty colors."
/datum/quirk/colorist/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/dyespray/spraycan = new(get_turf(quirk_holder))
H.equip_to_slot(spraycan, ITEM_SLOT_BACKPACK)
H.regenerate_icons()
/datum/quirk/colorist/post_add()
var/mob/living/carbon/human/H = quirk_holder
SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_SHOW, H)
to_chat(quirk_holder, "<span class='boldnotice'>You brought some extra dye with you! It's in your bag if you forgot.</span>")
// Moved Colorist quirk to a loadout item
/datum/quirk/salt_sensitive
name = "Sodium Sensitivity"
+7 -22
View File
@@ -32,6 +32,9 @@ GLOBAL_LIST_EMPTY(PDAs)
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
always_reskinnable = TRUE
reskin_binding = COMSIG_CLICK_CTRL_SHIFT
//Main variables
var/owner = null // String name of owner
var/default_cartridge = 0 // Access level defined by cartridge
@@ -112,10 +115,10 @@ GLOBAL_LIST_EMPTY(PDAs)
. += id ? "<span class='notice'>Alt-click to remove the id.</span>" : ""
if(inserted_item && (!isturf(loc)))
. += "<span class='notice'>Ctrl-click to remove [inserted_item].</span>"
if(LAZYLEN(GLOB.pda_reskins))
. += "<span class='notice'>Ctrl-shift-click it to reskin it.</span>"
/obj/item/pda/Initialize(mapload)
if(GLOB.pda_reskins)
unique_reskin = GLOB.pda_reskins
. = ..()
if(fon)
set_light(f_lum, f_pow, f_col)
@@ -130,28 +133,10 @@ GLOBAL_LIST_EMPTY(PDAs)
new_overlays = TRUE
update_icon()
/obj/item/pda/CtrlShiftClick(mob/living/user)
. = ..()
if(GLOB.pda_reskins && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
reskin_obj(user)
/obj/item/pda/reskin_obj(mob/M)
if(!LAZYLEN(GLOB.pda_reskins))
return
var/dat = "<b>Reskin options for [name]:</b>"
for(var/V in GLOB.pda_reskins)
var/output = icon2html(GLOB.pda_reskins[V], M, icon_state)
dat += "\n[V]: <span class='reallybig'>[output]</span>"
to_chat(M, dat)
var/choice = input(M, "Choose the a reskin for [src]","Reskin Object") as null|anything in GLOB.pda_reskins
var/new_icon = GLOB.pda_reskins[choice]
if(QDELETED(src) || isnull(new_icon) || new_icon == icon || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
icon = new_icon
. = ..()
new_overlays = TRUE
update_icon()
to_chat(M, "[src] is now skinned as '[choice]'.")
/obj/item/pda/proc/set_new_overlays()
if(!overlays_offsets || !(icon in overlays_offsets))
@@ -191,7 +176,7 @@ GLOBAL_LIST_EMPTY(PDAs)
else
font_index = MODE_MONO
font_mode = FONT_MONO
var/pref_skin = GLOB.pda_reskins[C.prefs.pda_skin]
var/pref_skin = GLOB.pda_reskins[C.prefs.pda_skin]["icon"]
if(icon != pref_skin)
icon = pref_skin
new_overlays = TRUE
-2
View File
@@ -211,8 +211,6 @@
/obj/item/melee/transforming/energy/sword/saber/reskin_obj(mob/M)
. = ..()
if(!.)
return
switch(current_skin)
if("Sword")
icon_state = "sword[active ? sword_color : "0"]"
+7 -2
View File
@@ -55,8 +55,9 @@
generate_items_inside(items_inside,src)
/obj/item/storage/firstaid/ancient
icon_state = "firstaid"
desc = "A first aid kit with the ability to heal common types of injuries."
name = "ancient first-aid kit"
icon_state = "oldfirstaid"
desc = "A first aid kit with the ability to heal common types of injuries. You start thinking of the good old days just by looking at it."
/obj/item/storage/firstaid/ancient/PopulateContents()
if(empty)
@@ -69,6 +70,10 @@
new /obj/item/stack/medical/mesh(src)
new /obj/item/stack/medical/mesh(src)
/obj/item/storage/firstaid/ancient/heirloom
// Long since been ransacked by hungry powergaming assistants breaking into med storage
empty = TRUE
/obj/item/storage/firstaid/brute
name = "trauma treatment kit"
desc = "A first aid kit for when you get toolboxed."
+17 -52
View File
@@ -28,9 +28,17 @@
var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/current_skin //the item reskin
var/list/unique_reskin //List of options to reskin.
//Reskin variables
/// The item reskin
var/current_skin
/// List of options to reskin.
var/list/unique_reskin
/// Can always be modified
var/always_reskinnable = FALSE
/// How to bring up the reskinning menu
var/reskin_binding = COMSIG_CLICK_ALT
//
// Access levels, used in modules\jobs\access.dm
var/list/req_access
@@ -76,6 +84,10 @@
var/turf/T = loc
T.add_blueprints_preround(src)
/obj/ComponentInitialize()
. = ..()
if(islist(unique_reskin) && length(unique_reskin))
AddElement(/datum/element/object_reskinning)
/obj/Destroy(force=FALSE)
if(!ismachinery(src))
@@ -340,57 +352,10 @@
. = ..()
if(obj_flags & UNIQUE_RENAME)
. += "<span class='notice'>Use a pen on it to rename it or change its description.</span>"
if(unique_reskin && (!current_skin || always_reskinnable))
. += "<span class='notice'>Alt-click it to reskin it.</span>"
/obj/AltClick(mob/user)
. = ..()
if(unique_reskin && (!current_skin || always_reskinnable) && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
reskin_obj(user)
return TRUE
/// Reskins an object according to M's choice, modified to be overridable and supports different icons
/obj/proc/reskin_obj(mob/M)
if(!LAZYLEN(unique_reskin))
return FALSE
var/list/items = list()
for(var/reskin_option in unique_reskin)
var/image/item_image = image(
icon = unique_reskin[reskin_option]["icon"] ? unique_reskin[reskin_option]["icon"] : icon,
icon_state = unique_reskin[reskin_option]["icon_state"])
items += list("[reskin_option]" = item_image)
sortList(items)
var/pick = show_radial_menu(M, src, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, M), radius = 38, require_near = TRUE)
if(!pick)
return FALSE
if(!unique_reskin[pick]["icon_state"])
return FALSE
current_skin = pick
var/has_icon = unique_reskin[pick]["icon"]
if(has_icon)
icon = has_icon
icon_state = unique_reskin[pick]["icon_state"]
to_chat(M, "[src] is now skinned as '[pick].'")
return TRUE
/**
* Checks if we are allowed to interact with a radial menu for reskins
*
* Arguments:
* * user The mob interacting with the menu
*/
/obj/proc/check_reskin_menu(mob/user)
if(QDELETED(src))
return FALSE
if(current_skin)
return FALSE
if(!istype(user))
return FALSE
if(user.incapacitated())
return FALSE
return TRUE
/// Do you want to make overrides, of course you do! Will be called if an object was reskinned successfully
/obj/proc/reskin_obj(mob/user)
return
/obj/update_overlays()
. = ..()
+12 -3
View File
@@ -15,9 +15,12 @@
var/obj/structure/chair/C = new /obj/structure/chair(loc)
W.play_tool_sound(src)
C.setDir(dir)
part.forceMove(loc)
part.master = null
part = null
if (part)
part.forceMove(loc)
part.master = null
part = null
qdel(src)
/obj/structure/chair/e_chair/proc/shock()
@@ -44,3 +47,9 @@
to_chat(buckled_mob, "<span class='userdanger'>You feel a deep shock course through your body!</span>")
addtimer(CALLBACK(buckled_mob, /mob/living.proc/electrocute_act, 85, src, 1), 1)
visible_message("<span class='danger'>The electric chair went off!</span>", "<span class='italics'>You hear a deep sharp shock!</span>")
/obj/structure/chair/e_chair/Destroy()
if(part)
QDEL_NULL(part)
return ..()
+10 -10
View File
@@ -99,10 +99,10 @@
to_chat(src,"<span class='userdanger'>Your [G.name] cannot cum.</span>")
return
if(mb_time) //as long as it's not instant, give a warning
to_chat(src,"<span class='userlove'>You feel yourself about to orgasm.</span>")
to_chat(src, span_userlove("You feel yourself about to orgasm."))
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
return
to_chat(src,"<span class='userlove'>You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name].</span>")
to_chat(src, span_userlove("You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name]."))
do_climax(fluid_source, loc, G)
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30, obj/item/organ/genital/Lgen = null) //Used for climaxing with any living thing
@@ -110,16 +110,16 @@
if(!fluid_source)
return
if(mb_time) //Skip warning if this is an instant climax.
to_chat(src,"<span class='userlove'>You're about to climax [(Lgen) ? "in [L]'s [Lgen.name]" : "with [L]"]!</span>")
to_chat(L,"<span class='userlove'>[src] is about to climax [(Lgen) ? "in your [Lgen.name]" : "with you"]!</span>")
to_chat(src, span_userlove("You're about to climax [(Lgen) ? "in [L]'s [Lgen.name]" : "with [L]"]!"))
to_chat(L, span_userlove("[src] is about to climax [(Lgen) ? "in your [Lgen.name]" : "with you"]!"))
if(!do_after(src, mb_time, target = src) || !in_range(src, L) || !G.climaxable(src, TRUE))
return
if(spillage)
to_chat(src,"<span class='userlove'>You orgasm with [L], spilling out of [(Lgen) ? "[L.p_their()] [Lgen.name]" : "[L.p_them()]"], using your [G.name].</span>")
to_chat(L,"<span class='userlove'>[src] climaxes [(Lgen) ? "in your [Lgen.name]" : "with you"], overflowing and spilling, using [p_their()] [G.name]!</span>")
to_chat(src, span_userlove("You orgasm with [L], spilling out of [(Lgen) ? "[L.p_their()] [Lgen.name]" : "[L.p_them()]"], using your [G.name]."))
to_chat(L, span_userlove("[src] climaxes [(Lgen) ? "in your [Lgen.name]" : "with you"], overflowing and spilling, using [p_their()] [G.name]!"))
else //knots and other non-spilling orgasms
to_chat(src,"<span class='userlove'>You climax [(Lgen) ? "in [L]'s [Lgen.name]" : "with [L]"], your [G.name] spilling nothing.</span>")
to_chat(L,"<span class='userlove'>[src] climaxes [(Lgen) ? "in your [Lgen.name]" : "with you"], [p_their()] [G.name] spilling nothing!</span>")
to_chat(src, span_userlove("You climax [(Lgen) ? "in [L]'s [Lgen.name]" : "with [L]"], your [G.name] spilling nothing."))
to_chat(L, span_userlove("[src] climaxes [(Lgen) ? "in your [Lgen.name]" : "with you"], [p_their()] [G.name] spilling nothing!"))
//SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm) //Sandstorm edit
do_climax(fluid_source, spillage ? loc : L, G, spillage,, Lgen)
//L.receive_climax(src, Lgen, G, spillage)
@@ -129,10 +129,10 @@
if(!fluid_source)
return
if(mb_time)
to_chat(src,"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>")
to_chat(src, span_userlove("You start to [G.masturbation_verb] your [G.name] over [container]."))
if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
return
to_chat(src,"<span class='userlove'>You used your [G.name] to fill [container].</span>")
to_chat(src, span_userlove("You used your [G.name] to fill [container]."))
message_admins("[ADMIN_LOOKUPFLW(src)] used [p_their()] [G.name] to fill [container] with [G.get_fluid_name()].")
log_consent("[key_name(src)] used their [G.name] to fill [container].")
do_climax(fluid_source, container, G, FALSE, cover = TRUE)
+2 -2
View File
@@ -167,9 +167,9 @@
var/original_state = picked_organ.aroused_state
picked_organ.set_aroused_state(!picked_organ.aroused_state)
if(original_state != picked_organ.aroused_state)
to_chat(src,"<span class='userlove'>[picked_organ.aroused_state ? picked_organ.arousal_verb : picked_organ.unarousal_verb].</span>")
to_chat(src, span_userlove("[picked_organ.aroused_state ? picked_organ.arousal_verb : picked_organ.unarousal_verb]."))
else
to_chat(src,"<span class='userlove'>You can't make that genital [picked_organ.aroused_state ? "unaroused" : "aroused"]!</span>")
to_chat(src, span_userlove("You can't make that genital [picked_organ.aroused_state ? "unaroused" : "aroused"]!"))
picked_organ.update_appearance()
if(ishuman(src))
var/mob/living/carbon/human/human = src
+4 -2
View File
@@ -27,8 +27,10 @@
return TRUE
/obj/item/assembly/shock_kit/attack_self(mob/user)
part1.attack_self(user)
part2.attack_self(user)
if (part1)
part1.attack_self(user)
if (part2)
part2.attack_self(user)
add_fingerprint(user)
return
@@ -237,34 +237,45 @@
SSair.high_pressure_delta[src] = TRUE
/turf/open/proc/high_pressure_movements()
var/diff = pressure_difference
var/atom/movable/M
var/multiplier = 1
if(locate(/obj/structure/rack) in src)
diff *= 0.1
multiplier *= 0.1
else if(locate(/obj/structure/table) in src)
diff *= 0.2
for(var/obj/M in src)
if(!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired)
M.experience_pressure_difference(diff, pressure_direction, 0, pressure_specific_target)
for(var/mob/M in src)
if(!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired)
M.experience_pressure_difference(diff, pressure_direction, 0, pressure_specific_target)
/*
multiplier *= 0.2
for(var/thing in src)
M = thing
if (!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired)
M.experience_pressure_difference(pressure_difference * multiplier, pressure_direction, 0, pressure_specific_target)
if(pressure_difference > 100)
new /obj/effect/temp_visual/dir_setting/space_wind(src, pressure_direction, clamp(round(sqrt(pressure_difference) * 2), 10, 255))
*/
/atom/movable/var/pressure_resistance = 10
/atom/movable/var/last_high_pressure_movement_air_cycle = 0
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0, throw_target)
var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75
set waitfor = FALSE
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_PRESSURE_PUSH) & COMSIG_MOVABLE_BLOCKS_PRESSURE)
return
var/const/PROBABILITY_OFFSET = 40
var/const/PROBABILITY_BASE_PRECENT = 10
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
set waitfor = 0
var/move_prob = 100
if (pressure_resistance > 0)
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) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
step(src, direction)
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))))
var/move_force = max_force * clamp(move_prob, 0, 100) / 100
if(move_force > 6000)
// WALLSLAM HELL TIME OH BOY
var/turf/throw_turf = get_ranged_target_turf(get_turf(src), direction, round(move_force / 2000))
if(throw_target && (get_dir(src, throw_target) & direction))
throw_turf = get_turf(throw_target)
var/throw_speed = clamp(round(move_force / 3000), 1, 10)
throw_at(throw_turf, move_force / 3000, throw_speed)
else
step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
@@ -2,21 +2,31 @@
/obj/item/prescription_kit
name = "prescription lens kit"
desc = "A disposable kit containing all the needed tools and parts to develop and apply a self-modifying prescription lens overlay device to any eyewear."
desc = "A disposable kit containing all the needed tools and parts to develop and apply a self-modifying prescription lens overlay device to any eyewear. \
Insert eyewear, receive vision-correcting lenses."
icon = 'icons/obj/device.dmi'
icon_state = "modkit"
/obj/item/prescription_kit/attack_obj(obj/O, mob/living/user)
if(!istype(O, /obj/item/clothing/glasses))
/obj/item/prescription_kit/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/clothing/glasses) && I.Adjacent(user))
var/obj/item/clothing/glasses/target_glasses = I
prescribe(target_glasses, user)
else
return ..()
if(istype(O, /obj/item/clothing/glasses))
var/obj/item/clothing/glasses/target_glasses = O
if(target_glasses.vision_correction)
to_chat(user, span_notice("These are already fitted with prescription lenses or otherwise already correct vision!"))
return
playsound(src, 'sound/items/screwdriver.ogg', 50, 1)
user.visible_message(span_notice("[user] fits \the [target_glasses] with a prescription overlay device."), span_notice("You fit \the [target_glasses] with a prescription overlay device."))
target_glasses.prescribe()
target_glasses.balloon_alert(user, "prescription fitted!")
qdel(src)
/obj/item/prescription_kit/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(istype(target, /obj/item/clothing/glasses) && target.Adjacent(user))
var/obj/item/clothing/glasses/target_glasses = target
prescribe(target_glasses, user)
else
. = ..()
/obj/item/prescription_kit/proc/prescribe(obj/item/clothing/glasses/target_glasses, mob/user)
if(target_glasses.vision_correction)
to_chat(user, span_notice("These are already fitted with prescription lenses or otherwise already correct vision!"))
return
playsound(src, 'sound/items/screwdriver.ogg', 50, 1)
user.visible_message(span_notice("[user] fits \the [target_glasses] with a prescription overlay device."), span_notice("You fit \the [target_glasses] with a prescription overlay device."))
target_glasses.prescribe()
target_glasses.balloon_alert(user, "prescription fitted!")
qdel(src)
@@ -86,8 +86,6 @@
/obj/item/clothing/gloves/fingerless/pugilist/crafted/reskin_obj(mob/M)
. = ..()
if(!.)
return
switch(current_skin)
if("Short")
item_state = "armwraps"
@@ -622,6 +622,4 @@
/obj/item/clothing/accessory/pride/reskin_obj(mob/M)
. = ..()
if(!.)
return
name = "[current_skin] pin"
+3
View File
@@ -69,6 +69,9 @@
///Is this job affected by weird spawns like the ones from station traits
var/random_spawns_possible = TRUE
/// List of family heirlooms this job can get with the family heirloom quirk. List of types.
var/list/family_heirlooms
var/display_order = JOB_DISPLAY_ORDER_DEFAULT
var/bounty_types = CIV_JOB_BASIC
+5
View File
@@ -20,6 +20,11 @@ Assistant
dresscodecompliant = FALSE
always_can_respawn_as = TRUE
threat = 0.2
family_heirlooms = list(
/obj/item/storage/toolbox/mechanical/old/heirloom,
/obj/item/clothing/gloves/cut/family
)
/datum/job/assistant/get_access()
if(CONFIG_GET(flag/assistants_have_maint_access) || !CONFIG_GET(flag/jobs_have_minimal_access)) //Config has assistant maint access set
@@ -26,6 +26,12 @@
display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN
threat = 0.5
family_heirlooms = list(
/obj/item/lighter,
/obj/item/lighter/greyscale,
/obj/item/storage/box/matches
)
/datum/outfit/job/atmos
name = "Atmospheric Technician"
+6
View File
@@ -20,6 +20,12 @@
bounty_types = CIV_JOB_DRINK
display_order = JOB_DISPLAY_ORDER_BARTENDER
threat = 0.5
family_heirlooms = list(
/obj/item/reagent_containers/rag,
/obj/item/clothing/head/that,
/obj/item/reagent_containers/food/drinks/shaker
)
/datum/outfit/job/bartender
name = "Bartender"
+6
View File
@@ -20,6 +20,12 @@
display_order = JOB_DISPLAY_ORDER_BOTANIST
threat = 1.5 // lol powergame
family_heirlooms = list(
/obj/item/cultivator,
/obj/item/reagent_containers/glass/bucket, // Watering cans don't exist yet
/obj/item/toy/plush/beeplushie,
)
/datum/outfit/job/botanist
name = "Botanist"
jobtype = /datum/job/hydro
+5
View File
@@ -32,6 +32,11 @@
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
threat = 5
family_heirlooms = list(
/obj/item/reagent_containers/food/drinks/flask/gold,
/obj/item/toy/figure/captain
)
/datum/job/captain/get_access()
return get_all_accesses()
@@ -21,6 +21,10 @@
display_order = JOB_DISPLAY_ORDER_CARGO_TECHNICIAN
bounty_types = CIV_JOB_RANDOM
threat = 0.2
family_heirlooms = list(
/obj/item/clipboard
)
/datum/outfit/job/cargo_tech
name = "Cargo Technician"
+5
View File
@@ -19,6 +19,11 @@
display_order = JOB_DISPLAY_ORDER_CHAPLAIN
threat = 0.5
family_heirlooms = list(
/obj/item/toy/windupToolbox,
/obj/item/reagent_containers/food/drinks/bottle/holywater
)
/datum/job/chaplain/after_spawn(mob/living/H, client/C)
+5
View File
@@ -24,6 +24,11 @@
threat = 1.5
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/book/manual/wiki/chemistry,
/obj/item/fermichem/pHbooklet
)
/datum/outfit/job/chemist
name = "Chemist"
@@ -37,6 +37,15 @@
display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity)
threat = 2
family_heirlooms = list(
/obj/item/clothing/head/hardhat,
/obj/item/screwdriver/brass/family,
/obj/item/wrench/brass/family,
/obj/item/weldingtool/mini, // No brass family variant
/obj/item/crowbar/brass/family,
/obj/item/wirecutters/brass/family
)
/datum/outfit/job/ce
name = "Chief Engineer"
@@ -35,6 +35,15 @@
threat = 2
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/storage/firstaid/ancient/heirloom,
/obj/item/scalpel,
/obj/item/hemostat,
/obj/item/circular_saw,
/obj/item/retractor,
/obj/item/cautery
)
/datum/outfit/job/cmo
name = "Chief Medical Officer"
+4
View File
@@ -21,6 +21,10 @@
display_order = JOB_DISPLAY_ORDER_CLOWN
threat = 0 // honk
family_heirlooms = list(
/obj/item/bikehorn/golden
)
/datum/outfit/job/clown
name = "Clown"
+6
View File
@@ -22,6 +22,12 @@
display_order = JOB_DISPLAY_ORDER_COOK
threat = 0.2
family_heirlooms = list(
/obj/item/reagent_containers/food/condiment/saltshaker,
/obj/item/kitchen/rollingpin,
/obj/item/clothing/head/chefhat
)
/datum/outfit/job/cook
name = "Cook"
jobtype = /datum/job/cook
+5
View File
@@ -19,6 +19,11 @@
display_order = JOB_DISPLAY_ORDER_CURATOR
threat = 0.3
family_heirlooms = list(
/obj/item/pen/fountain,
/obj/item/storage/dice
)
/datum/outfit/job/curator
name = "Curator"
+4
View File
@@ -27,6 +27,10 @@
display_order = JOB_DISPLAY_ORDER_DETECTIVE
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/monophobia)
threat = 1
family_heirlooms = list(
/obj/item/reagent_containers/food/drinks/flask/det
)
/datum/outfit/job/detective
name = "Detective"
@@ -24,6 +24,10 @@
threat = 1.5
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/clothing/under/shorts/purple
)
/datum/outfit/job/geneticist
name = "Geneticist"
@@ -39,6 +39,10 @@
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/prosopagnosia, /datum/quirk/insanity)
threat = 2
family_heirlooms = list(
/obj/item/reagent_containers/food/drinks/trophy/silver_cup
)
/datum/outfit/job/hop
@@ -38,6 +38,10 @@
display_order = JOB_DISPLAY_ORDER_HEAD_OF_SECURITY
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia, /datum/quirk/insanity)
threat = 3
family_heirlooms = list(
/obj/item/book/manual/wiki/security_space_law
)
/datum/outfit/job/hos
name = "Head of Security"
+7
View File
@@ -19,6 +19,13 @@
display_order = JOB_DISPLAY_ORDER_JANITOR
threat = 0.2
family_heirlooms = list(
/obj/item/mop,
/obj/item/clothing/suit/caution,
/obj/item/reagent_containers/glass/bucket,
/obj/item/soap
)
/datum/outfit/job/janitor
name = "Janitor"
+5
View File
@@ -22,6 +22,11 @@
display_order = JOB_DISPLAY_ORDER_LAWYER
threat = 0.3
family_heirlooms = list(
/obj/item/gavelhammer,
/obj/item/book/manual/wiki/security_space_law
)
/datum/outfit/job/lawyer
name = "Lawyer"
@@ -22,6 +22,15 @@
threat = 0.5
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/storage/firstaid/ancient/heirloom,
/obj/item/scalpel,
/obj/item/hemostat,
/obj/item/circular_saw,
/obj/item/retractor,
/obj/item/cautery
)
/datum/outfit/job/doctor
name = "Medical Doctor"
+4
View File
@@ -20,6 +20,10 @@
display_order = JOB_DISPLAY_ORDER_MIME
threat = 0
family_heirlooms = list(
/obj/item/reagent_containers/food/snacks/baguette
)
/datum/job/mime/after_spawn(mob/living/carbon/human/H, client/C)
. = ..()
+4
View File
@@ -23,6 +23,10 @@
threat = 0.5
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/storage/firstaid/ancient/heirloom
)
/datum/outfit/job/paramedic
name = "Paramedic"
+4
View File
@@ -13,6 +13,10 @@
plasma_outfit = /datum/outfit/plasmaman/prisoner
display_order = JOB_DISPLAY_ORDER_PRISONER
family_heirlooms = list(
/obj/item/pen/blue
)
/datum/job/prisoner/get_latejoin_spawn_point()
return get_roundstart_spawn_point()
@@ -33,6 +33,11 @@
display_order = JOB_DISPLAY_ORDER_QUARTERMASTER
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
threat = 0.5
family_heirlooms = list(
/obj/item/stamp,
/obj/item/stamp/denied
)
/datum/outfit/job/quartermaster
name = "Quartermaster"
@@ -38,6 +38,10 @@
starting_modifiers = list(/datum/skill_modifier/job/level/wiring)
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
threat = 5
family_heirlooms = list(
/obj/item/toy/plush/slimeplushie
)
/datum/outfit/job/rd
name = "Research Director"
@@ -24,6 +24,10 @@
display_order = JOB_DISPLAY_ORDER_ROBOTICIST
threat = 1
family_heirlooms = list(
/obj/item/toy/figure/borg
)
/datum/outfit/job/roboticist
name = "Roboticist"
+4
View File
@@ -22,6 +22,10 @@
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
display_order = JOB_DISPLAY_ORDER_SCIENTIST
threat = 1.2
family_heirlooms = list(
/obj/item/toy/plush/slimeplushie
)
/datum/outfit/job/scientist
name = "Scientist"
@@ -28,6 +28,11 @@
display_order = JOB_DISPLAY_ORDER_SECURITY_OFFICER
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia)
threat = 2
family_heirlooms = list(
/obj/item/book/manual/wiki/security_space_law,
/obj/item/clothing/head/beret/sec
)
/datum/job/officer/get_access()
var/list/L = list()
@@ -24,6 +24,11 @@
display_order = JOB_DISPLAY_ORDER_SHAFT_MINER
threat = 1.5
family_heirlooms = list(
/obj/item/pickaxe/mini,
/obj/item/shovel
)
/datum/outfit/job/miner
name = "Shaft Miner (Lavaland)"
@@ -27,6 +27,15 @@
display_order = JOB_DISPLAY_ORDER_STATION_ENGINEER
threat = 1
family_heirlooms = list(
/obj/item/clothing/head/hardhat,
/obj/item/screwdriver/brass/family,
/obj/item/wrench/brass/family,
/obj/item/weldingtool/mini, // No brass family variant
/obj/item/crowbar/brass/family,
/obj/item/wirecutters/brass/family
)
/datum/outfit/job/engineer
name = "Station Engineer"
@@ -25,6 +25,10 @@
threat = 1.5
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
family_heirlooms = list(
/obj/item/reagent_containers/syringe
)
/datum/outfit/job/virologist
name = "Virologist"
+4
View File
@@ -29,6 +29,10 @@
display_order = JOB_DISPLAY_ORDER_WARDEN
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/nonviolent, /datum/quirk/paraplegic, /datum/quirk/blindness, /datum/quirk/monophobia)
threat = 2
family_heirlooms = list(
/obj/item/book/manual/wiki/security_space_law
)
/datum/job/warden/get_access()
var/list/L = list()
@@ -599,7 +599,7 @@
if(job in GLOB.command_positions)
command_bold = " command"
//Sandstorm changes
var/jobline = "[job_datum.title] ([job_datum.current_positions])"
var/jobline = "[job_datum.title]"
if(job_datum in SSjob.prioritized_jobs)
jobline = "<span class='priority'>[jobline]</span>"
if(client && client.prefs && client.prefs.alt_titles_preferences[job_datum.title])
@@ -237,6 +237,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
///For custom overrides for species ass images
var/icon/ass_image
/// List of family heirlooms this species can get with the family heirloom quirk. List of types.
var/list/family_heirlooms
///////////
// PROCS //
///////////
@@ -25,3 +25,7 @@
allowed_limb_ids = list("insect","apid","moth","moth_not_greyscale")
eye_type = "insect"
family_heirlooms = list(
/obj/item/flashlight/lantern/heirloom_moth
)
@@ -20,6 +20,11 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
species_language_holder = /datum/language_holder/dwarf
species_category = SPECIES_CATEGORY_BASIC //a kind of human
family_heirlooms = list(
// Dwarves get a dwarf mug as their heirloom (normal container but has manly dorf icon)
/obj/item/reagent_containers/food/drinks/dwarf_mug
)
/mob/living/carbon/human/species/dwarf //species admin spawn path
race = /datum/species/dwarf //and the race the path is set to.
@@ -13,6 +13,7 @@
wagging_type = "mam_waggingtail"
species_category = SPECIES_CATEGORY_FURRY
ass_image = 'icons/ass/asscat.png'
family_heirlooms = list(/obj/item/toy/cattoy)
/datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
if(ishuman(C))
@@ -37,6 +37,11 @@
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
family_heirlooms = list(
// Gives a broken powercell for flavor text!
/obj/item/stock_parts/cell/family
)
var/datum/action/innate/monitor_change/screen
languagewhitelist = list("Encoded Audio Language") //Skyrat change - species language whitelist
@@ -35,6 +35,10 @@
ass_image = 'icons/ass/assslime.png'
blacklisted_quirks = list(/datum/quirk/glass_bones)
family_heirlooms = list(
/obj/item/toy/plush/slimeplushie
)
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
C.faction -= "slime"
if(ishuman(C))
@@ -34,6 +34,10 @@
ass_image = 'icons/ass/asslizard.png'
family_heirlooms = list(
/obj/item/toy/plush/lizardplushie
)
/datum/species/lizard/random_name(gender,unique,lastname)
if(unique)
return random_unique_lizard_name(gender)
@@ -37,3 +37,8 @@
wagging_type = "mam_waggingtail"
species_category = SPECIES_CATEGORY_ROBOT
wings_icons = SPECIES_WINGS_ROBOT
family_heirlooms = list(
// They're also robots
/obj/item/stock_parts/cell/family
)
-2
View File
@@ -120,8 +120,6 @@
/obj/item/pen/fountain/captain/reskin_obj(mob/M)
. = ..()
if(!.)
return
desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp."
/obj/item/pen/attack_self(mob/living/carbon/user)
@@ -1088,7 +1088,7 @@
var/list/adjusted = H.adjust_arousal(5,aphro = TRUE)
for(var/g in adjusted)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>You feel like playing with your [G.name]!</span>")
to_chat(M, span_userlove("You feel like playing with your [G.name]!"))
..()
/datum/reagent/consumable/monkey_energy
@@ -570,13 +570,13 @@
M.emote(pick("moan","blush"))
if(prob(min(current_cycle/4,10)))
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
to_chat(M, "<span class='userlove'>[aroused_message]</span>")
to_chat(M, span_userlove("[aroused_message]"))
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(current_cycle, "crocin", aphro = TRUE) // redundant but should still be here
for(var/g in genits)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>[G.arousal_verb]!</span>")
to_chat(M, span_userlove("[G.arousal_verb]!"))
..()
/datum/reagent/drug/aphrodisiacplus
@@ -603,14 +603,14 @@
aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
else
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
to_chat(M, "<span class='userlove'>[aroused_message]</span>")
to_chat(M, span_userlove("[aroused_message]"))
REMOVE_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(100, "hexacrocin", aphro = TRUE) // redundant but should still be here
for(var/g in genits)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>[G.arousal_verb]!</span>")
to_chat(M, span_userlove("[G.arousal_verb]!"))
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
@@ -631,7 +631,7 @@
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO) && prob(33))
if(prob(5) && ishuman(M) && M.has_dna() && (M.client?.prefs.cit_toggles & BIMBOFICATION))
if(!HAS_TRAIT(M,TRAIT_PERMABONER))
to_chat(M, "<span class='userlove'>Your libido is going haywire!</span>")
to_chat(M, span_userlove("Your libido is going haywire!"))
M.log_message("Made perma-horny by hexacrocin.",LOG_EMOTE)
ADD_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT)
..()
@@ -677,6 +677,6 @@
/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M)
if(M && M.client?.prefs.arousable && prob(5))
to_chat(M, "<span class='userlove'>You feel like you'll never feel aroused again...</span>")
to_chat(M, span_userlove("You feel like you'll never feel aroused again..."))
ADD_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
..()
@@ -2428,7 +2428,7 @@
var/list/adjusted = H.adjust_arousal(2,"catnip", aphro = TRUE)
for(var/g in adjusted)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>You feel like playing with your [G.name]!</span>")
to_chat(M, span_userlove("You feel like playing with your [G.name]!"))
..()
/datum/reagent/preservahyde
@@ -20,6 +20,10 @@
if(!. || synthesizing)
return
// Check if this user can process nutriment
if(HAS_TRAIT(owner, TRAIT_NO_PROCESS_FOOD))
return
if(owner.nutrition <= hunger_threshold)
synthesizing = TRUE
to_chat(owner, "<span class='notice'>You feel less hungry...</span>")
+22 -3
View File
@@ -5,15 +5,34 @@
product_slogans = "Carts to go!"
icon_state = "cart"
icon_deny = "cart-deny"
products = list(/obj/item/cartridge/medical = 10,
products = list(/obj/item/pda/heads = 10, // PDA
// Normal staff cards
/obj/item/cartridge/medical = 10,
/obj/item/cartridge/engineering = 10,
/obj/item/cartridge/security = 10,
/obj/item/cartridge/janitor = 10,
/obj/item/cartridge/signal/toxins = 10,
/obj/item/cartridge/roboticist = 10,
/obj/item/pda/heads = 10,
/obj/item/cartridge/atmos = 10,
/obj/item/cartridge/chemistry = 10,
/obj/item/cartridge/detective = 10,
/obj/item/cartridge/lawyer = 10,
/obj/item/cartridge/curator = 10,
/obj/item/cartridge/bartender = 10,
// Virus cards
/obj/item/cartridge/virus/clown = 3,
/obj/item/cartridge/virus/mime = 3,
// Command staff cards
/obj/item/cartridge/captain = 3,
/obj/item/cartridge/quartermaster = 10)
/obj/item/cartridge/quartermaster = 10,
/obj/item/cartridge/head = 10,
/obj/item/cartridge/hos = 10,
/obj/item/cartridge/ce = 10,
/obj/item/cartridge/cmo = 10,
/obj/item/cartridge/rd = 10)
armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50)
refill_canister = /obj/item/vending_refill/cart
resistance_flags = FIRE_PROOF
+83
View File
@@ -30,3 +30,86 @@
SandPoot:
- rscadd: Added a fancy reskin for the mining hardsuit, modify it using Alt-Click!
- imageadd: Special sprites made by Dexxiol#3462!
2023-01-10:
BongaTheProto:
- rscadd: New sloog sprites for character creation and backpack
- rscadd: New type of eyes, none
- bugfix: Fixes misclassing of sec badge
LeDrascol:
- tweak: Liquid Panty Dropper now launches clothing
- tweak: Liquid Panty Dropper no longer interferes with held items
- code_imp: LPD's clothing burst is now a mob proc
- bugfix: Fixed the late-join panel showing job slots twice
2023-01-11:
BongaTheProto:
- bugfix: Fixes gun reskins broken by the new reskin system
Seris02:
- bugfix: fixed gargoyles having sprites that are odd, along with sanity checks
and making the transition between living and statue seamless
2023-01-12:
LeDrascol:
- refactor: Moved quirk action datums to a new file
- rscadd: Added a Plushmium Crate to cargo
2023-01-13:
Guatolipo:
- rscadd: Added CART_CHEMISTRY access to cart-cmo
LeDrascol:
- tweak: Replaced three dangerous holodeck modes with harmless alternatives
2023-01-14:
LeDrascol:
- bugfix: Fixed spelling mistakes in the interaction system
- rscadd: Added the Love to Life spray bottle
- tweak: Updated Plushmium Crate contents
- rscadd: 'Added implant: Rapid Disrobe'
- tweak: Nudists now start with a Rapid Disrobe implant
- rscadd: Added the Wallet of Holding
2023-01-15:
BongaTheProto:
- rscadd: Adds nobl donator plushie
- rscadd: Adds a *poyo emote
Casper:
- bugfix: fixes telekinetic users from teleporting to stripper poles
- bugfix: infinite metal exploit
SandPoot:
- spellcheck: fixed a few typos.
- refactor: refactored skirt peeking.
- tweak: examine someone twice to actually peek their panties.
2023-01-16:
SandPoot:
- rscadd: You can now allow interacting with your genitals through clothes.
- tweak: Modified sandstorm's spans (`<span class='x'>"...`) with the defines (`span_x("...`)
2023-01-17:
BongaTheProto:
- code_imp: optimizes some genital related code
LeDrascol:
- code_imp: Added span defines for 'reallybig hypnophrase', 'big warning', 'header',
and 'umbra'
- refactor: All HTML spans are now defines-based
- tweak: Moved Autodoc techweb entry from Advanced Surgery to Advanced Surgery Tools
SishTis:
- rscadd: Addead keybinds to put/take items in/from suit storage and pockets slots.
zeroisthebiggay:
- spellcheck: You
2023-01-18:
LeDrascol:
- tweak: Moved Autodoc techweb entry from Advanced Surgery to Advanced Surgery Tools
- tweak: Bluespace mining research is now behind Anomaly Research
- balance: Bluespace miners now require a bluespace anomaly core
SandPoot:
- balance: Maybe very small amounts of air aren't as aggressive with pushing stuff
around.
- balance: Way too much air can send you FLYING, maybe think twice about opening
that airlock/firelock now.
- imageadd: Added space wind image for air pushing stuff.
2023-01-19:
LeDrascol:
- bugfix: Fixed spelling mistakes in server's clothing entries
- imageadd: Updated sprite for Chalice of Cum
- imagedel: Removed duplicate TG drink icons
- tweak: Liquid Panty Dropper now checks client prefs
2023-01-20:
LeDrascol:
- rscadd: Added a surplus condom box to Kinkmates
Winter Schock:
- bugfix: Doll with monophobia dont get stress in someone vore belly
- bugfix: Blind doll with monophobia dont get stress while someone in 1 tile range
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

@@ -190,3 +190,8 @@
loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION
subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES
cost = 0
// Moved here from quirks
/datum/gear/backpack/dyespray
name = "Hair dye spray"
path = /obj/item/dyespray
@@ -24,7 +24,7 @@
continue
if(valid_languages.len)
var/list/sorted_valid = sortList(valid_languages)
to_chat(user, "<span class='notice'>You are able to speak in [sorted_valid.Join(", ")]. If you're actually good at [valid_languages.len > 1 ? "them" : "it"] or not, it's up to you.</span>")
to_chat(user, span_notice("You are able to speak in [sorted_valid.Join(", ")]. If you're actually good at [valid_languages.len > 1 ? "them" : "it"] or not, it's up to you."))
if(invalid_languages.len)
var/list/sorted_invalid = sortList(invalid_languages)
to_chat(user, "<span class='warning'>[sorted_invalid.Join(", ")] [invalid_languages.len > 1 ? "are" : "is a"] restricted language[invalid_languages.len > 1 ? "s" : ""], and ha[invalid_languages.len > 1 ? "ve" : "s"] not been assigned.</span>")
to_chat(user, span_warning("[sorted_invalid.Join(", ")] [invalid_languages.len > 1 ? "are" : "is a"] restricted language[invalid_languages.len > 1 ? "s" : ""], and ha[invalid_languages.len > 1 ? "ve" : "s"] not been assigned."))
@@ -17,12 +17,12 @@
var/obj/item/I = parent
if(container.contents.len)
if(user)
to_chat(user, "<span class='warning'>There's already something in [container].</span>")
to_chat(user, span_warning("There's already something in [container]."))
return TRUE
if(user)
if(!user.transferItemToLoc(I, container))
return TRUE
to_chat(user, "<span class='notice'>You put [I] into [container].</span>")
to_chat(user, span_notice("You put [I] into [container]."))
else
I.forceMove(container)
container.tank = I
@@ -26,7 +26,7 @@
/datum/element/mob_holder/micro/on_examine(mob/living/source, mob/user, list/examine_list)
if(ishuman(user) && !istype(source.loc, /obj/item/clothing/head/mob_holder) && (abs(get_size(source)/get_size(user)) <= CONFIG_GET(number/max_pick_ratio)))
examine_list += "<span class='notice'>Looks like [source.p_they(FALSE)] can be picked up using <b>Alt+Click and grab intent</b>!</span>"
examine_list += span_notice("Looks like [source.p_they(FALSE)] can be picked up using <b>Alt+Click and grab intent</b>!")
/datum/element/mob_holder/micro/proc/mob_pickup_micro(mob/living/source, mob/user)
var/obj/item/clothing/head/mob_holder/micro/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
@@ -50,41 +50,41 @@
if(!ishuman(user) || !user.Adjacent(source) || user.incapacitated())
return FALSE
if(source == user)
to_chat(user, "<span class='warning'>You can't pick yourself up.</span>")
to_chat(user, span_warning("You can't pick yourself up."))
source.balloon_alert(user, "cannot pick yourself!")
return FALSE
if(abs(get_size(source)/get_size(user)) > CONFIG_GET(number/max_pick_ratio))
to_chat(user, "<span class='warning'>They're too big to pick up!</span>")
to_chat(user, span_warning("They're too big to pick up!"))
source.balloon_alert(user, "too big to pick up!")
return FALSE
if(user.get_active_held_item())
to_chat(user, "<span class='warning'>Your hands are full!</span>")
to_chat(user, span_warning("Your hands are full!"))
source.balloon_alert(user, "hands are full!")
return FALSE
if(source.buckled)
to_chat(user, "<span class='warning'>[source] is buckled to something!</span>")
to_chat(user, span_warning("[source] is buckled to something!"))
source.balloon_alert(user, "buckled to something!")
return FALSE
source.visible_message("<span class='warning'>[user] starts picking up [source].</span>", \
"<span class='userdanger'>[user] starts picking you up!</span>")
source.visible_message(span_warning("[user] starts picking up [source]."), \
span_userdanger("[user] starts picking you up!"))
source.balloon_alert(user, "picking up")
var/p = abs(get_size(source)/get_size(user) * 40) //Scale how fast the pickup will be depending on size difference
if(!do_after(user, p, target = source))
return FALSE
if(user.get_active_held_item())
to_chat(user, "<span class='warning'>Your hands are full!</span>")
to_chat(user, span_warning("Your hands are full!"))
source.balloon_alert(user, "hands full!")
return FALSE
if(source.buckled)
to_chat(user, "<span class='warning'>[source] is buckled to something!</span>")
to_chat(user, span_warning("[source] is buckled to something!"))
source.balloon_alert(user, "buckled!")
return FALSE
source.visible_message("<span class='warning'>[user] picks up [source]!</span>",
"<span class='userdanger'>[user] picks you up!</span>",
source.visible_message(span_warning("[user] picks up [source]!"),
span_userdanger("[user] picks you up!"),
target = user,
target_message = "<span class='notice'>You pick [source] up.</span>")
target_message = span_notice("You pick [source] up."))
source.drop_all_held_items()
mob_pickup_micro(source, user)
return TRUE
@@ -100,14 +100,14 @@
//TODO: add a timer to escape someone's grip dependant on size diff
/obj/item/clothing/head/mob_holder/micro/container_resist(mob/living/user)
if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't escape while you're restrained like this!</span>")
to_chat(user, span_warning("You can't escape while you're restrained like this!"))
return
var/mob/living/L = loc
visible_message("<span class='warning'>[src] begins to squirm in [L]'s grasp!</span>")
visible_message(span_warning("[src] begins to squirm in [L]'s grasp!"))
if(!do_after(user, 12 SECONDS, target = src, required_mobility_flags = MOBILITY_RESIST))
if(!user || user.stat != CONSCIOUS || user.loc != src)
return
to_chat(loc, "<span class='warning'>[src] stops resisting.</span>")
to_chat(loc, span_warning("[src] stops resisting."))
return
visible_message("<span class='warning'>[src] escapes [L]!")
release()
@@ -133,17 +133,17 @@
var/mob/living/carbon/human/M = held_mob
if(istype(M))
if(user.a_intent == "harm") //TO:DO, rework all of these interactions to be a lot more in depth
visible_message("<span class='danger'>[user] slams their fist down on [M]!</span>", runechat_popup = TRUE, rune_msg = " slams their fist down on [M]!")
visible_message(span_danger("[user] slams their fist down on [M]!"), runechat_popup = TRUE, rune_msg = " slams their fist down on [M]!")
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
M.adjustBruteLoss(5)
return
if(user.a_intent == "disarm")
visible_message("<span class='danger'>[user] pins [M] down with a finger!</span>", runechat_popup = TRUE, rune_msg = " pins [M] down with a finger!")
visible_message(span_danger("[user] pins [M] down with a finger!"), runechat_popup = TRUE, rune_msg = " pins [M] down with a finger!")
playsound(loc, 'sound/effects/bodyfall1.ogg', 50, 1)
M.adjustStaminaLoss(10)
return
if(user.a_intent == "grab")
visible_message("<span class='danger'>[user] squeezes their fist around [M]!</span>", runechat_popup = TRUE, rune_msg = " squeezes their fist around [M]!")
visible_message(span_danger("[user] squeezes their fist around [M]!"), runechat_popup = TRUE, rune_msg = " squeezes their fist around [M]!")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1)
M.adjustOxyLoss(5)
return
@@ -46,17 +46,17 @@
if(require_user_mouth)
if(!user.has_mouth() && !issilicon(user)) //Again, silicons do not have the required parts normally.
if(!silent)
to_chat(user, "<span class='warning'>You don't have a mouth.</span>")
to_chat(user, span_warning("You don't have a mouth."))
return FALSE
if(!user.mouth_is_free() && !issilicon(user)) //Borgs cannot wear mouthgear, bypassing the check.
if(!silent)
to_chat(user, "<span class='warning'>Your mouth is covered.</span>")
to_chat(user, span_warning("Your mouth is covered."))
return FALSE
if(require_user_hands && !user.has_hands() && !issilicon(user)) //Edited to allow silicons to interact.
if(!silent)
to_chat(user, "<span class='warning'>You don't have hands.</span>")
to_chat(user, span_warning("You don't have hands."))
return FALSE
if(COOLDOWN_FINISHED(user, last_interaction_time))
@@ -100,13 +100,13 @@
/datum/interaction/proc/do_action(mob/living/user, mob/living/target)
if(!user_is_target)
if(user == target) //tactical href fix
to_chat(user, "<span class='warning'>You cannot target yourself.</span>")
to_chat(user, span_warning("You cannot target yourself."))
return
if(get_dist(user, target) > max_distance)
to_chat(user, "<span class='warning'>They are too far away.</span>")
to_chat(user, span_warning("They are too far away."))
return
if(needs_physical_contact && !(user.Adjacent(target) && target.Adjacent(user)))
to_chat(user, "<span class='warning'>You cannot get to them.</span>")
to_chat(user, span_warning("You cannot get to them."))
return
if(!evaluate_user(user, silent = FALSE))
return
@@ -30,7 +30,7 @@
"lets a large stream of [u_His] own abundant [lowertext(milktext)] coat the back of \the <b>[target]</b>'s throat"
)
message = "<span class='lewd'>\The <b>[user]</b> [pick(lines)]</span>"
message = span_lewd("\The <b>[user]</b> [pick(lines)]")
user.visible_message(message, ignored_mobs = user.get_unconsenting())
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
@@ -59,56 +59,56 @@
/datum/interaction/lewd/titgrope/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
if(user.a_intent == INTENT_HELP)
user.visible_message(
pick("<span class='lewd'>\The <b>[user]</b> gently gropes \the <b>[target]</b>'s breast.</span>",
"<span class='lewd'>\The <b>[user]</b> softly squeezes \the <b>[target]</b>'s breasts.</span>",
"<span class='lewd'>\The <b>[user]</b> grips \the <b>[target]</b>'s breasts.</span>",
"<span class='lewd'>\The <b>[user]</b> runs a few fingers over \the <b>[target]</b>'s breast.</span>",
"<span class='lewd'>\The <b>[user]</b> delicately teases \the <b>[target]</b>'s nipple.</span>",
"<span class='lewd'>\The <b>[user]</b> traces a touch across \the <b>[target]</b>'s breast.</span>"))
pick(span_lewd("\The <b>[user]</b> gently gropes \the <b>[target]</b>'s breast."),
span_lewd("\The <b>[user]</b> softly squeezes \the <b>[target]</b>'s breasts."),
span_lewd("\The <b>[user]</b> grips \the <b>[target]</b>'s breasts."),
span_lewd("\The <b>[user]</b> runs a few fingers over \the <b>[target]</b>'s breast."),
span_lewd("\The <b>[user]</b> delicately teases \the <b>[target]</b>'s nipple."),
span_lewd("\The <b>[user]</b> traces a touch across \the <b>[target]</b>'s breast.")))
if(user.a_intent == INTENT_HARM)
user.visible_message(
pick("<span class='lewd'>\The <b>[user]</b> aggressively gropes \the <b>[target]</b>'s breast.</span>",
"<span class='lewd'>\The <b>[user]</b> grabs \the <b>[target]</b>'s breasts.</span>",
"<span class='lewd'>\The <b>[user]</b> tightly squeezes \the <b>[target]</b>'s breasts.</span>",
"<span class='lewd'>\The <b>[user]</b> slaps at \the <b>[target]</b>'s breasts.</span>",
"<span class='lewd'>\The <b>[user]</b> gropes \the <b>[target]</b>'s breasts roughly.</span>"))
pick(span_lewd("\The <b>[user]</b> aggressively gropes \the <b>[target]</b>'s breast."),
span_lewd("\The <b>[user]</b> grabs \the <b>[target]</b>'s breasts."),
span_lewd("\The <b>[user]</b> tightly squeezes \the <b>[target]</b>'s breasts."),
span_lewd("\The <b>[user]</b> slaps at \the <b>[target]</b>'s breasts."),
span_lewd("\The <b>[user]</b> gropes \the <b>[target]</b>'s breasts roughly.")))
if(prob(5 + target.get_lust()))
if(target.a_intent == INTENT_HELP)
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> shivers in arousal.</span>",
"<span class='lewd'>\The <b>[target]</b> moans quietly.</span>",
"<span class='lewd'>\The <b>[target]</b> breathes out a soft moan.</span>",
"<span class='lewd'>\The <b>[target]</b> gasps.</span>",
"<span class='lewd'>\The <b>[target]</b> shudders softly.</span>",
"<span class='lewd'>\The <b>[target]</b> trembles as hands run across bare skin.</span>"))
pick(span_lewd("\The <b>[target]</b> shivers in arousal."),
span_lewd("\The <b>[target]</b> moans quietly."),
span_lewd("\The <b>[target]</b> breathes out a soft moan."),
span_lewd("\The <b>[target]</b> gasps."),
span_lewd("\The <b>[target]</b> shudders softly."),
span_lewd("\The <b>[target]</b> trembles as hands run across bare skin.")))
if(target.get_lust() < 5)
target.set_lust(5)
if(target.a_intent == INTENT_DISARM)
if (target.restrained())
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> twists playfully against the restraints.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from <b>[user]</b>'s hand.</span>",
"<span class='lewd'>\The <b>[target]</b> slides back from <b>[user]</b>'s roaming hand.</span>",
"<span class='lewd'>\The <b>[target]</b> thrusts bare breasts forward into <b>[user]</b>'s hands.</span>"))
pick(span_lewd("\The <b>[target]</b> twists playfully against the restraints."),
span_lewd("\The <b>[target]</b> squirms away from <b>[user]</b>'s hand."),
span_lewd("\The <b>[target]</b> slides back from <b>[user]</b>'s roaming hand."),
span_lewd("\The <b>[target]</b> thrusts bare breasts forward into <b>[user]</b>'s hands.")))
else
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> playfully bats at <b>[user]</b>'s hand.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from <b>[user]</b>'s hand.</span>",
"<span class='lewd'>\The <b>[target]</b> guides <b>[user]</b>'s hand across bare breasts.</span>",
"<span class='lewd'>\The <b>[target]</b> teasingly laces a few fingers over <b>[user]</b>'s knuckles.</span>"))
pick(span_lewd("\The <b>[target]</b> playfully bats at <b>[user]</b>'s hand."),
span_lewd("\The <b>[target]</b> squirms away from <b>[user]</b>'s hand."),
span_lewd("\The <b>[target]</b> guides <b>[user]</b>'s hand across bare breasts."),
span_lewd("\The <b>[target]</b> teasingly laces a few fingers over <b>[user]</b>'s knuckles.")))
if(target.get_lust() < 10)
target.add_lust(1)
if(target.a_intent == INTENT_GRAB)
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> grips <b>[user]</b>'s wrist tight.</span>",
"<span class='lewd'>\The <b>[target]</b> digs nails into <b>[user]</b>'s arm.</span>",
"<span class='lewd'>\The <b>[target]</b> grabs <b>[user]</b>'s wrist for a second.</span>"))
pick(span_lewd("\The <b>[target]</b> grips <b>[user]</b>'s wrist tight."),
span_lewd("\The <b>[target]</b> digs nails into <b>[user]</b>'s arm."),
span_lewd("\The <b>[target]</b> grabs <b>[user]</b>'s wrist for a second.")))
if(target.a_intent == INTENT_HARM)
user.adjustBruteLoss(1)
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> pushes <b>[user]</b> roughly away.</span>",
"<span class='lewd'>\The <b>[target]</b> digs nails angrily into <b>[user]</b>'s arm.</span>",
"<span class='lewd'>\The <b>[target]</b> fiercely struggles against <b>[user]</b>.</span>",
"<span class='lewd'>\The <b>[target]</b> claws <b>[user]</b>'s forearm, drawing blood.</span>",
"<span class='lewd'>\The <b>[target]</b> slaps <b>[user]</b>'s hand away.</span>"))
pick(span_lewd("\The <b>[target]</b> pushes <b>[user]</b> roughly away."),
span_lewd("\The <b>[target]</b> digs nails angrily into <b>[user]</b>'s arm."),
span_lewd("\The <b>[target]</b> fiercely struggles against <b>[user]</b>."),
span_lewd("\The <b>[target]</b> claws <b>[user]</b>'s forearm, drawing blood."),
span_lewd("\The <b>[target]</b> slaps <b>[user]</b>'s hand away.")))
return
@@ -41,7 +41,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/champ1.ogg',
'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting(TRUE))
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting(TRUE))
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_EARS, partner)
partner.handle_post_sex(LOW_LUST, null, user)
@@ -41,7 +41,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/champ1.ogg',
'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting(TRUE))
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting(TRUE))
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_EYES, partner)
partner.handle_post_sex(LOW_LUST, null, user)
@@ -105,7 +105,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(retaliation_message)
user.visible_message("<font color=red><b>\The <b>[partner]</b></b> [retaliation_message]</span>", ignored_mobs = user.get_unconsenting())
if(fucktarget != "penis" || user.can_penetrating_genital_cum())
@@ -158,7 +158,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(retaliation_message)
user.visible_message(message = "<font color=red><b>\The <b>[partner]</b></b> [retaliation_message]</span>", ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
@@ -50,7 +50,7 @@
'modular_sand/sound/interactions/foot_dry2.ogg',
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_dry4.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
partner.handle_post_sex(LOW_LUST, null, user)
/datum/interaction/lewd/grindmouth
@@ -105,7 +105,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg',
'modular_sand/sound/interactions/foot_wet3.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
partner.handle_post_sex(LOW_LUST, null, user)
/datum/interaction/lewd/footjob
@@ -135,7 +135,7 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(partner.can_penetrating_genital_cum())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, user)
@@ -163,7 +163,7 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(partner.can_penetrating_genital_cum())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, user)
@@ -193,5 +193,5 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, user)
@@ -14,7 +14,7 @@
message = "rubs [t_His] [genital_name] against [partner]'s."
user.set_is_fucking(partner, CUM_TARGET_PENIS, user.getorganslot(ORGAN_SLOT_PENIS))
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, partner)
if(partner.can_penetrating_genital_cum())
@@ -43,6 +43,6 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/squelch1.ogg',
'modular_sand/sound/interactions/squelch2.ogg',
'modular_sand/sound/interactions/squelch3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, user)
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, partner)
@@ -24,7 +24,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/champ1.ogg',
'modular_sand/sound/interactions/champ2.ogg'), 50, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, partner)
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, user)
@@ -56,7 +56,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, partner)
partner.handle_post_sex(NORMAL_LUST, null, user)
@@ -86,7 +86,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_BREASTS, partner)
@@ -119,7 +119,7 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, partner)
@@ -148,7 +148,7 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, partner)
@@ -182,5 +182,5 @@
'modular_sand/sound/interactions/foot_dry3.ogg',
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_wet2.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_FEET, partner)
@@ -22,6 +22,6 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(partner.can_penetrating_genital_cum())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user)
@@ -16,6 +16,6 @@
/datum/interaction/lewd/kiss/display_interaction(mob/living/user, mob/living/partner)
if(user.get_lust() >= 3)
user.visible_message("<span class='lewd'>\The <b>[user]</b> gives an intense, lingering kiss to \the <b>[partner]</b>.</span>")
user.visible_message(span_lewd("\The <b>[user]</b> gives an intense, lingering kiss to \the <b>[partner]</b>."))
else
user.visible_message("<span class='lewd'>\The <b>[user]</b> kisses \the <b>[partner]</b> deeply.</span>")
user.visible_message(span_lewd("\The <b>[user]</b> kisses \the <b>[partner]</b> deeply."))
@@ -6,7 +6,7 @@
max_distance = 1
/datum/interaction/lewd/rimjob/display_interaction(mob/living/user, mob/living/partner)
user.visible_message("<span class='lewd'><b>\The [user]</b> licks \the <b>[partner]</b>'s asshole.</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> licks \the <b>[partner]</b>'s asshole."), ignored_mobs = user.get_unconsenting())
playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
partner.handle_post_sex(NORMAL_LUST, null, user)
@@ -29,5 +29,5 @@
message = "licks \the <b>[partner]</b>'s [partner.has_feet() == 1 ? "foot" : "feet"]."
playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/champ_fingering.ogg', 50, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
user.handle_post_sex(LOW_LUST, null, user)
@@ -19,7 +19,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(partner.can_penetrating_genital_cum())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_VAGINA, user)
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_PENIS, partner)
@@ -45,7 +45,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(partner.can_penetrating_genital_cum())
partner.handle_post_sex(NORMAL_LUST, CUM_TARGET_ANUS, user)
user.handle_post_sex(NORMAL_LUST, null, partner)
@@ -74,7 +74,7 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/squelch1.ogg',
'modular_sand/sound/interactions/squelch2.ogg',
'modular_sand/sound/interactions/squelch3.ogg'), 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
user.handle_post_sex(LOW_LUST, null, partner)
/datum/interaction/lewd/thighs
@@ -157,7 +157,7 @@
'modular_sand/sound/interactions/foot_wet1.ogg',
'modular_sand/sound/interactions/foot_dry3.ogg')
playlewdinteractionsound(get_turf(user), file, 70, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
user.handle_post_sex(lust_increase, THIGH_SMOTHERING, partner)
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
@@ -10,9 +10,9 @@
/datum/interaction/lewd/nipsuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target)
if((user.a_intent == INTENT_HELP) || (user.a_intent == INTENT_DISARM))
user.visible_message(
pick("<span class='lewd'>\The <b>[user]</b> gently sucks on \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>",
"<span class='lewd'>\The <b>[user]</b> gently nibs \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>",
"<span class='lewd'>\The <b>[user]</b> licks \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>"))
pick(span_lewd("\The <b>[user]</b> gently sucks on \the <b>[target]</b>'s [pick("nipple", "nipples")]."),
span_lewd("\The <b>[user]</b> gently nibs \the <b>[target]</b>'s [pick("nipple", "nipples")]."),
span_lewd("\The <b>[user]</b> licks \the <b>[target]</b>'s [pick("nipple", "nipples")].")))
if(target.has_breasts(REQUIRE_EXPOSED))
var/modifier = 1
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
@@ -31,8 +31,8 @@
if(user.a_intent == INTENT_HARM)
user.visible_message(
pick("<span class='lewd'>\The <b>[user]</b> bites \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>",
"<span class='lewd'>\The <b>[user]</b> aggressively sucks \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>"))
pick(span_lewd("\The <b>[user]</b> bites \the <b>[target]</b>'s [pick("nipple", "nipples")]."),
span_lewd("\The <b>[user]</b> aggressively sucks \the <b>[target]</b>'s [pick("nipple", "nipples")].")))
if(target.has_breasts(REQUIRE_EXPOSED))
var/modifier = 1
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
@@ -51,9 +51,9 @@
if(user.a_intent == INTENT_GRAB)
user.visible_message(
pick("<span class='lewd'>\The <b>[user]</b> sucks \the <b>[target]</b>'s [pick("nipple", "nipples")] intently.</span>",
"<span class='lewd'>\The <b>[user]</b> feasts \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>",
"<span class='lewd'>\The <b>[user]</b> glomps \the <b>[target]</b>'s [pick("nipple", "nipples")].</span>"))
pick(span_lewd("\The <b>[user]</b> sucks \the <b>[target]</b>'s [pick("nipple", "nipples")] intently."),
span_lewd("\The <b>[user]</b> feasts \the <b>[target]</b>'s [pick("nipple", "nipples")]."),
span_lewd("\The <b>[user]</b> glomps \the <b>[target]</b>'s [pick("nipple", "nipples")].")))
if(target.has_breasts(REQUIRE_EXPOSED))
var/modifier = 1
var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS)
@@ -74,66 +74,66 @@
if(target.a_intent == INTENT_HELP)
if(!target.has_breasts())
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> shivers in arousal.</span>",
"<span class='lewd'>\The <b>[target]</b> moans quietly.</span>",
"<span class='lewd'>\The <b>[target]</b> breathes out a soft moan.</span>",
"<span class='lewd'>\The <b>[target]</b> gasps.</span>",
"<span class='lewd'>\The <b>[target]</b> shudders softly.</span>",
"<span class='lewd'>\The <b>[target]</b> trembles as their chest gets molested.</span>"))
pick(span_lewd("\The <b>[target]</b> shivers in arousal."),
span_lewd("\The <b>[target]</b> moans quietly."),
span_lewd("\The <b>[target]</b> breathes out a soft moan."),
span_lewd("\The <b>[target]</b> gasps."),
span_lewd("\The <b>[target]</b> shudders softly."),
span_lewd("\The <b>[target]</b> trembles as their chest gets molested.")))
else
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> shivers in arousal.</span>",
"<span class='lewd'>\The <b>[target]</b> moans quietly.</span>",
"<span class='lewd'>\The <b>[target]</b> breathes out a soft moan.</span>",
"<span class='lewd'>\The <b>[target]</b> gasps.</span>",
"<span class='lewd'>\The <b>[target]</b> shudders softly.</span>",
"<span class='lewd'>\The <b>[target]</b> trembles as their breasts get molested.</span>",
"<span class='lewd'>\The <b>[target]</b> quivers in arousal as \the <b>[user]</b> delights themselves on their milk.</span>"))
pick(span_lewd("\The <b>[target]</b> shivers in arousal."),
span_lewd("\The <b>[target]</b> moans quietly."),
span_lewd("\The <b>[target]</b> breathes out a soft moan."),
span_lewd("\The <b>[target]</b> gasps."),
span_lewd("\The <b>[target]</b> shudders softly."),
span_lewd("\The <b>[target]</b> trembles as their breasts get molested."),
span_lewd("\The <b>[target]</b> quivers in arousal as \the <b>[user]</b> delights themselves on their milk.")))
if(target.get_lust() < 5)
target.set_lust(5)
if(target.a_intent == INTENT_DISARM)
if (target.restrained())
if(!target.has_breasts())
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> twists playfully against the restraints.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> thrusts their bare chest forward into \the <b>[user]</b>'s mouth.</span>"))
pick(span_lewd("\The <b>[target]</b> twists playfully against the restraints."),
span_lewd("\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> thrusts their bare chest forward into \the <b>[user]</b>'s mouth.")))
else
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> twists playfully against the restraints.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> thrust their bare breasts forward into \the <b>[user]</b>'s mouth.</span>"))
pick(span_lewd("\The <b>[target]</b> twists playfully against the restraints."),
span_lewd("\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> slides back from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> thrust their bare breasts forward into \the <b>[user]</b>'s mouth.")))
else
if(!target.has_breasts())
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> holds \the <b>[user]</b>'s head against their chest.</span>",
"<span class='lewd'>\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck.</span>"))
pick(span_lewd("\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head."),
span_lewd("\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> holds \the <b>[user]</b>'s head against their chest."),
span_lewd("\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck.")))
else
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head.</span>",
"<span class='lewd'>\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth.</span>",
"<span class='lewd'>\The <b>[target]</b> holds \the <b>[user]</b>'s head against their breast.</span>",
"<span class='lewd'>\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck.</span>",
"<span class='lewd'>\The <b>[target]</b> rubs their breasts against \the <b>[user]</b>'s head.</span>"))
pick(span_lewd("\The <b>[target]</b> playfully shoos away \the <b>[user]</b>'s head."),
span_lewd("\The <b>[target]</b> squirms away from \the <b>[user]</b>'s mouth."),
span_lewd("\The <b>[target]</b> holds \the <b>[user]</b>'s head against their breast."),
span_lewd("\The <b>[target]</b> teasingly caresses \the <b>[user]</b>'s neck."),
span_lewd("\The <b>[target]</b> rubs their breasts against \the <b>[user]</b>'s head.")))
if(target.get_lust() < 10)
target.add_lust(1)
if(target.a_intent == INTENT_GRAB)
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> grips \the <b>[user]</b>'s head tight.</span>",
"<span class='lewd'>\The <b>[target]</b> digs nails into \the <b>[user]</b>'s scalp.</span>",
"<span class='lewd'>\The <b>[target]</b> grabs and shoves \the <b>[user]</b>'s head away.</span>"))
pick(span_lewd("\The <b>[target]</b> grips \the <b>[user]</b>'s head tight."),
span_lewd("\The <b>[target]</b> digs nails into \the <b>[user]</b>'s scalp."),
span_lewd("\The <b>[target]</b> grabs and shoves \the <b>[user]</b>'s head away.")))
if(target.a_intent == INTENT_HARM)
user.adjustBruteLoss(1)
user.visible_message(
pick("<span class='lewd'>\The <b>[target]</b> slaps \the <b>[user]</b> away.</span>",
"<span class='lewd'>\The <b>[target]</b> scratches <b>[user]</b>'s face.</span>",
"<span class='lewd'>\The <b>[target]</b> fiercely struggles against <b>[user]</b>.</span>",
"<span class='lewd'>\The <b>[target]</b> claws <b>[user]</b>'s face, drawing blood.</span>",
"<span class='lewd'>\The <b>[target]</b> elbows <b>[user]</b>'s mouth away.</span>"))
pick(span_lewd("\The <b>[target]</b> slaps \the <b>[user]</b> away."),
span_lewd("\The <b>[target]</b> scratches <b>[user]</b>'s face."),
span_lewd("\The <b>[target]</b> fiercely struggles against <b>[user]</b>."),
span_lewd("\The <b>[target]</b> claws <b>[user]</b>'s face, drawing blood."),
span_lewd("\The <b>[target]</b> elbows <b>[user]</b>'s mouth away.")))
target.dir = get_dir(target, user)
user.dir = get_dir(user, target)
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
@@ -29,7 +29,7 @@
'modular_sand/sound/interactions/nuts2.ogg',
'modular_sand/sound/interactions/nuts3.ogg',
'modular_sand/sound/interactions/nuts4.ogg'), 70, 1, -1)*/ //These files don't even exist but nobody noticed because double-quotes were used instead of single.
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
user.handle_post_sex(lust_increase, CUM_TARGET_MOUTH, partner)
/datum/interaction/lewd/nut_smack
@@ -123,6 +123,6 @@
'modular_sand/sound/interactions/bj9.ogg',
'modular_sand/sound/interactions/bj10.ogg',
'modular_sand/sound/interactions/bj11.ogg'), 50, 1, -1)
user.visible_message("<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(fucktarget != "penis" || partner.can_penetrating_genital_cum())
partner.handle_post_sex(lust_increase, CUM_TARGET_MOUTH, user)
@@ -32,7 +32,7 @@
"gasps.",
"shudders softly.",
"trembles as [t_His] hands run across bare skin.")]</span>")
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1)
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user)
@@ -68,7 +68,7 @@
"fills [u_His] own mouth with a big gulp of [u_His] warm [lowertext(milktext)]"
)
message = "<span class='lewd'>\The <b>[user]</b> [pick(lines)]</span>"
message = span_lewd("\The <b>[user]</b> [pick(lines)]")
user.visible_message(message, ignored_mobs = user.get_unconsenting())
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg',
'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1)
@@ -28,6 +28,6 @@
playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/bang1.ogg',
'modular_sand/sound/interactions/bang2.ogg',
'modular_sand/sound/interactions/bang3.ogg'), 70, 1, -1)
user.visible_message(message = "<span class='lewd'><b>\The [user]</b> [message]</span>", ignored_mobs = user.get_unconsenting())
user.visible_message(message = span_lewd("<b>\The [user]</b> [message]"), ignored_mobs = user.get_unconsenting())
if(user.can_penetrating_genital_cum())
user.handle_post_sex(NORMAL_LUST, CUM_TARGET_HAND, user)

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