diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 18db6de76921..66a97ccf4184 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -33,48 +33,49 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
//Human Overlays Indexes/////////
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
-#define MUTATIONS_LAYER 41 //mutations. Tk headglows, cold resistance glow, etc
-#define ANTAG_LAYER 40 //stuff for things like cultism indicators (clock cult glow, cultist red halos, whatever else new that comes up)
-#define GENITALS_BEHIND_LAYER 39 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
-#define BODY_BEHIND_LAYER 38 //certain mutantrace features (tail when looking south) that must appear behind the body parts
-#define BODYPARTS_LAYER 37 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
-#define MARKING_LAYER 36 //Matrixed body markings because clashing with snouts?
-#define BODY_ADJ_LAYER 35 //certain mutantrace features (snout, body markings) that must appear above the body parts
-#define GENITALS_FRONT_LAYER 34 //Draws some genitalia above clothes and the TAUR body if need be.
-#define BODY_LAYER 33 //underwear, undershirts, socks, eyes, lips(makeup)
-#define BODY_ADJ_UPPER_LAYER 32
-#define FRONT_MUTATIONS_LAYER 31 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
-#define UNDERWEAR_LAYER 30
-#define SOCKS_LAYER 29
-#define SHIRT_LAYER 28
-#define UNIFORM_LAYER 27
-#define ID_LAYER 26
-#define HANDS_PART_LAYER 25
-#define DAMAGE_LAYER 24 //damage indicators (cuts and burns)
-#define LOWER_MEDICINE_LAYER 23 //Medicine, like gauze and tourniquets
-#define MEDICINE_LAYER 22 //Medicine, like gauze and tourniquets
-#define SHOES_LAYER 21
-#define GLOVES_LAYER 20
-#define WRISTS_LAYER 19
-#define EAR_RIGHT_LAYER 18
-#define EAR_LEFT_LAYER 17
-#define SUIT_LAYER 16
-#define GENITALS_EXPOSED_LAYER 15
-#define GLASSES_LAYER 14
-#define BELT_LAYER 13 //Possible make this an overlay of somethign required to wear a belt?
-#define SUIT_STORE_LAYER 12
-#define NECK_LAYER 11
-#define BACK_LAYER 10
-#define HAIR_LAYER 9 //TODO: make part of head layer?
-#define HORNS_LAYER 8
-#define FACEMASK_LAYER 7
-#define HEAD_LAYER 6
-#define HANDCUFF_LAYER 5
-#define LEGCUFF_LAYER 4
-#define HANDS_LAYER 3
-#define BODY_FRONT_LAYER 2
-#define FIRE_LAYER 1 //If you're on fire
-#define TOTAL_LAYERS 41 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
+#define MUTATIONS_LAYER 42 //mutations. Tk headglows, cold resistance glow, etc
+#define ANTAG_LAYER 41 //stuff for things like cultism indicators (clock cult glow, cultist red halos, whatever else new that comes up)
+#define GENITALS_BEHIND_LAYER 40 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
+#define BODY_BEHIND_LAYER 39 //certain mutantrace features (tail when looking south) that must appear behind the body parts
+#define BODYPARTS_LAYER 38 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
+#define MARKING_LAYER 37 //Matrixed body markings because clashing with snouts?
+#define BODY_ADJ_LAYER 36 //certain mutantrace features (snout, body markings) that must appear above the body parts
+#define GENITALS_FRONT_LAYER 35 //Draws some genitalia above clothes and the TAUR body if need be.
+#define BODY_LAYER 34 //underwear, undershirts, socks, eyes, lips(makeup)
+#define BODY_ADJ_UPPER_LAYER 33
+#define FRONT_MUTATIONS_LAYER 32 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
+#define UNDERWEAR_LAYER 31
+#define SOCKS_LAYER 30
+#define SHIRT_LAYER 29
+#define UNIFORM_LAYER 28
+#define ID_LAYER 27
+#define HANDS_PART_LAYER 26
+#define DAMAGE_LAYER 25 //damage indicators (cuts and burns)
+#define LOWER_MEDICINE_LAYER 24 //Medicine, like gauze and tourniquets
+#define MEDICINE_LAYER 23 //Medicine, like gauze and tourniquets
+#define SHOES_LAYER 22
+#define GLOVES_LAYER 21
+#define WRISTS_LAYER 20
+#define EAR_RIGHT_LAYER 19
+#define EAR_LEFT_LAYER 18
+#define SUIT_LAYER 17
+#define GENITALS_EXPOSED_LAYER 16
+#define GLASSES_LAYER 15
+#define BELT_LAYER 14 //Possible make this an overlay of somethign required to wear a belt?
+#define SUIT_STORE_LAYER 13
+#define NECK_LAYER 12
+#define BACK_LAYER 11
+#define HAIR_LAYER 10 //TODO: make part of head layer?
+#define HORNS_LAYER 9
+#define FACEMASK_LAYER 8
+#define HEAD_LAYER 7
+#define HANDCUFF_LAYER 6
+#define LEGCUFF_LAYER 5
+#define HANDS_LAYER 4
+#define BODY_FRONT_LAYER 3
+#define FIRE_LAYER 2 //If you're on fire
+#define GROPING_LAYER 1
+#define TOTAL_LAYERS 42 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
diff --git a/code/__DEFINES/rendering/atom_hud.dm b/code/__DEFINES/rendering/atom_hud.dm
index 8fb5aa6784be..ebbcca857efb 100644
--- a/code/__DEFINES/rendering/atom_hud.dm
+++ b/code/__DEFINES/rendering/atom_hud.dm
@@ -28,6 +28,7 @@
//for antag huds. these are used at the /mob level
#define ANTAG_HUD "24"
#define ANTAGTARGET_HUD "25" // Which players consent via their game settings to be a target for antagonists
+#define AROUSAL_HUD "26"
//by default everything in the hud_list of an atom is an image
//a value in hud_list with one of these will change that behavior
@@ -69,5 +70,6 @@
// Which players consent via their game settings to be a target for antagonists
#define DATA_HUD_ANTAGTARGET 30
+#define DATA_HUD_AROUSAL 31
#define ADD_HUD_TO_COOLDOWN 20 //cooldown for being shown the images for any particular data hud
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index dbacbcbda59c..7d244fc06485 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -210,6 +210,7 @@
#define TRAIT_TAGGER "tagger"
#define TRAIT_PHOTOGRAPHER "photographer"
#define TRAIT_MUSICIAN "musician"
+#define TRAIT_SEXSPELLS "sexspells"
#define TRAIT_PERMABONER "permanent_arousal"
#define TRAIT_NEVERBONER "never_aroused"
#define TRAIT_NYMPHO "nymphomaniac"
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index 709d558a4203..3afd1d4ac2aa 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -121,6 +121,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_TAGGER" = TRAIT_TAGGER,
"TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER,
"TRAIT_MUSICIAN" = TRAIT_MUSICIAN,
+ "TRAIT_SEXSPELLS" = TRAIT_SEXSPELLS,
"TRAIT_MASO" = TRAIT_MASO,
"TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD,
"TRAIT_EMPATH" = TRAIT_EMPATH,
diff --git a/code/_rendering/atom_huds/atom_hud.dm b/code/_rendering/atom_huds/atom_hud.dm
index 9cdf277c5f52..827a2e4e0503 100644
--- a/code/_rendering/atom_huds/atom_hud.dm
+++ b/code/_rendering/atom_huds/atom_hud.dm
@@ -34,6 +34,7 @@ GLOBAL_LIST_INIT(huds, list(
ANTAG_HUD_GANGSTER = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_SLAVER = new/datum/atom_hud/antag(),
DATA_HUD_ANTAGTARGET = new/datum/atom_hud/data/human/antagtarget(),
+ DATA_HUD_AROUSAL = new/datum/atom_hud/data/human/arousal(),
))
/datum/atom_hud
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 218a181819fe..93be378b0752 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1611,6 +1611,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Receive Cum Covering : [(cit_toggles & CUM_ONTO) ? "Allowed" : "Disallowed"]
"
dat += "? "
dat += "Unholy ERP verbs : [unholypref]
" //https://www.youtube.com/watch?v=OHKARc-GObU
+ dat += "Magical ERP : [magicalpref]
" //https://www.youtube.com/watch?v=OHKARc-GObU
dat += "? "
dat += "Stomping Interactions : [stomppref ? "Yes" : "No"]
"
//END OF SPLURT EDIT
@@ -3625,6 +3626,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
unholypref = "No"
if("No")
unholypref = "Yes"
+ if("magicalpref")
+ switch(magicalpref)
+ if("Yes")
+ magicalpref = "No"
+ if("No")
+ magicalpref = "Yes"
if("stomppref") // What the fuck is this?
stomppref = !stomppref
//Skyrat edit - *someone* offered me actual money for this shit
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index ab36cebd34cf..0ad718829342 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,5 +1,5 @@
/mob/living/carbon/human
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD,RAD_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD,RAD_HUD,AROUSAL_HUD)
hud_type = /datum/hud/human
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
pressure_resistance = 25
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 0c30c42a6552..1855f2a74ccd 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1297,6 +1297,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return
/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
+
+ if(H.uncovered)
+ if(return_warning)
+ return_warning[1] = "I've been wicked!"
+ return FALSE
+
if(slot in no_equip)
if(!I.species_exception || !is_type_in_list(src, I.species_exception))
return FALSE
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 1580c7605fe1..7de5e90eb900 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/modular_sand/code/datums/interactions/_interaction.dm b/modular_sand/code/datums/interactions/_interaction.dm
index 9ea6ab6c3ee9..e85ddd6d2410 100644
--- a/modular_sand/code/datums/interactions/_interaction.dm
+++ b/modular_sand/code/datums/interactions/_interaction.dm
@@ -106,15 +106,17 @@
return TRUE
/// Actually doing the action, has a few checks to see if it's valid, usually overwritten to be make things actually happen and what-not
-/datum/interaction/proc/do_action(mob/living/user, mob/living/target)
+
+/datum/interaction/proc/do_action(mob/living/user, mob/living/target, var/ignore_distance=0) //ignore distance for magic
if(!(interaction_flags & INTERACTION_FLAG_USER_IS_TARGET))
if(user == target) //tactical href fix
to_chat(user, span_warning("You cannot target yourself."))
return
- if(get_dist(user, target) > max_distance)
+ if(get_dist(user, target) > max_distance && !ignore_distance)
to_chat(user, span_warning("They are too far away."))
return
- if(interaction_flags & INTERACTION_FLAG_ADJACENT && !(user.Adjacent(target) && target.Adjacent(user)))
+
+ if(interaction_flags & INTERACTION_FLAG_ADJACENT && !(user.Adjacent(target) && target.Adjacent(user)) && !ignore_distance)
to_chat(user, span_warning("You cannot get to them."))
return
if(!evaluate_user(user, silent = FALSE))
diff --git a/modular_splurt/code/modules/client/preferences.dm b/modular_splurt/code/modules/client/preferences.dm
index 8d9a17312fa2..253d803b1f77 100644
--- a/modular_splurt/code/modules/client/preferences.dm
+++ b/modular_splurt/code/modules/client/preferences.dm
@@ -6,6 +6,7 @@
/datum/preferences
max_save_slots = DEFAULT_SAVE_SLOTS
var/unholypref = "No" //Goin 2 hell fo dis one
+ var/magicalpref = "No" //Goin 2 hell fo dis one
var/stomppref = TRUE // Please step on me.
var/list/gfluid_blacklist = list() //Stuff you don't want people to cum into you
var/new_character_creator = TRUE // old/new character creator
diff --git a/modular_splurt/code/modules/mob/living/carbon/human/human_defines.dm b/modular_splurt/code/modules/mob/living/carbon/human/human_defines.dm
index 93880806ee20..114995e55037 100644
--- a/modular_splurt/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/modular_splurt/code/modules/mob/living/carbon/human/human_defines.dm
@@ -5,5 +5,6 @@
/mob/living/carbon/human/Initialize()
LAZYADD(hud_possible, ANTAGTARGET_HUD)
+ LAZYADD(hud_possible, AROUSAL_HUD)
. = ..()
RegisterSignal(src, COMSIG_MOB_CLIMAX, .proc/check_orgasm)
diff --git a/modular_splurt/code/modules/mob/living/living.dm b/modular_splurt/code/modules/mob/living/living.dm
index 2638d8e6c6a1..2a458868c016 100644
--- a/modular_splurt/code/modules/mob/living/living.dm
+++ b/modular_splurt/code/modules/mob/living/living.dm
@@ -36,7 +36,7 @@
if("Toggle Penis")
has_penis = !has_penis
if("Toggle Pussy")
- has_vagina = !has_vagina
+ has_vagina = !has_vagina
if("Toggle Balls")
has_balls = !has_balls
@@ -89,3 +89,9 @@
set desc = "Switch sharp/fuzzy scaling for current mob."
appearance_flags ^= PIXEL_SCALE
fuzzy = !fuzzy
+
+/mob/living/Initialize(mapload)
+ . = ..()
+ for(var/datum/atom_hud/data/human/arousal/arousal_hud in GLOB.huds)
+ arousal_hud.add_to_hud(src)
+
diff --git a/modular_splurt/code/modules/spell/spell_types/aoe_lust.dm b/modular_splurt/code/modules/spell/spell_types/aoe_lust.dm
new file mode 100644
index 000000000000..1bb6cb9c41aa
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/aoe_lust.dm
@@ -0,0 +1,18 @@
+/obj/effect/proc_holder/spell/self/aoe_lust
+ name = "Area Lust"
+ desc = "Make the people nearby horny."
+ charge_max = 600 //variable
+ cooldown_min = 0
+ clothes_req = NONE
+ antimagic_allowed = TRUE
+ action_icon_state = "aoe_lust"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ var/activated = 0
+ clothes_req = NONE
+
+/obj/effect/proc_holder/spell/self/aoe_lust/cast(mob/living/carbon/human/user)
+ for(var/mob/living/carbon/human/HH in view(5, user))
+ if(HH?.client?.prefs?.magicalpref == "No")
+ continue
+ HH.add_lust(50)
+
diff --git a/modular_splurt/code/modules/spell/spell_types/eyes_of_lust.dm b/modular_splurt/code/modules/spell/spell_types/eyes_of_lust.dm
new file mode 100644
index 000000000000..5a837abc42ce
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/eyes_of_lust.dm
@@ -0,0 +1,55 @@
+/datum/atom_hud/data/human/arousal
+ hud_icons = list(AROUSAL_HUD)
+
+/mob/living/carbon/human/proc/add_arousal_hud()
+ var/datum/atom_hud/data/human/arousal/hud = GLOB.huds[DATA_HUD_AROUSAL]
+ hud.add_hud_to(src)
+ arousal_hud_update()
+ for(var/mob/living/carbon/human/H in view(7, src))
+ hud.add_to_hud(H)
+
+/mob/living/carbon/human/proc/remove_arousal_hud()
+ var/datum/atom_hud/data/human/arousal/hud = GLOB.huds[DATA_HUD_AROUSAL]
+ hud.remove_hud_from(src)
+
+/mob/living/carbon/human/Life()
+ . = ..()
+ arousal_hud_update()
+
+/mob/living/carbon/human/proc/arousal_hud_update()
+ var/image/holder = hud_list[AROUSAL_HUD]
+ var/icon/I = icon(icon, icon_state, dir)
+ holder.pixel_y = I.Height() - world.icon_size
+ var/arousal = getPercentAroused()
+ switch(arousal)
+ if(0 to 25)
+ holder.icon_state = "hudarousal1"
+ if(25 to 50)
+ holder.icon_state = "hudarousal2"
+ if(50 to 75)
+ holder.icon_state = "hudarousal3"
+ if(75 to INFINITY)
+ holder.icon_state = "hudarousal4"
+
+/obj/effect/proc_holder/spell/self/eyes_of_lust
+ name = "Eyes of Lust"
+ desc = "Watch the lust."
+ charge_max = 1200 //variable
+ cooldown_min = 0
+ clothes_req = NONE
+ antimagic_allowed = TRUE
+ action_icon_state = "eyes_of_lust"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ var/activated = 0
+ clothes_req = NONE
+
+/obj/effect/proc_holder/spell/self/eyes_of_lust/cast(mob/living/carbon/human/user)
+
+ if(!activated)
+ user.add_arousal_hud()
+ activated = 1
+ else
+ user.remove_arousal_hud()
+ activated = 0
+
+
diff --git a/modular_splurt/code/modules/spell/spell_types/groping.dm b/modular_splurt/code/modules/spell/spell_types/groping.dm
new file mode 100644
index 000000000000..d302c75edaf5
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/groping.dm
@@ -0,0 +1,94 @@
+
+
+/obj/effect/proc_holder/spell/grope
+ name = "Grope"
+ desc = "Spawns magical hands of groping."
+ charge_max = 1200 //variable
+ cooldown_min = 0
+ level_max = 1
+ clothes_req = NONE
+ antimagic_allowed = TRUE
+ action_icon_state = "grope"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ var/mob/living/carbon/human/victim
+ clothes_req = NONE
+
+/obj/effect/proc_holder/spell/grope/choose_targets(mob/user = usr)
+ perform(user=user)
+
+/obj/effect/proc_holder/spell/grope/perform(list/targets, recharge = 1, mob/user = usr)
+ var/list/possible = list()
+ for(var/mob/living/carbon/human/H in view(7, user))
+ if(H?.client?.prefs?.magicalpref == "No")
+ continue
+ possible.Add(H)
+ victim = input(user, "Choose the one to be groped", "Command") in possible
+ if(QDELETED(src) || QDELETED(user))
+ return
+ if(!victim)
+ revert_cast(user)
+ return
+ ..()
+
+/obj/effect/proc_holder/spell/grope/cast(list/targets, mob/user = usr)
+ victim.be_groped(user)
+
+/mob/living/carbon/human
+ var/is_being_groped = 0
+
+/mob/living/carbon/human/proc/be_groped(var/mob/living/carbon/human/H)
+ is_being_groped = H
+ update_groped_icon()
+
+/mob/living/carbon/human/proc/update_groped_icon()
+ if(is_being_groped)
+ var/mutable_appearance/new_groping_overlay = mutable_appearance('modular_splurt/icons/effects/sex_spells.dmi', "grope overlay", -GROPING_LAYER)
+ overlays_standing[GROPING_LAYER] = new_groping_overlay
+ apply_overlay(GROPING_LAYER)
+ else
+ overlays_standing[GROPING_LAYER] = null
+ return 0
+
+/mob/living/carbon/human/Life()
+ . = ..()
+ if(is_being_groped)
+ var/datum/interaction/I
+ if(prob(50))
+ I = SSinteractions.interactions["/datum/interaction/lewd/titgrope_self"]
+ I.do_action(is_being_groped, src, TRUE)
+ else
+ I = SSinteractions.interactions["/datum/interaction/lewd/fingerass_self"]
+ I.do_action(is_being_groped, src, TRUE)
+
+
+/datum/quirk/sex_magician
+ name = "Sex Magician"
+ desc = "You can cast sexual spells into others."
+ value = 1
+ mob_trait = TRAIT_SEXSPELLS
+ gain_text = "You can cast sexual spells."
+ lose_text = "You forget how to cast sexual spells."
+ medical_record_text = "Patient brain scans show a highly-developed into sexual spells."
+
+/datum/quirk/sex_magician/on_spawn()
+ var/mob/living/carbon/human/H = quirk_holder
+ var/obj/effect/proc_holder/spell/grope/S = new /obj/effect/proc_holder/spell/grope
+ var/obj/effect/proc_holder/spell/targeted/touch/penis_max/P = new /obj/effect/proc_holder/spell/targeted/touch/penis_max
+ var/obj/effect/proc_holder/spell/targeted/touch/penis/PP = new /obj/effect/proc_holder/spell/targeted/touch/penis
+ var/obj/effect/proc_holder/spell/self/eyes_of_lust/eol = new /obj/effect/proc_holder/spell/self/eyes_of_lust
+ var/obj/effect/proc_holder/spell/hypno/hyp = new /obj/effect/proc_holder/spell/hypno
+ var/obj/effect/proc_holder/spell/self/aoe_lust/aoe = new /obj/effect/proc_holder/spell/self/aoe_lust
+ var/obj/effect/proc_holder/spell/targeted/touch/uncover/unc = new /obj/effect/proc_holder/spell/targeted/touch/uncover
+ H.mind.AddSpell(S)
+ H.mind.AddSpell(P)
+ H.mind.AddSpell(PP)
+ H.mind.AddSpell(eol)
+ H.mind.AddSpell(hyp)
+ H.mind.AddSpell(aoe)
+ H.mind.AddSpell(unc)
+ //H.add_arousal_hud()
+
+
+
+
+
diff --git a/modular_splurt/code/modules/spell/spell_types/hypnotize.dm b/modular_splurt/code/modules/spell/spell_types/hypnotize.dm
new file mode 100644
index 000000000000..ee785fede0f0
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/hypnotize.dm
@@ -0,0 +1,38 @@
+
+
+/obj/effect/proc_holder/spell/hypno
+ name = "Hypnotize"
+ desc = "Hypnotize someone with a phrase."
+ charge_max = 1200 //variable
+ cooldown_min = 0
+ level_max = 1
+ clothes_req = NONE
+ antimagic_allowed = TRUE
+ action_icon_state = "hypno"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ var/mob/living/carbon/human/victim
+ var/hypnophrase
+ clothes_req = NONE
+
+/obj/effect/proc_holder/spell/hypno/choose_targets(mob/user = usr)
+ perform(user=user)
+
+/obj/effect/proc_holder/spell/hypno/perform(list/targets, recharge = 1, mob/user = usr)
+ var/list/possible = list()
+ for(var/mob/living/carbon/human/H in view(7, user))
+ if(H?.client?.prefs?.magicalpref == "No")
+ continue
+ possible.Add(H)
+ victim = input(user, "Choose the one to be hypnotized", "Command") in possible
+ hypnophrase = input(user, "Choose the phrase", "Command") as text
+ if(QDELETED(src) || QDELETED(user))
+ return
+ if(!victim)
+ revert_cast(user)
+ return
+ ..()
+
+/obj/effect/proc_holder/spell/hypno/cast(list/targets, mob/user = usr)
+ addtimer(CALLBACK(victim, /mob/living/carbon.proc/gain_trauma, /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, hypnophrase), 10)
+
+
diff --git a/modular_splurt/code/modules/spell/spell_types/penis_spells.dm b/modular_splurt/code/modules/spell/spell_types/penis_spells.dm
new file mode 100644
index 000000000000..12c450253491
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/penis_spells.dm
@@ -0,0 +1,86 @@
+
+/obj/effect/proc_holder/spell/targeted/touch/penis_max
+ name = "Penis Grower"
+ desc = "This spell charges your hand with vile energy that can be used to grow penises."
+ hand_path = /obj/item/melee/touch_attack/penis_max
+ school = "evocation"
+ charge_max = 600
+ cooldown_min = 200 //100 deciseconds reduction per rank
+ action_icon_state = "penis-increased"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ clothes_req = NONE
+
+/obj/item/melee/touch_attack/penis_max
+ name = "\improper penis increase touch"
+ desc = "This hand of mine glows with an erotic power!"
+ catchphrase = "Dicogrand!!"
+ on_use_sound = 'sound/magic/disintegrate.ogg'
+ icon_state = "disintegrate"
+ item_state = "disintegrate"
+
+/obj/item/melee/touch_attack/penis_max/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad
+ return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out!")
+ return
+ var/mob/M = target
+ do_sparks(4, FALSE, M.loc)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H?.client?.prefs?.magicalpref == "No")
+ return
+ else
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
+ P.modify_size(30)
+ spawn(15 MINUTES)
+ P.modify_size(-30)
+ return ..()
+
+
+
+
+
+
+
+/obj/effect/proc_holder/spell/targeted/touch/penis
+ name = "Penis Grower"
+ desc = "This spell charges your hand with vile energy that can be used to grow penises."
+ hand_path = /obj/item/melee/touch_attack/penis
+ school = "evocation"
+ charge_max = 600
+ cooldown_min = 200 //100 deciseconds reduction per rank
+ action_icon_state = "penis-increase"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ clothes_req = NONE
+
+
+/obj/item/melee/touch_attack/penis
+ name = "\improper penis increase touch"
+ desc = "This hand of mine glows with an erotic power!"
+ catchphrase = "Dicogrand!!"
+ on_use_sound = 'sound/magic/disintegrate.ogg'
+ icon_state = "disintegrate"
+ item_state = "disintegrate"
+
+/obj/item/melee/touch_attack/penis/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad
+ return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out!")
+ return
+ var/mob/M = target
+ do_sparks(4, FALSE, M.loc)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H?.client?.prefs?.magicalpref == "No")
+ return
+ else
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
+ P.modify_size(10)
+ addtimer(CALLBACK(P, /obj/item/organ/genital/proc/modify_size, -10), 10 MINUTES)
+ return ..()
+
+
+
+
diff --git a/modular_splurt/code/modules/spell/spell_types/uncover.dm b/modular_splurt/code/modules/spell/spell_types/uncover.dm
new file mode 100644
index 000000000000..972f8965f286
--- /dev/null
+++ b/modular_splurt/code/modules/spell/spell_types/uncover.dm
@@ -0,0 +1,51 @@
+/mob/living/carbon/human
+ var/uncovered = 0
+
+/obj/effect/proc_holder/spell/targeted/touch/uncover
+ name = "Uncover"
+ desc = "This spell charges your hand with vile energy that can be used to uncover victims."
+ hand_path = /obj/item/melee/touch_attack/uncover
+ school = "evocation"
+ charge_max = 600
+ cooldown_min = 200 //100 deciseconds reduction per rank
+ action_icon_state = "uncover"
+ action_icon = 'modular_splurt/icons/effects/sex_spells.dmi'
+ clothes_req = NONE
+
+/obj/item/melee/touch_attack/uncover
+ name = "\improper uncover touch"
+ desc = "This hand of mine glows with an erotic power!"
+ catchphrase = "Dicogrand!!"
+ on_use_sound = 'sound/magic/disintegrate.ogg'
+ icon_state = "disintegrate"
+ item_state = "disintegrate"
+ var/mob/living/carbon/user_saved = null
+
+/mob/living/carbon/human/proc/remove_uncovered() //would be problematic adding it to the touch attack since it is deleted right after the hit.
+ if(uncovered)
+ uncovered = 0
+
+/obj/item/melee/touch_attack/uncover/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //exploding after touching yourself would be bad
+ return
+ if(!user.can_speak_vocal())
+ to_chat(user, "You can't get the words out!")
+ return
+ var/mob/M = target
+ do_sparks(4, FALSE, M.loc)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H?.client?.prefs?.magicalpref == "Yes")
+ for(var/obj/item/W in H)
+ H.dropItemToGround(W, 1)
+ if(!H.uncovered)
+ H.uncovered = 1
+ else
+ H.uncovered = 0
+ addtimer(CALLBACK(H, /mob/living/carbon/human/proc/remove_uncovered), 10 MINUTES)
+ return ..()
+
+
+
+
+
diff --git a/modular_splurt/icons/effects/sex_spells.dmi b/modular_splurt/icons/effects/sex_spells.dmi
new file mode 100644
index 000000000000..458bf9240181
Binary files /dev/null and b/modular_splurt/icons/effects/sex_spells.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 717640c7a180..732b89348751 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -4514,8 +4514,8 @@
#include "modular_splurt\code\game\objects\items\armor_kits.dm"
#include "modular_splurt\code\game\objects\items\cards_ids.dm"
#include "modular_splurt\code\game\objects\items\cosmetics.dm"
-#include "modular_splurt\code\game\objects\items\gift.dm"
#include "modular_splurt\code\game\objects\items\fluff.dm"
+#include "modular_splurt\code\game\objects\items\gift.dm"
#include "modular_splurt\code\game\objects\items\granters.dm"
#include "modular_splurt\code\game\objects\items\holy_weapons.dm"
#include "modular_splurt\code\game\objects\items\manuals.dm"
@@ -5030,7 +5030,13 @@
#include "modular_splurt\code\modules\smithing\anvil.dm"
#include "modular_splurt\code\modules\smithing\finished_items.dm"
#include "modular_splurt\code\modules\smithing\smithed_items.dm"
+#include "modular_splurt\code\modules\spell\spell_types\aoe_lust.dm"
#include "modular_splurt\code\modules\spell\spell_types\conjure.dm"
+#include "modular_splurt\code\modules\spell\spell_types\eyes_of_lust.dm"
+#include "modular_splurt\code\modules\spell\spell_types\groping.dm"
+#include "modular_splurt\code\modules\spell\spell_types\hypnotize.dm"
+#include "modular_splurt\code\modules\spell\spell_types\penis_spells.dm"
+#include "modular_splurt\code\modules\spell\spell_types\uncover.dm"
#include "modular_splurt\code\modules\surgery\bodyparts\_bodyparts.dm"
#include "modular_splurt\code\modules\surgery\organs\augments_arms.dm"
#include "modular_splurt\code\modules\surgery\organs\augments_eyes.dm"