Merge remote-tracking branch 'citadel/master' into god_wish_your_plushies_holy_shit
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
/client/proc/citaPPoptions(mob/M) // why is this client and not /datum/admins? noone knows, in PP src == client, instead of holder. wtf.
|
||||
var/body = "<br>"
|
||||
if(M.client)
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makementor=[M.ckey]'>Make mentor</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];removementor=[M.ckey]'>Remove mentor</A>"
|
||||
return body
|
||||
|
||||
/client/proc/cmd_admin_man_up(mob/M in GLOB.mob_list)
|
||||
set category = "Special Verbs"
|
||||
set name = "Man Up"
|
||||
|
||||
if(!M)
|
||||
return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
to_chat(M, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
|
||||
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
|
||||
log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up")
|
||||
var/message = "<span class='adminnotice'>[key_name_admin(usr)] told [key_name_admin(M)] to man up.</span>"
|
||||
message_admins(message)
|
||||
admin_ticket_log(M, message)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up")
|
||||
|
||||
/client/proc/cmd_admin_man_up_global()
|
||||
set category = "Special Verbs"
|
||||
set name = "Man Up Global"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
to_chat(world, "<span class='warning bold reallybig'>Man up, and deal with it.</span><br><span class='warning big'>Move on.</span>")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
|
||||
log_admin("Man up global: [key_name(usr)] told everybody to man up")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] told everybody to man up.</span>")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global")
|
||||
@@ -1,59 +0,0 @@
|
||||
/datum/admins/proc/citaTopic(href, href_list)
|
||||
if(href_list["makementor"])
|
||||
makeMentor(href_list["makementor"])
|
||||
else if(href_list["removementor"])
|
||||
removeMentor(href_list["removementor"])
|
||||
|
||||
/datum/admins/proc/makeMentor(ckey)
|
||||
if(!usr.client)
|
||||
return
|
||||
if (!check_rights(0))
|
||||
return
|
||||
if(!ckey)
|
||||
return
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
if(C)
|
||||
if(check_rights_for(C, R_ADMIN,0))
|
||||
to_chat(usr, "<span class='danger'>The client chosen is an admin! Cannot mentorize.</span>")
|
||||
return
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
|
||||
if(query_get_mentor.NextRow())
|
||||
to_chat(usr, "<span class='danger'>[ckey] is already a mentor.</span>")
|
||||
return
|
||||
var/datum/DBQuery/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')")
|
||||
if(!query_add_mentor.warn_execute())
|
||||
return
|
||||
var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');")
|
||||
if(!query_add_admin_log.warn_execute())
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection. The changes will last only for the current round.</span>")
|
||||
new /datum/mentors(ckey)
|
||||
to_chat(usr, "<span class='adminnotice'>New mentor added.</span>")
|
||||
|
||||
/datum/admins/proc/removeMentor(ckey)
|
||||
if(!usr.client)
|
||||
return
|
||||
if (!check_rights(0))
|
||||
return
|
||||
if(!ckey)
|
||||
return
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
if(C)
|
||||
if(check_rights_for(C, R_ADMIN,0))
|
||||
to_chat(usr, "<span class='danger'>The client chosen is an admin, not a mentor! Cannot de-mentorize.</span>")
|
||||
return
|
||||
C.remove_mentor_verbs()
|
||||
C.mentor_datum = null
|
||||
GLOB.mentors -= C
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
|
||||
if(!query_remove_mentor.warn_execute())
|
||||
return
|
||||
var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');")
|
||||
if(!query_add_admin_log.warn_execute())
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection. The changes will last only for the current round.</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Mentor removed.</span>")
|
||||
@@ -1,17 +1,8 @@
|
||||
//Mob vars
|
||||
/mob/living
|
||||
var/arousalloss = 0 //How aroused the mob is.
|
||||
var/min_arousal = AROUSAL_MINIMUM_DEFAULT //The lowest this mobs arousal will get. default = 0
|
||||
var/max_arousal = AROUSAL_MAXIMUM_DEFAULT //The highest this mobs arousal will get. default = 100
|
||||
var/arousal_rate = AROUSAL_START_VALUE //The base rate that arousal will increase in this mob.
|
||||
var/arousal_loss_rate = AROUSAL_START_VALUE //How easily arousal can be relieved for this mob.
|
||||
var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types.
|
||||
var/mb_cd_length = 5 SECONDS //5 second cooldown for masturbating because fuck spam.
|
||||
var/mb_cd_timer = 0 //The timer itself
|
||||
|
||||
/mob/living/carbon/human
|
||||
canbearoused = TRUE
|
||||
|
||||
var/saved_underwear = ""//saves their underwear so it can be toggled later
|
||||
var/saved_undershirt = ""
|
||||
var/saved_socks = ""
|
||||
@@ -21,8 +12,6 @@
|
||||
|
||||
//Species vars
|
||||
/datum/species
|
||||
var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused
|
||||
var/arousal_lose_rate = AROUSAL_START_VALUE //Multiplier for how easily arousal can be relieved
|
||||
var/list/cum_fluids = list("semen")
|
||||
var/list/milk_fluids = list("milk")
|
||||
var/list/femcum_fluids = list("femcum")
|
||||
@@ -52,130 +41,26 @@
|
||||
|
||||
update_body()
|
||||
|
||||
/mob/living/proc/handle_arousal(times_fired)
|
||||
return
|
||||
|
||||
/mob/living/carbon/handle_arousal(times_fired)
|
||||
if(!canbearoused || !dna)
|
||||
return
|
||||
var/datum/species/S = dna.species
|
||||
if(!S || (times_fired % 36) || !getArousalLoss() >= max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
|
||||
return
|
||||
var/our_loss = arousal_rate * S.arousal_gain_rate
|
||||
if(HAS_TRAIT(src, TRAIT_EXHIBITIONIST) && client)
|
||||
var/amt_nude = 0
|
||||
/mob/living/carbon/human/proc/adjust_arousal(strength,aphro = FALSE,maso = FALSE) // returns all genitals that were adjust
|
||||
var/list/obj/item/organ/genital/genit_list = list()
|
||||
if(!client?.prefs.arousable || (aphro && (client?.prefs.cit_toggles & NO_APHRO)) || (maso && !HAS_TRAIT(src, TRAIT_MASO)))
|
||||
return // no adjusting made here
|
||||
if(strength>0)
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.is_exposed())
|
||||
amt_nude++
|
||||
if(amt_nude)
|
||||
var/watchers = 0
|
||||
for(var/mob/living/L in view(src))
|
||||
if(L.client && !L.stat && !L.eye_blind && (src in view(L)))
|
||||
watchers++
|
||||
if(watchers)
|
||||
our_loss += (amt_nude * watchers) + S.arousal_gain_rate
|
||||
adjustArousalLoss(our_loss)
|
||||
|
||||
/mob/living/proc/getArousalLoss()
|
||||
return arousalloss
|
||||
|
||||
/mob/living/proc/adjustArousalLoss(amount, updating_arousal=1)
|
||||
if(status_flags & GODMODE || !canbearoused)
|
||||
return FALSE
|
||||
arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal)
|
||||
if(updating_arousal)
|
||||
updatearousal()
|
||||
|
||||
/mob/living/proc/setArousalLoss(amount, updating_arousal=1)
|
||||
if(status_flags & GODMODE || !canbearoused)
|
||||
return FALSE
|
||||
arousalloss = CLAMP(amount, min_arousal, max_arousal)
|
||||
if(updating_arousal)
|
||||
updatearousal()
|
||||
|
||||
/mob/living/proc/getPercentAroused()
|
||||
var/percentage = ((100 / max_arousal) * arousalloss)
|
||||
return percentage
|
||||
|
||||
/mob/living/proc/isPercentAroused(percentage)//returns true if the mob's arousal (measured in a percent of 100) is greater than the arg percentage.
|
||||
if(!isnum(percentage) || percentage > 100 || percentage < 0)
|
||||
CRASH("Provided percentage is invalid")
|
||||
if(getPercentAroused() >= percentage)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//H U D//
|
||||
/mob/living/proc/updatearousal()
|
||||
update_arousal_hud()
|
||||
|
||||
/mob/living/carbon/updatearousal()
|
||||
. = ..()
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(istype(G))
|
||||
var/datum/sprite_accessory/S
|
||||
switch(G.type)
|
||||
if(/obj/item/organ/genital/penis)
|
||||
S = GLOB.cock_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/testicles)
|
||||
S = GLOB.balls_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
S = GLOB.vagina_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/breasts)
|
||||
S = GLOB.breasts_shapes_list[G.shape]
|
||||
if(S?.alt_aroused)
|
||||
G.aroused_state = isPercentAroused(G.aroused_amount)
|
||||
else
|
||||
G.aroused_state = FALSE
|
||||
G.update_appearance()
|
||||
|
||||
/mob/living/proc/update_arousal_hud()
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/update_arousal_hud()
|
||||
if(!client || !(hud_used?.arousal))
|
||||
return FALSE
|
||||
if(!canbearoused)
|
||||
hud_used.arousal.icon_state = ""
|
||||
return FALSE
|
||||
if(!G.aroused_state && prob(strength*G.sensitivity))
|
||||
G.set_aroused_state(TRUE)
|
||||
G.update_appearance()
|
||||
if(G.aroused_state)
|
||||
genit_list += G
|
||||
else
|
||||
var/value = FLOOR(getPercentAroused(), 10)
|
||||
hud_used.arousal.icon_state = "arousal[value]"
|
||||
return TRUE
|
||||
|
||||
/obj/screen/arousal
|
||||
name = "arousal"
|
||||
icon_state = "arousal0"
|
||||
icon = 'modular_citadel/icons/obj/genitals/hud.dmi'
|
||||
screen_loc = ui_arousal
|
||||
|
||||
/obj/screen/arousal/Click()
|
||||
if(!isliving(usr))
|
||||
return FALSE
|
||||
var/mob/living/M = usr
|
||||
if(M.canbearoused)
|
||||
M.mob_climax()
|
||||
return TRUE
|
||||
else
|
||||
to_chat(M, "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>")
|
||||
|
||||
|
||||
/mob/living/proc/mob_climax(forced_climax = FALSE)//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
|
||||
set name = "Masturbate"
|
||||
set category = "IC"
|
||||
if(canbearoused && !restrained() && !stat)
|
||||
if(mb_cd_timer <= world.time)
|
||||
//start the cooldown even if it fails
|
||||
mb_cd_timer = world.time + mb_cd_length
|
||||
if(getArousalLoss() >= 33)//one third of average max_arousal or greater required
|
||||
visible_message("<span class='danger'>[src] starts masturbating!</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, 30, target = src))
|
||||
visible_message("<span class='danger'>[src] relieves [p_them()]self!</span>", \
|
||||
"<span class='userdanger'>You have relieved yourself.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
setArousalLoss(min_arousal)
|
||||
else
|
||||
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.aroused_state && prob(strength*G.sensitivity))
|
||||
G.set_aroused_state(FALSE)
|
||||
G.update_appearance()
|
||||
if(G.aroused_state)
|
||||
genit_list += G
|
||||
return genit_list
|
||||
|
||||
/obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found.
|
||||
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
|
||||
@@ -189,48 +74,25 @@
|
||||
/mob/living/carbon/human/proc/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill = TRUE)
|
||||
if(!G)
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
setArousalLoss(min_arousal)
|
||||
if(!target || !R)
|
||||
return
|
||||
var/turfing = isturf(target)
|
||||
if(spill & R.total_volume >= 5)
|
||||
if(spill && R.total_volume >= 5)
|
||||
R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
|
||||
if(!turfing)
|
||||
R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
|
||||
R.clear_reagents()
|
||||
|
||||
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
|
||||
//For all of these, we assume the arguments given are proper and have been checked beforehand.
|
||||
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
|
||||
var/datum/reagents/fluid_source = G.climaxable(src)
|
||||
if(!fluid_source)
|
||||
return
|
||||
var/obj/item/organ/genital/PP = CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) ? G.linked_organ : G
|
||||
if(!PP)
|
||||
to_chat(src, "<span class='warning'>You shudder, unable to cum with your [name].</span>")
|
||||
if(mb_time)
|
||||
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name].</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
visible_message("<span class='love'>[src] orgasms, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with [p_their()] [PP.name]!</span>", \
|
||||
"<span class='userlove'>You orgasm, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with your [PP.name].</span>")
|
||||
do_climax(fluid_source, loc, G)
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
|
||||
var/datum/reagents/fluid_source = G.climaxable(src, TRUE)
|
||||
if(!fluid_source)
|
||||
visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
|
||||
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
|
||||
visible_message("<span class='love'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='userlove'>You feel yourself about to orgasm.</span>")
|
||||
to_chat(src,"<span class='userlove'>You feel yourself about to orgasm.</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
visible_message("<span class='love'>[src] orgasms[isturf(loc) ? " onto [loc]" : ""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name].</span>")
|
||||
to_chat(src,"<span class='userlove'>You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name].</span>")
|
||||
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) //Used for climaxing with any living thing
|
||||
@@ -238,48 +100,30 @@
|
||||
if(!fluid_source)
|
||||
return
|
||||
if(mb_time) //Skip warning if this is an instant climax.
|
||||
visible_message("<span class='love'>[src] is about to climax with [L]!</span>", \
|
||||
"<span class='userlove'>You're about to climax with [L]!</span>")
|
||||
to_chat(src,"<span class='userlove'>You're about to climax with [L]!</span>")
|
||||
to_chat(L,"<span class='userlove'>[src] is about to climax with you!</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !in_range(src, L) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
if(spillage)
|
||||
visible_message("<span class='love'>[src] climaxes with [L], overflowing and spilling, using [p_their()] [G.name]!</span>", \
|
||||
"<span class='userlove'>You orgasm with [L], spilling out of them, using your [G.name].</span>")
|
||||
to_chat(src,"<span class='userlove'>You orgasm with [L], spilling out of them, using your [G.name].</span>")
|
||||
to_chat(L,"<span class='userlove'>[src] climaxes with you, overflowing and spilling, using [p_their()] [G.name]!</span>")
|
||||
else //knots and other non-spilling orgasms
|
||||
visible_message("<span class='love'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
|
||||
"<span class='userlove'>You ejaculate with [L], your [G.name] spilling nothing.</span>")
|
||||
to_chat(src,"<span class='userlove'>You climax with [L], your [G.name] spilling nothing.</span>")
|
||||
to_chat(L,"<span class='userlove'>[src] climaxes with you, [p_their()] [G.name] spilling nothing!</span>")
|
||||
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
|
||||
do_climax(fluid_source, spillage ? loc : L, G, spillage)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
|
||||
var/datum/reagents/fluid_source = G.climaxable(src)
|
||||
if(!fluid_source)
|
||||
return
|
||||
if(mb_time)
|
||||
visible_message("<span class='love'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
|
||||
"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>")
|
||||
to_chat(src,"<span class='userlove'>You start to [G.masturbation_verb] your [G.name] over [container].</span>")
|
||||
if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
|
||||
return
|
||||
visible_message("<span class='love'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
|
||||
"<span class='userlove'>You used your [G.name] to fill [container].</span>")
|
||||
to_chat(src,"<span class='userlove'>You used your [G.name] to fill [container].</span>")
|
||||
do_climax(fluid_source, container, G, FALSE)
|
||||
|
||||
/mob/living/carbon/human/proc/pick_masturbate_genitals(silent = FALSE)
|
||||
var/list/genitals_list
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(CHECK_BITFIELD(G.genital_flags, CAN_MASTURBATE_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
|
||||
if(CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) && !G.linked_organ)
|
||||
continue
|
||||
LAZYADD(genitals_list, G)
|
||||
if(LAZYLEN(genitals_list))
|
||||
var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
else if(!silent)
|
||||
to_chat(src, "<span class='warning'>You cannot masturbate without available genitals.</span>")
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_genitals(silent = FALSE)
|
||||
var/list/genitals_list
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
@@ -301,6 +145,8 @@
|
||||
partners += pulledby
|
||||
//Now we got both of them, let's check if they're proper
|
||||
for(var/mob/living/L in partners)
|
||||
if(!L.client || !L.mind) // can't consent, not a partner
|
||||
partners -= L
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed()) //Nothing through_clothing, no proper partner.
|
||||
@@ -312,7 +158,9 @@
|
||||
return //No one left.
|
||||
var/mob/living/target = input(src, "With whom?", "Sexual partner", null) as null|anything in partners //pick one, default to null
|
||||
if(target && in_range(src, target))
|
||||
return target
|
||||
var/consenting = input(target, "Do you want [src] to climax with you?","Climax mechanics","No") in list("Yes","No")
|
||||
if(consenting == "Yes")
|
||||
return target
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_container(silent = FALSE)
|
||||
var/list/containers_list = list()
|
||||
@@ -349,13 +197,13 @@
|
||||
return TRUE
|
||||
|
||||
//Here's the main proc itself
|
||||
/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
|
||||
/mob/living/carbon/human/proc/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
|
||||
if(mb_cd_timer > world.time)
|
||||
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
|
||||
to_chat(src, "<span class='warning'>You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!</span>")
|
||||
return
|
||||
|
||||
if(!canbearoused || !has_dna())
|
||||
if(!client?.prefs.arousable || !has_dna())
|
||||
return
|
||||
if(stat == DEAD)
|
||||
if(!forced_climax)
|
||||
@@ -398,32 +246,19 @@
|
||||
if(stat == UNCONSCIOUS) //No sleep-masturbation, you're unconscious.
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
return
|
||||
if(getArousalLoss() < 33) //flat number instead of percentage
|
||||
to_chat(src, "<span class='warning'>You aren't aroused enough for that!</span>")
|
||||
return
|
||||
|
||||
//Ok, now we check what they want to do.
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") as null|anything in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") as null|anything in list("Climax alone","Climax with partner", "Fill container")
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
switch(choice)
|
||||
if("Masturbate")
|
||||
if(!available_rosie_palms())
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ && available_rosie_palms(TRUE))
|
||||
mob_masturbate(picked_organ)
|
||||
return
|
||||
|
||||
if("Climax alone")
|
||||
if(!available_rosie_palms())
|
||||
return
|
||||
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
|
||||
if(picked_organ && available_rosie_palms(TRUE))
|
||||
mob_climax_outside(picked_organ)
|
||||
|
||||
if("Climax with partner")
|
||||
//We need no hands, we can be restrained and so on, so let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
|
||||
@@ -433,7 +268,6 @@
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as null|anything in list("Yes", "No")
|
||||
if(spillage && in_range(src, partner))
|
||||
mob_climax_partner(picked_organ, partner, spillage == "Yes" ? TRUE : FALSE)
|
||||
|
||||
if("Fill container")
|
||||
//We'll need hands and no restraints.
|
||||
if(!available_rosie_palms(FALSE, /obj/item/reagent_containers))
|
||||
@@ -447,4 +281,10 @@
|
||||
if(fluid_container && available_rosie_palms(TRUE, /obj/item/reagent_containers))
|
||||
mob_fill_container(picked_organ, fluid_container)
|
||||
|
||||
mb_cd_timer = world.time + mb_cd_length
|
||||
mb_cd_timer = world.time + mb_cd_length
|
||||
|
||||
/mob/living/carbon/human/verb/climax_verb()
|
||||
set category = "IC"
|
||||
set name = "Climax"
|
||||
set desc = "Lets you choose a couple ways to ejaculate."
|
||||
mob_climax()
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
color = "#fcccb3"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/shape = "human"
|
||||
var/sensitivity = AROUSAL_START_VALUE
|
||||
var/sensitivity = 1 // wow if this were ever used that'd be cool but it's not but i'm keeping it for my unshit code
|
||||
var/genital_flags //see citadel_defines.dm
|
||||
var/masturbation_verb = "masturbate"
|
||||
var/orgasm_verb = "cumming" //present continous
|
||||
var/arousal_verb = "You feel aroused"
|
||||
var/unarousal_verb = "You no longer feel aroused"
|
||||
var/fluid_transfer_factor = 0 //How much would a partner get in them if they climax using this?
|
||||
var/size = 2 //can vary between num or text, just used in icon_state strings
|
||||
var/datum/reagent/fluid_id = null
|
||||
@@ -14,7 +16,6 @@
|
||||
var/fluid_rate = CUM_RATE
|
||||
var/fluid_mult = 1
|
||||
var/aroused_state = FALSE //Boolean used in icon_state strings
|
||||
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
|
||||
var/obj/item/organ/genital/linked_organ
|
||||
var/linked_organ_slot //used for linking an apparatus' organ to its other half on update_link().
|
||||
var/layer_index = GENITAL_LAYER_INDEX //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
|
||||
@@ -38,6 +39,11 @@
|
||||
Remove(owner, TRUE)//this should remove references to it, so it can be GCd correctly
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/genital/proc/set_aroused_state(new_state)
|
||||
if(!((HAS_TRAIT(owner,TRAIT_PERMABONER) && !new_state) || HAS_TRAIT(owner,TRAIT_NEVERBONER) && new_state))
|
||||
aroused_state = new_state
|
||||
return aroused_state
|
||||
|
||||
/obj/item/organ/genital/proc/update(removing = FALSE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
@@ -90,11 +96,9 @@
|
||||
set desc = "Allows you to toggle which genitals should show through clothes or not."
|
||||
|
||||
var/list/genital_list = list()
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(isgenital(O))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL))
|
||||
genital_list += G
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL))
|
||||
genital_list += G
|
||||
if(!genital_list.len) //There is nothing to expose
|
||||
return
|
||||
//Full list of exposable genitals created
|
||||
@@ -105,6 +109,39 @@
|
||||
picked_organ.toggle_visibility(picked_visibility)
|
||||
return
|
||||
|
||||
/mob/living/carbon/verb/toggle_arousal_state()
|
||||
set category = "IC"
|
||||
set name = "Toggle genital arousal"
|
||||
set desc = "Allows you to toggle which genitals are showing signs of arousal."
|
||||
var/list/genital_list = list()
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
var/datum/sprite_accessory/S
|
||||
switch(G.type)
|
||||
if(/obj/item/organ/genital/penis)
|
||||
S = GLOB.cock_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/testicles)
|
||||
S = GLOB.balls_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
S = GLOB.vagina_shapes_list[G.shape]
|
||||
if(/obj/item/organ/genital/breasts)
|
||||
S = GLOB.breasts_shapes_list[G.shape]
|
||||
if(S?.alt_aroused)
|
||||
genital_list += G
|
||||
if(!genital_list.len) //There's nothing that can show arousal
|
||||
return
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = input(src, "Choose which genitalia to toggle arousal on", "Set genital arousal", null) in genital_list
|
||||
if(picked_organ)
|
||||
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>")
|
||||
else
|
||||
to_chat(src,"<span class='userlove'>You can't make that genital [picked_organ.aroused_state ? "unaroused" : "aroused"]!</span>")
|
||||
picked_organ.update_appearance()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/organ/genital/proc/modify_size(modifier, min = -INFINITY, max = INFINITY)
|
||||
fluid_max_volume += modifier*2.5
|
||||
fluid_rate += modifier/10
|
||||
@@ -233,7 +270,7 @@
|
||||
|
||||
//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
|
||||
/mob/living/carbon/human/proc/emergent_genital_call()
|
||||
if(!canbearoused)
|
||||
if(!client.prefs.arousable)
|
||||
return FALSE
|
||||
|
||||
var/organCheck = locate(/obj/item/organ/genital) in internal_organs
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
shape = "pair"
|
||||
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION
|
||||
masturbation_verb = "massage"
|
||||
arousal_verb = "Your breasts start feeling sensitive"
|
||||
unarousal_verb = "Your breasts no longer feel sensitive"
|
||||
orgasm_verb = "leaking"
|
||||
fluid_transfer_factor = 0.5
|
||||
var/static/list/breast_values = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_PENIS
|
||||
masturbation_verb = "stroke"
|
||||
arousal_verb = "You pop a boner"
|
||||
unarousal_verb = "Your boner goes down"
|
||||
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
|
||||
linked_organ_slot = ORGAN_SLOT_TESTICLES
|
||||
fluid_transfer_factor = 0.5
|
||||
@@ -26,7 +28,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/organ/genital/penis/update_size(modified = FALSE)
|
||||
if(length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
|
||||
if(length <= 0)//I don't actually know what round() does to negative numbers, so to be safe!!
|
||||
if(owner)
|
||||
to_chat(owner, "<span class='warning'>You feel your tallywacker shrinking away from your body as your groin flattens out!</b></span>")
|
||||
QDEL_IN(src, 1)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_TESTICLES
|
||||
size = BALLS_SIZE_MIN
|
||||
arousal_verb = "Your balls ache a little"
|
||||
unarousal_verb = "Your balls finally stop aching, again"
|
||||
linked_organ_slot = ORGAN_SLOT_PENIS
|
||||
genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION
|
||||
var/size_name = "average"
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
size = 1 //There is only 1 size right now
|
||||
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
|
||||
masturbation_verb = "finger"
|
||||
arousal_verb = "You feel wetness on your crotch."
|
||||
unarousal_verb = "You no longer feel wet."
|
||||
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
|
||||
layer_index = VAGINA_LAYER_INDEX
|
||||
var/cap_length = 8//D E P T H (cap = capacity)
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
name = "dildo"
|
||||
desc = "Floppy!"
|
||||
icon = 'modular_citadel/icons/obj/genitals/dildo.dmi'
|
||||
damtype = AROUSAL
|
||||
force = 5
|
||||
force = 0
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
throwforce = 0
|
||||
icon_state = "dildo_knotted_2"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/gear/greytidestationwide
|
||||
name = "Grey jumpsuit"
|
||||
name = "Staff Assistant's jumpsuit"
|
||||
category = SLOT_W_UNIFORM
|
||||
path = /obj/item/clothing/under/color/grey
|
||||
path = /obj/item/clothing/under/staffassistant
|
||||
restricted_roles = list("Assistant")
|
||||
|
||||
/datum/gear/neetsuit
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
restricted_desc = "Engineering, Security, and Cargo"
|
||||
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
|
||||
|
||||
/*Commenting out Until next Christmas or made automatic
|
||||
/datum/gear/santahatr
|
||||
name = "Red Santa Hat"
|
||||
category = SLOT_HEAD
|
||||
@@ -102,6 +103,7 @@
|
||||
name = "Green Santa Hat"
|
||||
category = SLOT_HEAD
|
||||
path = /obj/item/clothing/head/christmashatg
|
||||
*/
|
||||
|
||||
/datum/gear/cowboyhat
|
||||
name = "Cowboy Hat, Brown"
|
||||
@@ -129,6 +131,3 @@
|
||||
path = /obj/item/clothing/head/cowboyhat/sec
|
||||
restricted_desc = "Security"
|
||||
restricted_roles = list("Warden","Detective","Security Officer","Head of Security")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
path = /obj/item/clothing/under/gear_harness
|
||||
|
||||
//Christmas
|
||||
/*Commenting out Until next Christmas or made automatic
|
||||
/datum/gear/christmasmaler
|
||||
name = "Red Masculine Christmas Suit"
|
||||
category = SLOT_W_UNIFORM
|
||||
@@ -415,6 +416,7 @@
|
||||
category = SLOT_W_UNIFORM
|
||||
path = /obj/item/clothing/under/stripper_pink
|
||||
cost = 3
|
||||
*/
|
||||
|
||||
/datum/gear/greenstripper
|
||||
name = "Green stripper outfit"
|
||||
|
||||
@@ -49,10 +49,9 @@
|
||||
if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT)
|
||||
return TRUE
|
||||
|
||||
datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates = 1)
|
||||
/datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates = 1)
|
||||
..()
|
||||
character.give_genitals(TRUE)
|
||||
character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially
|
||||
character.canbearoused = arousable
|
||||
if(icon_updates)
|
||||
character.update_genitals()
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/obj/item/integrated_circuit/manipulation/electric_stimulator
|
||||
name = "electronic stimulation module"
|
||||
desc = "Used to induce sexual stimulation in a target via electricity."
|
||||
icon_state = "power_relay"
|
||||
extended_desc = "The circuit accepts a reference to a person, as well as a number representing the strength of the shock, and upon activation, attempts to stimulate them to orgasm. The number ranges from -35 to 35, with negative numbers reducing arousal and positive numbers increasing it by that amount."
|
||||
complexity = 15
|
||||
size = 2
|
||||
inputs = list("target" = IC_PINTYPE_REF, "strength" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("arousal gain"=IC_PINTYPE_NUMBER)
|
||||
activators = list("fire" = IC_PINTYPE_PULSE_IN, "on success" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT, "on orgasm" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 500
|
||||
cooldown_per_use = 50
|
||||
ext_cooldown = 25
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/electric_stimulator/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, 0)
|
||||
var/mob/living/M = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
if(!check_target(M))
|
||||
return
|
||||
|
||||
var/arousal_gain = CLAMP(get_pin_data(IC_INPUT, 2),-35,35)
|
||||
set_pin_data(IC_OUTPUT, 1, arousal_gain)
|
||||
|
||||
if(ismob(M) && M.canbearoused && arousal_gain != 0)
|
||||
var/orgasm = FALSE
|
||||
if(arousal_gain > 0)
|
||||
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/orgasm_message = pick("A sharp pulse of electricity pushes you to orgasm!", "You feel a jolt of electricity force you into orgasm!")
|
||||
H.visible_message("<span class='warning'>\The [assembly] electrodes shock [H]!</span>", "<span class='warning'>[orgasm_message]</span>")
|
||||
playsound(src, "sound/effects/light_flicker.ogg", 30, 1)
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
orgasm = TRUE
|
||||
else
|
||||
M.adjustArousalLoss(arousal_gain)
|
||||
var/stimulate_message = pick("You feel a sharp warming tingle of electricity through your body!", "A burst of arousing electricity flows through your body!")
|
||||
M.visible_message("<span class='warning'>\The [assembly] electrodes shock [M]!</span>", "<span class='warning'>[stimulate_message]</span>")
|
||||
|
||||
else
|
||||
var/stimulate_message = pick("You feel a dull prickle of electricity through your body!", "A burst of dull electricity flows through your body!")
|
||||
M.visible_message("<span class='warning'>\The [assembly] electrodes shock [M]!</span>", "<span class='warning'>[stimulate_message]</span>")
|
||||
M.adjustArousalLoss(arousal_gain)
|
||||
|
||||
playsound(src, "sound/effects/light_flicker.ogg", 30, 1)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
if(orgasm) activate_pin(4)
|
||||
|
||||
else
|
||||
visible_message("<span class='warning'>\The [assembly] electrodes fail to shock [M]!</span>")
|
||||
push_data()
|
||||
activate_pin(3)
|
||||
@@ -416,14 +416,14 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1)
|
||||
weather_immunities -= "lava"
|
||||
|
||||
/mob/living/silicon/robot/throw_impact(atom/A)
|
||||
/mob/living/silicon/robot/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
|
||||
if(!leaping)
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(hit_atom)
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/L = hit_atom
|
||||
if(!L.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Knockdown(iscarbon(L) ? 60 : 45, override_stamdmg = CLAMP(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
|
||||
@@ -437,8 +437,8 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
spawn(pounce_cooldown_time) //3s by default
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>")
|
||||
else if(hit_atom.density && !hit_atom.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [hit_atom]!</span>", "<span class ='userdanger'>You smash into [hit_atom]!</span>")
|
||||
playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
|
||||
Knockdown(15, 1, 1)
|
||||
|
||||
|
||||
@@ -78,3 +78,13 @@
|
||||
build_path = /obj/item/ammo_box/a357
|
||||
category = list("Ammo")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
/datum/design/sl357ap
|
||||
name = "revolver speedloader (.357 AP)"
|
||||
desc = "A revolver speedloader. Cuts through like a hot knife through butter."
|
||||
id = "sl357ap"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 30000, MAT_TITANIUM = 45000)
|
||||
build_path = /obj/item/ammo_box/a357/ap
|
||||
category = list("Ammo")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
|
||||
|
||||
@@ -66,6 +66,7 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
knockdown = 0
|
||||
|
||||
/obj/item/projectile/bullet/c10mm/soporific/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if((blocked != 100) && isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.blur_eyes(6)
|
||||
@@ -73,7 +74,6 @@ obj/item/projectile/bullet/c10mm/soporific
|
||||
L.Sleeping(300)
|
||||
else
|
||||
L.adjustStaminaLoss(25)
|
||||
return 1
|
||||
|
||||
/obj/item/ammo_casing/c10mm/soporific
|
||||
name = ".10mm soporific bullet casing"
|
||||
|
||||
@@ -355,7 +355,7 @@
|
||||
damage = 10
|
||||
armour_penetration = 10
|
||||
stamina = 10
|
||||
forcedodge = TRUE
|
||||
movement_type = FLYING | UNSTOPPABLE
|
||||
range = 6
|
||||
light_range = 1
|
||||
light_color = LIGHT_COLOR_RED
|
||||
@@ -363,14 +363,14 @@
|
||||
/obj/item/projectile/bullet/mags/hyper/inferno
|
||||
icon_state = "magjectile-large"
|
||||
stamina = 0
|
||||
forcedodge = FALSE
|
||||
movement_type = FLYING | UNSTOPPABLE
|
||||
range = 25
|
||||
light_range = 4
|
||||
|
||||
/obj/item/projectile/bullet/mags/hyper/inferno/on_hit(atom/target, blocked = FALSE)
|
||||
..()
|
||||
explosion(target, -1, 1, 2, 4, 5)
|
||||
return 1
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
///ammo casings///
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
|
||||
icon_state = "magjectile-toy"
|
||||
name = "lasertag magbolt"
|
||||
forcedodge = TRUE //for penetration memes
|
||||
movement_type = FLYING | UNSTOPPABLE //for penetration memes
|
||||
range = 5 //so it isn't super annoying
|
||||
light_range = 2
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/obj/item/projectile/bullet/spinfusor/on_hit(atom/target, blocked = FALSE) //explosion to emulate the spinfusor's AOE
|
||||
..()
|
||||
explosion(target, -1, -1, 2, 0, -1)
|
||||
return 1
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/obj/item/ammo_casing/caseless/spinfusor
|
||||
name = "spinfusor disk"
|
||||
|
||||
@@ -308,8 +308,6 @@ Creating a chem with a low purity will make you permanently fall in love with so
|
||||
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times people have bonded")
|
||||
else
|
||||
if(get_dist(M, love) < 8)
|
||||
if(HAS_TRAIT(M, TRAIT_NYMPHO)) //Add this back when merged/updated.
|
||||
M.adjustArousalLoss(5)
|
||||
var/message = "[(lewd?"I'm next to my crush..! Eee!":"I'm making friends with [love]!")]"
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "InLove", /datum/mood_event/InLove, message)
|
||||
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "MissingLove")
|
||||
|
||||
@@ -97,14 +97,18 @@
|
||||
color = "#FFADFF"//PINK, rgb(255, 173, 255)
|
||||
|
||||
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M)
|
||||
if(M && M.canbearoused && !(M.client?.prefs.cit_toggles & NO_APHRO))
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(2)
|
||||
if(prob(5))
|
||||
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO))
|
||||
if((prob(min(current_cycle/2,5))))
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
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>")
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/genits = H.adjust_arousal(current_cycle, 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>")
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus
|
||||
@@ -118,21 +122,26 @@
|
||||
overdose_threshold = 20
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M)
|
||||
if(M && M.canbearoused && !(M.client?.prefs.cit_toggles & NO_APHRO))
|
||||
if(prob(33))
|
||||
M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful.
|
||||
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO))
|
||||
if(prob(5))
|
||||
if(M.getArousalLoss() > 75)
|
||||
if(prob(current_cycle))
|
||||
M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn..."))
|
||||
else
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message
|
||||
if(M.getArousalLoss() > 90)
|
||||
if(current_cycle>25)
|
||||
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>")
|
||||
REMOVE_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/genits = H.adjust_arousal(100, 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>")
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
|
||||
@@ -150,15 +159,11 @@
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
|
||||
if(M && M.canbearoused && !(M.client?.prefs.cit_toggles & NO_APHRO) && prob(33))
|
||||
if(prob(5) && M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
|
||||
if(prob(5)) //Less spam
|
||||
to_chat(M, "<span class='love'>Your libido is going haywire!</span>")
|
||||
if(M.min_arousal < 50)
|
||||
M.min_arousal += 1
|
||||
if(M.min_arousal < M.max_arousal)
|
||||
M.min_arousal += 1
|
||||
M.adjustArousalLoss(2)
|
||||
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>")
|
||||
ADD_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT)
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/anaphrodisiac
|
||||
@@ -171,8 +176,12 @@
|
||||
reagent_state = SOLID
|
||||
|
||||
/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M)
|
||||
if(M && M.canbearoused && prob(33))
|
||||
M.adjustArousalLoss(-2)
|
||||
if(M && M.client?.prefs.arousable && prob(16))
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/genits = H.adjust_arousal(-100, aphro = TRUE)
|
||||
if(genits.len)
|
||||
to_chat(M, "<span class='notice'>You no longer feel aroused.")
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/anaphrodisiacplus
|
||||
@@ -184,17 +193,20 @@
|
||||
overdose_threshold = 20
|
||||
|
||||
/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M)
|
||||
if(M && M.canbearoused && prob(33))
|
||||
M.adjustArousalLoss(-4)
|
||||
if(M && M.client?.prefs.arousable)
|
||||
REMOVE_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/genits = H.adjust_arousal(-100, aphro = TRUE)
|
||||
if(genits.len)
|
||||
to_chat(M, "<span class='notice'>You no longer feel aroused.")
|
||||
|
||||
..()
|
||||
|
||||
/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M)
|
||||
if(M && M.canbearoused && prob(33))
|
||||
if(M.min_arousal > 0)
|
||||
M.min_arousal -= 1
|
||||
if(M.min_arousal > 50)
|
||||
M.min_arousal -= 1
|
||||
M.adjustArousalLoss(-2)
|
||||
if(M && M.client?.prefs.arousable && prob(5))
|
||||
to_chat(M, "<span class='userlove'>You feel like you'll never feel aroused again...</span>")
|
||||
ADD_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
|
||||
..()
|
||||
|
||||
//recipes
|
||||
|
||||
Reference in New Issue
Block a user