Merge remote-tracking branch 'citadel/master' into mobility_flags

This commit is contained in:
kevinz000
2020-02-13 00:39:20 -07:00
481 changed files with 10666 additions and 9059 deletions
+10 -20
View File
@@ -10,12 +10,6 @@
var/hidden_undershirt = FALSE
var/hidden_socks = FALSE
//Species vars
/datum/species
var/list/cum_fluids = list("semen")
var/list/milk_fluids = list("milk")
var/list/femcum_fluids = list("femcum")
//Mob procs
/mob/living/carbon/human/proc/underwear_toggle()
set name = "Toggle undergarments"
@@ -46,20 +40,12 @@
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.aroused_state && prob(strength*G.sensitivity))
G.set_aroused_state(TRUE)
G.update_appearance()
if(G.aroused_state)
genit_list += G
else
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
for(var/obj/item/organ/genital/G in internal_organs)
if(G.genital_flags & GENITAL_CAN_AROUSE && !G.aroused_state && prob(strength*G.sensitivity))
G.set_aroused_state(strength > 0)
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.
@@ -158,9 +144,13 @@
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))
to_chat(src,"<span class='notice'>Waiting for consent...</span>")
var/consenting = input(target, "Do you want [src] to climax with you?","Climax mechanics","No") in list("Yes","No")
if(consenting == "Yes")
return target
else
message_admins("[src] tried to climax with [target], but [target] did not consent.")
log_consent("[src] tried to climax with [target], but [target] did not consent.")
/mob/living/carbon/human/proc/pick_climax_container(silent = FALSE)
var/list/containers_list = list()
+102 -120
View File
@@ -32,23 +32,20 @@
else
update()
/obj/item/organ/genital/Destroy()
if(linked_organ)
update_link(TRUE)//this should remove any other links it has
return ..()
/obj/item/organ/genital/proc/set_aroused_state(new_state)
if(!(genital_flags & GENITAL_CAN_AROUSE))
return FALSE
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)
/obj/item/organ/genital/proc/update()
if(QDELETED(src))
return
update_size()
update_appearance()
if(linked_organ_slot || (linked_organ && removing))
update_link(removing)
if(linked_organ_slot || (linked_organ && !owner))
update_link()
//exposure and through-clothing code
/mob/living/carbon
@@ -113,17 +110,7 @@
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)
if(G.genital_flags & GENITAL_CAN_AROUSE)
genital_list += G
if(!genital_list.len) //There's nothing that can show arousal
return
@@ -174,19 +161,18 @@
return TRUE
return FALSE
/obj/item/organ/genital/proc/update_link(removing = FALSE)
if(!removing && owner)
/obj/item/organ/genital/proc/update_link()
if(owner)
if(linked_organ)
return
return FALSE
linked_organ = owner.getorganslot(linked_organ_slot)
if(linked_organ)
linked_organ.linked_organ = src
linked_organ.upon_link()
upon_link()
return TRUE
else
if(linked_organ)
linked_organ.linked_organ = null
if(linked_organ)
linked_organ.linked_organ = null
linked_organ = null
return FALSE
@@ -200,10 +186,13 @@
update()
RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/update_appearance)
/obj/item/organ/genital/Remove(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
update(TRUE)
if(!QDELETED(owner))
UnregisterSignal(owner, COMSIG_MOB_DEATH)
/obj/item/organ/genital/Remove(special = FALSE)
. = ..()
var/mob/living/carbon/human/H = .
update()
if(!QDELETED(H))
UnregisterSignal(H, COMSIG_MOB_DEATH)
H.update_genitals()
//proc to give a player their genitals and stuff when they log in
/mob/living/carbon/human/proc/give_genitals(clean = FALSE)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
@@ -238,12 +227,6 @@
/obj/item/organ/genital/proc/get_features(mob/living/carbon/human/H)
return
/datum/species/proc/genitals_layertext(layer)
switch(layer)
if(GENITALS_BEHIND_LAYER)
return "BEHIND"
if(GENITALS_FRONT_LAYER)
return "FRONT"
//procs to handle sprite overlays being applied to humans
@@ -262,8 +245,90 @@
update_genitals()
/mob/living/carbon/human/proc/update_genitals()
if(!QDELETED(src))
dna.species.handle_genitals(src)
if(QDELETED(src))
return
var/static/list/relevant_layers
if(!relevant_layers)
relevant_layers = list()
relevant_layers[GENITALS_BEHIND_LAYER] = "BEHIND"
relevant_layers[GENITALS_FRONT_LAYER] = "FRONT"
for(var/L in relevant_layers) //Less hardcode
remove_overlay(L)
remove_overlay(GENITALS_EXPOSED_LAYER)
if(!LAZYLEN(internal_organs) || ((NOGENITALS in dna.species.species_traits) && !genital_override) || HAS_TRAIT(src, TRAIT_HUSK))
return
//start scanning for genitals
var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
var/list/genitals_to_add
var/list/fully_exposed
for(var/obj/item/organ/genital/G in internal_organs)
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
LAZYADD(gen_index[G.layer_index], G)
for(var/L in gen_index)
if(L) //skip nulls
LAZYADD(genitals_to_add, L)
if(!genitals_to_add)
return
//Now we added all genitals that aren't internal and should be rendered
//start applying overlays
for(var/layer in relevant_layers)
var/list/standing = list()
var/layertext = relevant_layers[layer]
for(var/A in genitals_to_add)
var/obj/item/organ/genital/G = A
var/datum/sprite_accessory/S
var/size = G.size
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 || S.icon_state == "none")
continue
var/aroused_state = G.aroused_state && S.alt_aroused
var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(skin_tone)]"
else
switch(S.color_src)
if("cock_color")
genital_overlay.color = "#[dna.features["cock_color"]]"
if("balls_color")
genital_overlay.color = "#[dna.features["balls_color"]]"
if("breasts_color")
genital_overlay.color = "#[dna.features["breasts_color"]]"
if("vag_color")
genital_overlay.color = "#[dna.features["vag_color"]]"
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size][dna.species.use_skintones ? "_s" : ""]_[aroused_state]_[layertext]"
if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
genital_overlay.layer = -GENITALS_EXPOSED_LAYER
LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
else
standing += genital_overlay
if(LAZYLEN(standing))
overlays_standing[layer] = standing
if(LAZYLEN(fully_exposed))
overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
apply_overlay(GENITALS_EXPOSED_LAYER)
for(var/L in relevant_layers)
apply_overlay(L)
//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()
@@ -292,86 +357,3 @@
else if (willyCheck == FALSE)
dna.features["cock_color"] = dna.features["breasts_color"]
return TRUE
/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
if(!H)//no args
CRASH("H = null")
if(!LAZYLEN(H.internal_organs) || ((NOGENITALS in species_traits) && !H.genital_override) || HAS_TRAIT(H, TRAIT_HUSK))
return
var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER)
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
H.remove_overlay(GENITALS_EXPOSED_LAYER)
//start scanning for genitals
var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
var/list/genitals_to_add
var/list/fully_exposed
for(var/obj/item/organ/genital/G in H.internal_organs)
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
LAZYADD(gen_index[G.layer_index], G)
for(var/L in gen_index)
if(L) //skip nulls
LAZYADD(genitals_to_add, L)
if(!genitals_to_add)
return
//Now we added all genitals that aren't internal and should be rendered
//start applying overlays
for(var/layer in relevant_layers)
var/list/standing = list()
var/layertext = genitals_layertext(layer)
for(var/A in genitals_to_add)
var/obj/item/organ/genital/G = A
var/datum/sprite_accessory/S
var/size = G.size
var/aroused_state = G.aroused_state
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 || S.icon_state == "none")
continue
var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
if(S.center)
genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
if(use_skintones && H.dna.features["genitals_use_skintone"])
genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
else
switch(S.color_src)
if("cock_color")
genital_overlay.color = "#[H.dna.features["cock_color"]]"
if("balls_color")
genital_overlay.color = "#[H.dna.features["balls_color"]]"
if("breasts_color")
genital_overlay.color = "#[H.dna.features["breasts_color"]]"
if("vag_color")
genital_overlay.color = "#[H.dna.features["vag_color"]]"
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
genital_overlay.layer = -GENITALS_EXPOSED_LAYER
LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
else
standing += genital_overlay
if(LAZYLEN(standing))
H.overlays_standing[layer] = standing
if(LAZYLEN(fully_exposed))
H.overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
H.apply_overlay(GENITALS_EXPOSED_LAYER)
for(var/L in relevant_layers)
H.apply_overlay(L)
@@ -85,36 +85,36 @@
//Vaginas
/datum/sprite_accessory/vagina
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
icon_state = null
name = "vagina"
color_src = "vag_color"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/human
icon_state = "human"
name = "Human"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/tentacles
icon_state = "tentacle"
name = "Tentacle"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/dentata
icon_state = "dentata"
name = "Dentata"
alt_aroused = TRUE
/datum/sprite_accessory/vagina/hairy
icon_state = "hairy"
name = "Hairy"
alt_aroused = FALSE
/datum/sprite_accessory/vagina/spade
icon_state = "spade"
name = "Spade"
alt_aroused = FALSE
/datum/sprite_accessory/vagina/furred
icon_state = "furred"
name = "Furred"
alt_aroused = FALSE
/datum/sprite_accessory/vagina/gaping
icon_state = "gaping"
@@ -125,7 +125,6 @@
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
name = "breasts"
color_src = "breasts_color"
alt_aroused = TRUE
/datum/sprite_accessory/breasts/pair
icon_state = "pair"
@@ -1,3 +1,6 @@
#define BREASTS_ICON_MIN_SIZE 1
#define BREASTS_ICON_MAX_SIZE 6
/obj/item/organ/genital/breasts
name = "breasts"
desc = "Female milk producing organs."
@@ -9,7 +12,7 @@
fluid_id = /datum/reagent/consumable/milk
fluid_rate = MILK_RATE
shape = "pair"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION|GENITAL_CAN_AROUSE
masturbation_verb = "massage"
arousal_verb = "Your breasts start feeling sensitive"
unarousal_verb = "Your breasts no longer feel sensitive"
@@ -46,22 +49,24 @@
desc += " You estimate that they're [uppertext(size)]-cups."
if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION) && aroused_state)
desc += " They're leaking [initial(fluid_id.name)]."
var/string
var/datum/reagent/R = GLOB.chemical_reagents_list[fluid_id]
if(R)
desc += " They're leaking [lowertext(R.name)]."
var/datum/sprite_accessory/S = GLOB.breasts_shapes_list[shape]
var/icon_shape = S ? S.icon_state : "pair"
var/icon_size = CLAMP(breast_values[size], BREASTS_ICON_MIN_SIZE, BREASTS_ICON_MAX_SIZE)
icon_state = "breasts_[icon_shape]_[breast_values[icon_size]]"
if(owner)
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]-s"
icon_state += "_s"
else
color = "#[owner.dna.features["breasts_color"]]"
string = "breasts_[GLOB.breasts_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
icon_state = sanitize_text(string)
//Allows breasts to grow and change size, with sprite changes too.
//maximum wah
@@ -120,7 +125,6 @@
color = "#[D.features["breasts_color"]]"
size = D.features["breasts_size"]
shape = D.features["breasts_shape"]
fluid_id = D.features["breasts_fluid"]
if(!D.features["breasts_producing"])
DISABLE_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH)
if(!isnum(size))
@@ -129,3 +133,6 @@
cached_size = size
size = breast_values[size]
prev_size = cached_size
#undef BREASTS_ICON_MIN_SIZE
#undef BREASTS_ICON_MAX_SIZE
@@ -8,13 +8,13 @@
masturbation_verb = "stroke"
arousal_verb = "You pop a boner"
unarousal_verb = "Your boner goes down"
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE
linked_organ_slot = ORGAN_SLOT_TESTICLES
fluid_transfer_factor = 0.5
size = 2 //arbitrary value derived from length and girth for sprites.
layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/prev_length = 6 //really should be renamed to prev_length
var/prev_length = 6
var/girth = 4.38
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
@@ -73,22 +73,21 @@
/obj/item/organ/genital/penis/update_appearance()
. = ..()
var/string
var/datum/sprite_accessory/S = GLOB.cock_shapes_list[shape]
var/icon_shape = S ? S.icon_state : "human"
icon_state = "penis_[icon_shape]_[size]"
var/lowershape = lowertext(shape)
desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] [name]. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
if(owner)
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]-s"
icon_state += "_s"
else
color = "#[owner.dna.features["cock_color"]]"
string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
@@ -43,19 +43,19 @@
/obj/item/organ/genital/testicles/update_appearance()
. = ..()
desc = "You see an [size_name] pair of testicles."
var/datum/sprite_accessory/S = GLOB.balls_shapes_list[shape]
var/icon_shape = S ? S.icon_state : "single"
icon_state = "testicles_[icon_shape]_[size]"
if(owner)
var/string
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]-s"
icon_state += "_s"
else
color = "#[owner.dna.features["balls_color"]]"
string = "testicles_[GLOB.balls_shapes_icons[shape]]_[size]"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
@@ -68,7 +68,6 @@
shape = D.features["balls_shape"]
if(D.features["balls_shape"] == "Hidden")
ENABLE_BITFIELD(genital_flags, GENITAL_INTERNAL)
fluid_id = D.features["balls_fluid"]
fluid_rate = D.features["balls_cum_rate"]
fluid_mult = D.features["balls_cum_mult"]
fluid_efficiency = D.features["balls_efficiency"]
@@ -6,7 +6,7 @@
zone = BODY_ZONE_PRECISE_GROIN
slot = "vagina"
size = 1 //There is only 1 size right now
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE
masturbation_verb = "finger"
arousal_verb = "You feel wetness on your crotch"
unarousal_verb = "You no longer feel wet"
@@ -22,7 +22,7 @@
/obj/item/organ/genital/vagina/update_appearance()
. = ..()
var/string //Keeping this code here, so making multiple sprites for the different kinds is easier.
icon_state = "vagina"
var/lowershape = lowertext(shape)
var/details
@@ -55,13 +55,11 @@
if(ishuman(owner)) // Check before recasting type, although someone fucked up if you're not human AND have use_skintones somehow...
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
color = "#[skintone2hex(H.skin_tone)]"
string = "vagina-s"
icon_state += "_s"
else
color = "#[owner.dna.features["vag_color"]]"
string = "vagina"
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
/obj/item/organ/genital/vagina/get_features(mob/living/carbon/human/H)
@@ -5,7 +5,7 @@
restricted_roles = list("Head of Security")
/datum/gear/navybluehosberet
name = "Head of security's Naviblue beret"
name = "Head of security's navyblue beret"
category = SLOT_HEAD
path = /obj/item/clothing/head/beret/sec/navyhos
restricted_roles = list("Head of Security")
@@ -13,13 +13,13 @@
/datum/gear/navybluejackethos
name = "head of security's navyblue jacket"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/security/hos
path = /obj/item/clothing/suit/armor/hos/navyblue
restricted_roles = list("Head of Security")
/datum/gear/navybluejacketofficer
name = "security officer's navyblue jacket"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/security/officer
path = /obj/item/clothing/suit/armor/navyblue
restricted_roles = list("Security Officer")
/datum/gear/navyblueofficerberet
@@ -37,7 +37,7 @@
/datum/gear/navybluejacketwarden
name = "warden navyblue jacket"
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/security/warden
path = /obj/item/clothing/suit/armor/vest/warden/navyblue
restricted_roles = list("Warden")
/datum/gear/navybluewardenberet
@@ -57,13 +57,11 @@
WRITE_FILE(S["feature_balls_size"], features["balls_size"])
WRITE_FILE(S["feature_balls_shape"], features["balls_shape"])
WRITE_FILE(S["feature_balls_sack_size"], features["balls_sack_size"])
WRITE_FILE(S["feature_balls_fluid"], features["balls_fluid"])
//breasts features
WRITE_FILE(S["feature_has_breasts"], features["has_breasts"])
WRITE_FILE(S["feature_breasts_size"], features["breasts_size"])
WRITE_FILE(S["feature_breasts_shape"], features["breasts_shape"])
WRITE_FILE(S["feature_breasts_color"], features["breasts_color"])
WRITE_FILE(S["feature_breasts_fluid"], features["breasts_fluid"])
WRITE_FILE(S["feature_breasts_producing"], features["breasts_producing"])
//vagina features
WRITE_FILE(S["feature_has_vag"], features["has_vag"])
@@ -557,3 +557,13 @@
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
mutantrace_variation = NONE
/obj/item/toy/plush/mammal/dog/fritz
icon = 'icons/obj/custom.dmi'
icon_state = "fritz"
item_state = "fritz"
attack_verb = list("barked", "boofed", "shotgun'd")
obj_flags = UNIQUE_RENAME
unique_reskin = list("Goodboye" = "fritz", "Badboye" = "fritz_bad")
mutantrace_variation = NONE
@@ -18,13 +18,13 @@ GLOBAL_LIST(custom_item_list)
if(copytext(line,1,3) == "//") //Commented line, ignore. 3 == length("//") + 1
continue
var/ckey_str_sep = findtext(line, "|") //Process our stuff..
var/char_str_sep = findtext(line, "|", ckey_str_sep + length(ckey_str_sep))
var/job_str_sep = findtext(line, "|", char_str_sep + length(char_str_sep))
var/item_str_sep = findtext(line, "|", job_str_sep + length(job_str_sep))
var/char_str_sep = findtext(line, "|", ckey_str_sep + length(line[ckey_str_sep]))
var/job_str_sep = findtext(line, "|", char_str_sep + length(line[char_str_sep]))
var/item_str_sep = findtext(line, "|", job_str_sep + length(line[job_str_sep]))
var/ckey_str = ckey(copytext(line, 1, ckey_str_sep))
var/char_str = copytext(line, ckey_str_sep + length(ckey_str_sep), char_str_sep)
var/job_str = copytext(line, char_str_sep + length(char_str_sep), job_str_sep)
var/item_str = copytext(line, job_str_sep + length(job_str_sep), item_str_sep)
var/char_str = copytext(line, ckey_str_sep + length(line[ckey_str_sep]), char_str_sep)
var/job_str = copytext(line, char_str_sep + length(line[char_str_sep]), job_str_sep)
var/item_str = copytext(line, job_str_sep + length(line[job_str_sep]), item_str_sep)
if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str))
log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!")
if(!islist(GLOB.custom_item_list[ckey_str]))
@@ -42,7 +42,7 @@ GLOBAL_LIST(custom_item_list)
for(var/item_string in item_strings)
var/path_str_sep = findtext(item_string, "=")
var/path = copytext(item_string, 1, path_str_sep) //Path to spawn
var/amount = copytext(item_string, path_str_sep + length(path_str_sep)) //Amount to spawn
var/amount = copytext(item_string, path_str_sep + length(item_string[path_str_sep])) //Amount to spawn
//world << "DEBUG: Item string [item_string] processed"
amount = text2num(amount)
path = text2path(path)
@@ -46,34 +46,22 @@
cell.use(shot.e_cost)//... drain the cell cell
chambered = 0 //either way, released the prepared shot
/obj/item/gun/energy/pumpaction/select_fire(mob/living/user) //makes it so that it doesn't rack itself when changing firing modes unless already racked
select++
if (select > ammo_type.len)
select = 1
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
fire_sound = shot.fire_sound
fire_delay = shot.delay
if (shot.select_name)
to_chat(user, "<span class='notice'>[src] is now set to [shot.select_name].</span>")
if(chambered)
chambered = 0
recharge_newshot(1)
update_icon()
if(ismob(loc)) //forces inhands to update
var/mob/M = loc
M.update_inv_hands()
return
/obj/item/gun/energy/pumpaction/post_set_firemode()
var/has_shot = chambered
. = ..(recharge_newshot = FALSE)
if(has_shot)
recharge_newshot(TRUE)
/obj/item/gun/energy/pumpaction/update_icon() //adds racked indicators
..()
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(chambered)
add_overlay("[icon_state]_rack_[shot.select_name]")
else
add_overlay("[icon_state]_rack_empty")
/obj/item/gun/energy/pumpaction/proc/pump(mob/M) //pumping proc. Checks if the gun is empty and plays a different sound if it is.
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(cell.charge < shot.e_cost)
playsound(M, 'sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
else
@@ -102,7 +90,7 @@
/obj/item/gun/energy/pumpaction/worn_overlays(isinhands, icon_file, style_flags = NONE) //ammo counter for inhands
. = ..()
var/ratio = CEILING((cell.charge / cell.maxcharge) * charge_sections, 1)
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
if(isinhands)
if(cell.charge < shot.e_cost)
var/mutable_appearance/ammo_inhand = mutable_appearance(icon_file, "[item_state]_empty")