Merge branch 'master' into Ghommie-cit629

This commit is contained in:
Ghom
2020-03-19 17:15:26 +01:00
committed by GitHub
118 changed files with 9283 additions and 5906 deletions
+1 -3
View File
@@ -639,15 +639,13 @@
var/almcam = CONFIG_GET(flag/allow_ai_multicam)
CONFIG_SET(flag/allow_ai_multicam, !almcam)
if (almcam)
to_chat(world, "<B>The AI no longer has multicam.</B>")
for(var/i in GLOB.ai_list)
var/mob/living/silicon/ai/aiPlayer = i
if(aiPlayer.multicam_on)
aiPlayer.end_multicam()
else
to_chat(world, "<B>The AI now has multicam.</B>")
log_admin("[key_name(usr)] toggled AI multicam.")
world.update_status()
to_chat(GLOB.ai_list | GLOB.admins, "<B>The AI [almcam ? "no longer" : "now"] has multicam.</B>")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Multicam", "[!almcam ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleaban()
+1 -1
View File
@@ -1732,7 +1732,7 @@
var/mob/M = locate(href_list["makeeligible"])
if(!ismob(M))
to_chat(usr, "this can only be used on instances of type /mob.")
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
if(M.ckey in eli.timeouts)
eli.timeouts -= M.ckey
+3 -3
View File
@@ -1315,15 +1315,15 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target))
creamy.splat(target)
if (ADMIN_PUNISHMENT_CUSTOM_PIE)
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new(get_turf(target))
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new()
if(!A.reagents)
var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num
var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num|null
if(amount)
A.create_reagents(amount)
if(A.reagents)
var/chosen_id = choose_reagent_id(usr)
if(chosen_id)
var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num
var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num|null
if(amount)
A.reagents.add_reagent(chosen_id, amount)
A.splat(target)
@@ -185,10 +185,10 @@
BuyPower(new /datum/action/bloodsucker/veil)
// Traits
for(var/T in defaultTraits)
ADD_TRAIT(owner.current, T, "bloodsucker")
ADD_TRAIT(owner.current, T, BLOODSUCKER_TRAIT)
if(HAS_TRAIT(owner.current, TRAIT_TOXINLOVER)) //No slime bonuses here, no thank you
had_toxlover = TRUE
REMOVE_TRAIT(owner.current, TRAIT_TOXINLOVER, "species")
REMOVE_TRAIT(owner.current, TRAIT_TOXINLOVER, SPECIES_TRAIT)
// Traits: Species
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
@@ -235,9 +235,9 @@
// owner.RemoveSpell(power)
// Traits
for(var/T in defaultTraits)
REMOVE_TRAIT(owner.current, T, "bloodsucker")
REMOVE_TRAIT(owner.current, T, BLOODSUCKER_TRAIT)
if(had_toxlover == TRUE)
ADD_TRAIT(owner.current, TRAIT_TOXINLOVER, "species")
ADD_TRAIT(owner.current, TRAIT_TOXINLOVER, SPECIES_TRAIT)
// Traits: Species
if(ishuman(owner.current))
@@ -387,7 +387,7 @@
add_objective(heartthief_objective)
/*
else
// Solars Objective, doesnt work due to TG updates.
var/datum/objective/bloodsucker/solars/solars_objective = new
solars_objective.owner = owner
+1 -1
View File
@@ -211,7 +211,7 @@
/datum/export/weapon/arrows
cost = 150
unit_name = "arrow"
export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ashen)
export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ash)
/datum/export/weapon/bow_teaching
cost = 500
-8
View File
@@ -223,7 +223,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
new /datum/admins(localhost_rank, ckey, 1, 1)
//preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum)
prefs = GLOB.preferences_datums[ckey]
prefs_vr = GLOB.vore_preferences_datums[ckey] //CITADEL EDIT bypassing a failing hook
if(prefs)
prefs.parent = src
@@ -231,13 +230,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
prefs = new /datum/preferences(src)
GLOB.preferences_datums[ckey] = prefs
if(prefs_vr) //CITADEL EDIT bypassing a failing hook START
prefs_vr.client = src
else
prefs_vr = new/datum/vore_preferences(src)
GLOB.vore_preferences_datums[ckey] = prefs_vr
//CITADEL EDIT bypassing a failing hook END
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
fps = prefs.clientfps
+9 -5
View File
@@ -205,6 +205,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/action_buttons_screen_locs = list()
//bad stuff
var/digestable = FALSE
var/devourable = FALSE
var/feeding = FALSE
var/lickable = FALSE
var/list/belly_prefs = list()
var/vore_taste = "nothing in particular"
//backgrounds
var/mutable_appearance/character_background
var/icon/bgstate = "steel"
@@ -1483,7 +1491,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
if("flavor_text")
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], MAX_FAVOR_LEN, TRUE)
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], MAX_FLAVOR_LEN, TRUE)
if(!isnull(msg))
features["flavor_text"] = html_decode(msg)
@@ -2301,16 +2309,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("load")
load_preferences()
load_character()
if(parent && parent.prefs_vr)
attempt_vr(parent.prefs_vr,"load_vore","")
if("changeslot")
if(!load_character(text2num(href_list["num"])))
random_character()
real_name = random_unique_name(gender)
save_character()
if(parent && parent.prefs_vr)
attempt_vr(parent.prefs_vr,"load_vore","")
if("tab")
if (href_list["tab"])
+51 -17
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 25
#define SAVEFILE_VERSION_MAX 26
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -115,6 +115,36 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(digi == "Digitigrade Legs")
WRITE_FILE(S["feature_lizard_legs"], "Digitigrade")
if(current_version < 26)
var/vr_path = "data/player_saves/[parent.ckey[1]]/[parent.ckey]/vore/character[default_slot].json"
if(fexists(vr_path))
var/list/json_from_file = json_decode(file2text(vr_path))
if(json_from_file)
digestable = json_from_file["digestable"]
devourable = json_from_file["devourable"]
feeding = json_from_file["feeding"]
lickable = json_from_file["lickable"]
belly_prefs = json_from_file["belly_prefs"]
vore_taste = json_from_file["vore_taste"]
for(var/V in all_quirks) // quirk migration
switch(V)
if("Acute hepatic pharmacokinesis")
DISABLE_BITFIELD(cit_toggles, PENIS_ENLARGEMENT)
DISABLE_BITFIELD(cit_toggles, BREAST_ENLARGEMENT)
ENABLE_BITFIELD(cit_toggles,FORCED_FEM)
ENABLE_BITFIELD(cit_toggles,FORCED_MASC)
all_quirks -= V
if("Crocin Immunity")
ENABLE_BITFIELD(cit_toggles,NO_APHRO)
all_quirks -= V
if("Buns of Steel")
ENABLE_BITFIELD(cit_toggles,NO_ASS_SLAP)
all_quirks -= V
if(features["meat_type"] == "Inesct")
features["meat_type"] = "Insect"
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -446,6 +476,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
else //We have no old flavortext, default to new
S["feature_flavor_text"] >> features["flavor_text"]
S["digestable"] >> digestable
S["devourable"] >> devourable
S["feeding"] >> feeding
S["vore_taste"] >> vore_taste
S["lickable"] >> lickable
S["belly_prefs"] >> belly_prefs
//try to fix any outdated data if necessary
if(needs_update >= 0)
@@ -515,6 +551,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["cock_length"] = sanitize_integer(features["cock_length"], COCK_SIZE_MIN, COCK_SIZE_MAX, COCK_SIZE_DEF)
features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE)
features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE)
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
//Validate job prefs
@@ -524,23 +561,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
all_quirks = SANITIZE_LIST(all_quirks)
for(var/V in all_quirks) // quirk migration
switch(V)
if("Acute hepatic pharmacokinesis")
DISABLE_BITFIELD(cit_toggles, PENIS_ENLARGEMENT)
DISABLE_BITFIELD(cit_toggles, BREAST_ENLARGEMENT)
ENABLE_BITFIELD(cit_toggles,FORCED_FEM)
ENABLE_BITFIELD(cit_toggles,FORCED_MASC)
all_quirks -= V
if("Crocin Immunity")
ENABLE_BITFIELD(cit_toggles,NO_APHRO)
all_quirks -= V
if("Buns of Steel")
ENABLE_BITFIELD(cit_toggles,NO_ASS_SLAP)
all_quirks -= V
lickable = sanitize_integer(lickable, FALSE, TRUE, initial(lickable))
devourable = sanitize_integer(devourable, FALSE, TRUE, initial(devourable))
digestable = sanitize_integer(digestable, FALSE, TRUE, initial(digestable))
feeding = sanitize_integer(feeding, FALSE, TRUE, initial(feeding))
vore_taste = copytext(vore_taste, 1, MAX_TASTE_LEN)
belly_prefs = SANITIZE_LIST(belly_prefs)
if(features["meat_type"] == "Inesct")
features["meat_type"] = "Insect"
cit_character_pref_load(S)
return 1
@@ -619,6 +646,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Quirks
WRITE_FILE(S["all_quirks"] , all_quirks)
WRITE_FILE(S["digestable"] , digestable)
WRITE_FILE(S["devourable"] , devourable)
WRITE_FILE(S["feeding"] , feeding)
WRITE_FILE(S["vore_taste"] , vore_taste)
WRITE_FILE(S["lickable"] , lickable)
WRITE_FILE(S["belly_prefs"] , belly_prefs)
cit_character_pref_save(S)
return 1
@@ -97,6 +97,11 @@
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP
/obj/item/clothing/glasses/meson/eyepatch
name = "eyepatch mesons"
desc = "A meson system that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "mesonpatch"
/obj/item/clothing/glasses/science
name = "science goggles"
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
+17 -6
View File
@@ -83,6 +83,11 @@
name = "prescription medical HUDSunglasses"
vision_correction = 1
/obj/item/clothing/glasses/hud/health/eyepatch
name = "eyepatch medHUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "medpatch"
///////////////////
//Diagnostic Huds//
///////////////////
@@ -97,7 +102,8 @@
/obj/item/clothing/glasses/hud/diagnostic/sunglasses
name = "diagnostic HUDSunglasses"
desc = "Sunglasses with a diagnostic HUD."
icon_state = "sunhuddiagnostic"
icon_state = "sunhuddiag"
item_state = "glasses"
darkness_view = 1
flash_protect = 1
tint = 1
@@ -123,6 +129,11 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/hud/diagnostic/eyepatch
name = "eyepatch diagnostic HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "diagpatch"
////////////
//Sec Huds//
////////////
@@ -165,11 +176,6 @@
return
chameleon_action.emp_randomise()
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
name = "eyepatch HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "hudpatch"
/obj/item/clothing/glasses/hud/security/sunglasses
name = "security HUDSunglasses"
desc = "Sunglasses with a security HUD."
@@ -179,6 +185,11 @@
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/darkred
/obj/item/clothing/glasses/hud/security/sunglasses/eyepatch // why was this defined *before* the sunglasses it is a subtype of.
name = "eyepatch HUD"
desc = "A heads-up display that connects directly to the optical nerve of the user, replacing the need for that useless eyeball."
icon_state = "hudpatch"
/obj/item/clothing/glasses/hud/security/sunglasses/prescription
name = "prescription security HUDSunglasses"
vision_correction = 1
@@ -44,8 +44,8 @@
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
var/mutable_appearance/creamoverlay = mutable_appearance('icons/effects/creampie.dmi')
if(H.dna.species.limbs_id == "lizard")
creamoverlay.icon_state = "creampie_lizard"
if((("mam_snouts" in H.dna.species.default_features) && H.dna.features["mam_snouts"] != "None") || (("snout" in H.dna.species.default_features) && H.dna.features["snout"] != "None"))
creamoverlay.icon_state = "creampie_snout"
else
creamoverlay.icon_state = "creampie_human"
if(stunning)
@@ -53,7 +53,7 @@
H.adjust_blurriness(1)
H.visible_message("<span class='warning'>[H] is creamed by [src]!</span>", "<span class='userdanger'>You've been creamed by [src]!</span>")
playsound(H, "desceration", 50, TRUE)
if(!H.is_mouth_covered())
if(!H.is_mouth_covered())
reagents.trans_to(H,15) //Cream pie combat
if(!H.creamed) // one layer at a time
H.add_overlay(creamoverlay)
@@ -139,6 +139,9 @@
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper"
/obj/machinery/sleeper/survival_pod/update_icon_state()
return
/obj/machinery/sleeper/survival_pod/update_overlays()
. = ..()
if(!state_open)
@@ -189,7 +192,7 @@
flags_1 = NODECONSTRUCT_1
var/empty = FALSE
/obj/machinery/stasis/survival_pod/ComponentInitialize()
/obj/machinery/smartfridge/survival_pod/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
+3
View File
@@ -24,6 +24,9 @@
/obj/item/mmi/update_overlays()
. = ..()
. += add_mmi_overlay()
/obj/item/mmi/proc/add_mmi_overlay()
if(brainmob && brainmob.stat != DEAD)
. += "mmi_alive"
else
@@ -193,3 +193,6 @@ GLOBAL_VAR(posibrain_notify_cooldown)
icon_state = "[initial(icon_state)]-occupied"
else
icon_state = initial(icon_state)
/obj/item/mmi/posibrain/add_mmi_overlay()
return
@@ -242,6 +242,12 @@
return
if(href_list["pockets"])
var/strip_mod = 1
var/strip_silence = FALSE
var/obj/item/clothing/gloves/g = gloves
if (istype(g))
strip_mod = g.strip_mod
strip_silence = g.strip_silence
var/pocket_side = href_list["pockets"]
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
@@ -258,7 +264,7 @@
else
return
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator, ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster
if(do_mob(usr, src, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too)
if(pocket_item)
if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search
dropItemToGround(pocket_item)
@@ -276,7 +282,8 @@
show_inv(usr)
else
// Display a warning if the user mocks up
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
if (!strip_silence)
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined
@@ -397,7 +397,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(I.flags_inv & HIDEFACIALHAIR)
facialhair_hidden = TRUE
if(H.wear_mask)
if(H.wear_mask && istype(H.wear_mask))
var/obj/item/clothing/mask/M = H.wear_mask
dynamic_fhair_suffix = M.dynamic_fhair_suffix //mask > head in terms of facial hair
if(M.flags_inv & HIDEFACIALHAIR)
@@ -451,7 +451,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(I.flags_inv & HIDEHAIR)
hair_hidden = TRUE
if(H.wear_mask)
if(H.wear_mask && istype(H.wear_mask))
var/obj/item/clothing/mask/M = H.wear_mask
if(!dynamic_hair_suffix) //head > mask in terms of head hair
dynamic_hair_suffix = M.dynamic_hair_suffix
+1 -1
View File
@@ -24,4 +24,4 @@
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
if(vore_init && !vorepref_init) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing.
apply_vore_prefs()
copy_from_prefs_vr()
@@ -1116,6 +1116,7 @@
desc = "Stop controlling your shell and resume normal core operations."
icon_icon = 'icons/mob/actions/actions_AI.dmi'
button_icon_state = "ai_core"
required_mobility_flags = NONE
/datum/action/innate/undeployment/Trigger()
if(!..())
@@ -821,7 +821,6 @@
/obj/item/gps/cyborg,
/obj/item/weapon/gripper/mining,
/obj/item/cyborg_clamp,
/obj/item/card/id/miningborg,
/obj/item/stack/marker_beacon,
/obj/item/destTagger,
/obj/item/stack/packageWrap)
@@ -1023,4 +1022,4 @@
/datum/robot_energy_storage/wrapping_paper
max_energy = 30
recharge_rate = 1
name = "Wrapping Paper Storage"
name = "Wrapping Paper Storage"
@@ -363,10 +363,8 @@
icon_dead = "old_corgi_dead"
desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
turns_per_move = 20
var/datum/element/mob_holder/ele = SSdcs.GetElement(/datum/element/mob_holder, held_icon)
if(ele)
ele.Detach(src)
AddElement(/datum/element/mob_holder, "old_corgi")
RemoveElement(/datum/element/mob_holder, held_icon)
AddElement(/datum/element/mob_holder, "old_corgi")
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
@@ -447,7 +445,7 @@
sleep(3)
step_to(src,movement_target,1)
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if(movement_target?.loc) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if (movement_target.loc.x < src.x)
setDir(WEST)
else if (movement_target.loc.x > src.x)
@@ -204,7 +204,7 @@
rapid = 2
icon_state = "syndicate_smg"
icon_living = "syndicate_smg"
casingtype = /obj/item/ammo_casing/c45/nostamina
casingtype = /obj/item/ammo_casing/c45
projectilesound = 'sound/weapons/gunshot_smg.ogg'
/mob/living/simple_animal/hostile/syndicate/ranged/smg/pilot //caravan ambush ruin
@@ -12,6 +12,10 @@
battery = new battery_type(src)
..()
/obj/item/computer_hardware/battery/Destroy()
. = ..()
QDEL_NULL(battery)
/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null)
if(!holder)
return FALSE
+3
View File
@@ -70,6 +70,9 @@
else
. = FALSE //as to not cancel attack_hand()
/obj/item/clothing/gloves/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
/obj/item/clothing/gloves/space_ninja/proc/toggledrain()
var/mob/living/carbon/human/U = loc
+5 -1
View File
@@ -9,4 +9,8 @@
strip_delay = 12
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
blockTracking = 1//Roughly the only unique thing about this helmet.
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
/obj/item/clothing/head/helmet/space/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
+4
View File
@@ -19,6 +19,10 @@ Contents:
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
modifies_speech = TRUE
/obj/item/clothing/mask/gas/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(message[1] != "*")
@@ -24,9 +24,6 @@
caliber = ".45"
projectile_type = /obj/item/projectile/bullet/c45
/obj/item/ammo_casing/c45/nostamina
projectile_type = /obj/item/projectile/bullet/c45_nostamina
/obj/item/ammo_casing/c45/kitchengun
desc = "A .45 bullet casing. It has a small sponge attached to it."
projectile_type = /obj/item/projectile/bullet/c45_cleaning
@@ -1,17 +1,21 @@
/obj/item/ammo_casing/caseless/arrow
name = "wooden arrow"
desc = "An arrow made of wood, typically fired from a bow."
name = "arrow of questionable material"
desc = "You shouldn't be seeing this arrow."
projectile_type = /obj/item/projectile/bullet/reusable/arrow
caliber = "arrow"
icon_state = "arrow"
throwforce = 3 //good luck hitting someone with the pointy end of the arrow
throw_speed = 3
/obj/item/ammo_casing/caseless/arrow/ashen
/obj/item/ammo_casing/caseless/arrow/wood
name = "wooden arrow"
desc = "An arrow made of wood, typically fired from a bow."
/obj/item/ammo_casing/caseless/arrow/ash
name = "ashen arrow"
desc = "An arrow made of wood, hardened by fire."
icon_state = "ashenarrow"
projectile_type = /obj/item/projectile/bullet/reusable/arrow/ashen
projectile_type = /obj/item/projectile/bullet/reusable/arrow/ash
/obj/item/ammo_casing/caseless/arrow/bone
name = "bone arrow"
+1 -1
View File
@@ -60,7 +60,7 @@
/obj/item/ammo_box/magazine/smgm45
name = "SMG magazine (.45)"
icon_state = "c20r45-24"
ammo_type = /obj/item/ammo_casing/c45/nostamina
ammo_type = /obj/item/ammo_casing/c45
caliber = ".45"
max_ammo = 24
@@ -47,7 +47,7 @@
var/mob/current_user = null
var/list/obj/effect/projectile/tracer/current_tracers
var/structure_piercing = 1
var/structure_piercing = 0
var/structure_bleed_coeff = 0.7
var/wall_pierce_amount = 0
var/wall_devastate = 0
@@ -60,7 +60,7 @@
var/impact_structure_damage = 75
var/projectile_damage = 40
var/projectile_stun = 0
var/projectile_setting_pierce = TRUE
var/projectile_setting_pierce = FALSE
var/delay = 30
var/lastfire = 0
@@ -160,6 +160,9 @@
add_overlay(drained_overlay)
/obj/item/gun/energy/beam_rifle/attack_self(mob/user)
if(!structure_piercing)
projectile_setting_pierce = FALSE
return
projectile_setting_pierce = !projectile_setting_pierce
to_chat(user, "<span class='boldnotice'>You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.</span>")
aiming_beam()
@@ -402,7 +405,7 @@
/obj/item/ammo_casing/energy/beam_rifle/hitscan
projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan
select_name = "beam"
e_cost = 5000
e_cost = 10000
fire_sound = 'sound/weapons/beam_sniper.ogg'
/obj/item/projectile/beam/beam_rifle
@@ -557,9 +560,4 @@
hitscan_light_color_override = "#99ff99"
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/prehit(atom/target)
qdel(src)
return FALSE
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
qdel(src)
return BULLET_ACT_HIT
@@ -1,18 +1,12 @@
// .45 (M1911 & C20r)
/obj/item/projectile/bullet/c45
name = ".45 bullet"
damage = 20
stamina = 65
/obj/item/projectile/bullet/c45_nostamina
name = ".45 bullet"
damage = 30
/obj/item/projectile/bullet/c45_cleaning
name = ".45 bullet"
damage = 24
stamina = 10
damage = 40 //BANG BANG BANG
/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -3,13 +3,13 @@
desc = "Woosh!"
damage = 15
icon_state = "arrow"
ammo_type = /obj/item/ammo_casing/caseless/arrow
ammo_type = /obj/item/ammo_casing/caseless/arrow/wood
/obj/item/projectile/bullet/reusable/arrow/ashen
/obj/item/projectile/bullet/reusable/arrow/ash
name = "ashen arrow"
desc = "Fire harderned arrow."
damage = 25
ammo_type = /obj/item/ammo_casing/caseless/arrow/ashen
ammo_type = /obj/item/ammo_casing/caseless/arrow/ash
/obj/item/projectile/bullet/reusable/arrow/bone //AP for ashwalkers
name = "bone arrow"
+3 -4
View File
@@ -43,14 +43,14 @@
set_APTFT()
return TRUE
/obj/item/reagent_containers/proc/set_APTFT(mob/user) //set amount_per_transfer_from_this
/obj/item/reagent_containers/proc/set_APTFT() //set amount_per_transfer_from_this
set name = "Set Transfer Amount"
set category = "Object"
set waitfor = FALSE
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
if(N)
amount_per_transfer_from_this = N
to_chat(user, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
to_chat(usr, "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>")
/obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents)
@@ -134,6 +134,7 @@
throwerstring = " THROWN BY [key_name(thrownby)] at [AT] (AREACOORD(AT)]"
log_reagent("SPLASH: [src] mob SplashReagents() onto [key_name(target)] at [TT] ([AREACOORD(TT)])[throwerstring] - [R]")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
else if(bartender_check(target) && thrown)
visible_message("<span class='notice'>[src] lands without spilling a single drop.</span>")
@@ -154,8 +155,6 @@
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
if(QDELETED(src))
return
//melts plastic beakers
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
@@ -35,6 +35,17 @@
dangerous_construction = TRUE
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
/datum/design/duffelbag_holding
name = "Duffel Bag of Holding"
desc = "A duffel bag that opens into a localized pocket of bluespace."
id = "duffelbag_holding"
build_type = PROTOLATHE
materials = list(/datum/material/gold = 3000, /datum/material/diamond = 1500, /datum/material/uranium = 250, /datum/material/bluespace = 2000)
build_path = /obj/item/storage/backpack/holding/duffel
category = list("Bluespace Designs")
dangerous_construction = TRUE
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
/datum/design/biobag_holding
name = "Bio Bag of Holding"
desc = "A chemical holding thingy. Mostly used for xenobiology."
@@ -633,15 +633,6 @@
construction_time = 120
category = list("Cyborg Upgrade Modules")
/datum/design/borg_upgrade_premiumka
name = "Cyborg Upgrade (Premium Kinetic Accelerator)"
id = "borg_upgrade_premiumka"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/premiumka
materials = list(/datum/material/iron=8000, /datum/material/glass=4000, /datum/material/titanium=2000)
construction_time = 120
category = list("Cyborg Upgrade Modules")
/datum/design/borg_upgrade_lavaproof
name = "Cyborg Upgrade (Lavaproof Tracks)"
id = "borg_upgrade_lavaproof"
+2 -2
View File
@@ -278,7 +278,7 @@
display_name = "Bluespace Pockets"
description = "Studies into the mysterious alternate dimension known as bluespace and how to place items in the threads of reality."
prereq_ids = list("adv_power", "adv_bluespace", "adv_biotech", "adv_plasma")
design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag")
design_ids = list( "bluespacebodybag","bag_holding", "bluespace_pod", "borg_upgrade_trashofholding", "blutrash", "satchel_holding", "bsblood_bag", "duffelbag_holding")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5500)
/datum/techweb_node/bluespace_portal
@@ -336,7 +336,7 @@
display_name = "Advanced Robotics Research"
description = "It can even do the dishes!"
prereq_ids = list("robotics")
design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter", "borg_upgrade_premiumka")
design_ids = list("borg_upgrade_diamonddrill", "borg_upgrade_advancedmop", "borg_upgrade_advcutter")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000)
/datum/techweb_node/neural_programming
+2
View File
@@ -319,6 +319,8 @@
on_mob.forceMove(scanning)
for(var/i in 1 to light_beam_distance)
scanning = get_step(scanning, scandir)
if(!scanning)
break
if(scanning.opacity || scanning.has_opaque_atom)
stop = TRUE
var/obj/effect/abstract/eye_lighting/L = LAZYACCESS(eye_lighting, i)
@@ -159,7 +159,7 @@
/datum/uplink_item/role_restricted/kitchen_gun
name = "Kitchen Gun (TM)"
desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \
Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!"
Just three shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!"
cost = 10
surplus = 40
restricted_roles = list("Cook", "Janitor")
+39 -49
View File
@@ -41,7 +41,7 @@
return TRUE
//We'll load our client's organs if we have one
if(client && client.prefs_vr)
if(client?.prefs)
if(!copy_from_prefs_vr())
to_chat(src,"<span class='warning'>ERROR: You seem to have saved vore prefs, but they couldn't be loaded.</span>")
return FALSE
@@ -262,47 +262,22 @@
else
to_chat(src,"<span class='alert'>You aren't inside anyone, though, is the thing.</span>")
//
// Verb for saving vore preferences to save file
//
/mob/living/proc/save_vore_prefs()
if(!client || !client.prefs_vr)
return FALSE
if(!copy_to_prefs_vr())
return FALSE
if(!client.prefs_vr.save_vore())
return FALSE
return TRUE
/mob/living/proc/apply_vore_prefs()
if(!client || !client.prefs_vr)
return FALSE
if(!client.prefs_vr.load_vore())
return FALSE
if(!copy_from_prefs_vr())
return FALSE
return TRUE
/mob/living/proc/copy_to_prefs_vr()
if(!client || !client.prefs_vr)
to_chat(src,"<span class='warning'>You attempted to save your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev.</span>")
if(!client || !client.prefs)
to_chat(src,"<span class='warning'>You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.</span>")
return FALSE
var/datum/vore_preferences/P = client.prefs_vr
P.digestable = src.digestable
P.devourable = src.devourable
P.feeding = src.feeding
P.vore_taste = src.vore_taste
client.prefs.digestable = digestable
client.prefs.devourable = devourable
client.prefs.feeding = feeding
client.prefs.vore_taste = vore_taste
var/list/serialized = list()
for(var/belly in src.vore_organs)
for(var/belly in vore_organs)
var/obj/belly/B = belly
serialized += list(B.serialize()) //Can't add a list as an object to another list in Byond. Thanks.
P.belly_prefs = serialized
client.prefs.belly_prefs = serialized
return TRUE
@@ -310,21 +285,20 @@
// Proc for applying vore preferences, given bellies
//
/mob/living/proc/copy_from_prefs_vr()
if(!client || !client.prefs_vr)
to_chat(src,"<span class='warning'>You attempted to apply your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev.</span>")
if(!client || !client.prefs)
to_chat(src,"<span class='warning'>You attempted to apply your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev.</span>")
return FALSE
vorepref_init = TRUE
var/datum/vore_preferences/P = client.prefs_vr
digestable = P.digestable
devourable = P.devourable
feeding = P.feeding
vore_taste = P.vore_taste
digestable = client.prefs.digestable
devourable = client.prefs.devourable
feeding = client.prefs.feeding
vore_taste = client.prefs.vore_taste
release_vore_contents(silent = TRUE)
vore_organs.Cut()
for(var/entry in P.belly_prefs)
QDEL_LIST(vore_organs)
for(var/entry in client.prefs.belly_prefs)
list_to_object(entry,src)
return TRUE
@@ -376,23 +350,31 @@
//
// Clearly super important. Obviously.
//
/mob/living/proc/lick(var/mob/living/tasted in oview(1))
/mob/living/proc/lick()
set name = "Lick Someone"
set category = "Vore"
set desc = "Lick someone nearby!"
if(!istype(tasted))
if(incapacitated(ignore_restraints = TRUE))
to_chat(src, "<span class='warning'>You can't do that while incapacitated.</span>")
return
if(!tasted.client?.prefs_vr.lickable)
var/list/choices
for(var/mob/living/L in view(1))
if(L != src && (!L.ckey || L.client?.prefs.lickable) && Adjacent(L))
LAZYADD(choices, L)
if(!choices)
return
if(src == stat)
var/mob/living/tasted = input(src, "Who would you like to lick? (Excluding yourself and those with the preference disabled)", "Licking") as null|anything in choices
if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.lickable)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE))
return
src.setClickCooldown(100)
setClickCooldown(100)
src.visible_message("<span class='warning'>[src] licks [tasted]!</span>","<span class='notice'>You lick [tasted]. They taste rather like [tasted.get_taste_message()].</span>","<b>Slurp!</b>")
visible_message("<span class='warning'>[src] licks [tasted]!</span>","<span class='notice'>You lick [tasted]. They taste rather like [tasted.get_taste_message()].</span>","<b>Slurp!</b>")
/mob/living/proc/get_taste_message(allow_generic = TRUE, datum/species/mrace)
@@ -408,3 +390,11 @@
else
taste_message += "a plain old normal [src]"
return taste_message
// Check if an object is capable of eating things, based on vore_organs
//
/proc/is_vore_predator(var/mob/living/O)
if(istype(O))
if(O.vore_organs.len > 0)
return TRUE
return FALSE
-174
View File
@@ -1,174 +0,0 @@
/*
VVVVVVVV VVVVVVVV OOOOOOOOO RRRRRRRRRRRRRRRRR EEEEEEEEEEEEEEEEEEEEEE
V::::::V V::::::V OO:::::::::OO R::::::::::::::::R E::::::::::::::::::::E
V::::::V V::::::V OO:::::::::::::OO R::::::RRRRRR:::::R E::::::::::::::::::::E
V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEEE::::E
V:::::V V:::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE
V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E:::::E
V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E::::::EEEEEEEEEE
V:::::V V:::::V O:::::O O:::::O R:::::::::::::RR E:::::::::::::::E
V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E:::::::::::::::E
V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E::::::EEEEEEEEEE
V:::::V:::::V O:::::O O:::::O R::::R R:::::R E:::::E
V:::::::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE
V:::::::V O:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEE:::::E
V:::::V OO:::::::::::::OO R::::::R R:::::RE::::::::::::::::::::E
V:::V OO:::::::::OO R::::::R R:::::RE::::::::::::::::::::E
VVV OOOOOOOOO RRRRRRRR RRRRRRREEEEEEEEEEEEEEEEEEEEEE
-Aro <3 */
//
// Overrides/additions to stock defines go here, as well as hooks. Sort them by
// the object they are overriding. So all /mob/living together, etc.
//
//
// The datum type bolted onto normal preferences datums for storing Vore stuff
//
#define VORE_VERSION 4
GLOBAL_LIST_EMPTY(vore_preferences_datums)
/client
var/datum/vore_preferences/prefs_vr
/datum/vore_preferences
//Actual preferences
var/digestable = FALSE
var/devourable = FALSE
var/feeding = FALSE
var/lickable = FALSE
// var/allowmobvore = TRUE
var/list/belly_prefs = list()
var/vore_taste = "nothing in particular"
// var/can_be_drop_prey = FALSE
// var/can_be_drop_pred = FALSE
//Mechanically required
var/path
var/slot
var/client/client
var/client_ckey
/datum/vore_preferences/New(client/C)
if(istype(C))
client = C
client_ckey = C.ckey
load_vore()
//
// Check if an object is capable of eating things, based on vore_organs
//
/proc/is_vore_predator(var/mob/living/O)
if(istype(O,/mob/living))
if(O.vore_organs.len > 0)
return TRUE
return FALSE
//
// Belly searching for simplifying other procs
// Mostly redundant now with belly-objects and isbelly(loc)
//
/proc/check_belly(atom/movable/A)
return isbelly(A.loc)
//
// Save/Load Vore Preferences
//
/datum/vore_preferences/proc/load_path(ckey,slot,filename="character",ext="json")
if(!ckey || !slot) return
path = "data/player_saves/[ckey[1]]/[ckey]/vore/[filename][slot].[ext]"
/datum/vore_preferences/proc/load_vore()
if(!client || !client_ckey)
return FALSE //No client, how can we save?
if(!client.prefs || !client.prefs.default_slot)
return FALSE //Need to know what character to load!
slot = client.prefs.default_slot
load_path(client_ckey,slot)
if(!path) return FALSE //Path couldn't be set?
if(!fexists(path)) //Never saved before
save_vore() //Make the file first
return TRUE
var/list/json_from_file = json_decode(file2text(path))
if(!json_from_file)
return FALSE //My concern grows
var/version = json_from_file["version"]
json_from_file = patch_version(json_from_file,version)
digestable = json_from_file["digestable"]
devourable = json_from_file["devourable"]
feeding = json_from_file["feeding"]
lickable = json_from_file["lickable"]
vore_taste = json_from_file["vore_taste"]
belly_prefs = json_from_file["belly_prefs"]
//Quick sanitize
if(isnull(digestable))
digestable = FALSE
if(isnull(devourable))
devourable = FALSE
if(isnull(feeding))
feeding = FALSE
if(isnull(lickable))
lickable = FALSE
if(isnull(belly_prefs))
belly_prefs = list()
return TRUE
/datum/vore_preferences/proc/save_vore()
if(!path)
return FALSE
var/version = VORE_VERSION //For "good times" use in the future
var/list/settings_list = list(
"version" = version,
"digestable" = digestable,
"devourable" = devourable,
"feeding" = feeding,
"lickable" = lickable,
"vore_taste" = vore_taste,
"belly_prefs" = belly_prefs,
)
//List to JSON
var/json_to_file = json_encode(settings_list)
if(!json_to_file)
testing("Saving: [path] failed jsonencode")
return FALSE
//Write it out
//#ifdef RUST_G
// call(RUST_G, "file_write")(json_to_file, path)
//#else
// Fall back to using old format if we are not using rust-g
if(fexists(path))
fdel(path) //Byond only supports APPENDING to files, not replacing.
text2file(json_to_file, path)
//#endif
if(!fexists(path))
testing("Saving: [path] failed file write")
return FALSE
return TRUE
/* commented out list things
"allowmobvore" = allowmobvore,
"can_be_drop_prey" = can_be_drop_prey,
"can_be_drop_pred" = can_be_drop_pred, */
//Can do conversions here
datum/vore_preferences/proc/patch_version(var/list/json_from_file,var/version)
return json_from_file
#undef VORE_VERSION
+29 -25
View File
@@ -6,7 +6,6 @@
#define BELLIES_NAME_MIN 2
#define BELLIES_NAME_MAX 12
#define BELLIES_DESC_MAX 1024
#define FLAVOR_MAX 40
/mob/living/proc/insidePanel()
set name = "Vore Panel"
@@ -247,8 +246,8 @@
dat += "<br><a style='background:[user.digestable ? pref_on : pref_off];' href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: [user.digestable ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[user.devourable ? pref_on : pref_off];' href='?src=\ref[src];toggledvor=1'>Toggle Devourable (Currently: [user.devourable ? "ON" : "OFF"])</a>"
dat += "<br><a style='background:[user.feeding ? pref_on : pref_off];' href='?src=\ref[src];toggledfeed=1'>Toggle Feeding (Currently: [user.feeding ? "ON" : "OFF"])</a>"
if(user.client.prefs_vr)
dat += "<br><a style='background:[user.client.prefs_vr.lickable ? pref_on : pref_off];' href='?src=\ref[src];toggledlickable=1'>Toggle Licking (Currently: [user.client.prefs_vr.lickable ? "ON" : "OFF"])</a>"
if(user.client.prefs)
dat += "<br><a style='background:[user.client.prefs.lickable ? pref_on : pref_off];' href='?src=\ref[src];toggledlickable=1'>Toggle Licking (Currently: [user.client.prefs.lickable ? "ON" : "OFF"])</a>"
//Returns the dat html to the vore_look
return dat
@@ -659,18 +658,19 @@
user.vore_selected = user.vore_organs[1]
if(href_list["saveprefs"])
if(!user.save_vore_prefs())
if(!(user.client?.prefs))
return FALSE
if(!user.client.prefs.save_character())
to_chat(user, "<span class='warning'>Belly Preferences not saved!</span>")
log_admin("Could not save vore prefs on USER: [user].")
else
to_chat(user, "<span class='notice'>Belly Preferences were saved!</span>")
log_admin("Could not save vore prefs on USER: [user].")
if(href_list["applyprefs"])
var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel")
var/alert = alert("Are you sure you want to reload the current slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel")
if(!alert == "Reload")
return FALSE
if(!user.apply_vore_prefs())
if(!user.copy_from_prefs_vr())
alert("ERROR: Vore preferences failed to apply!","Error")
else
to_chat(user,"<span class='notice'>Vore preferences applied from active slot!</span>")
@@ -681,13 +681,15 @@
return FALSE
new_flavor = readd_quotes(new_flavor)
if(length(new_flavor) > FLAVOR_MAX)
alert("Entered flavor/taste text too long. [FLAVOR_MAX] character limit.","Error!")
if(length(new_flavor) > MAX_TASTE_LEN)
alert("Entered flavor/taste text too long. [MAX_TASTE_LEN] character limit.","Error!")
return FALSE
user.vore_taste = new_flavor
if(href_list["toggledg"])
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable to all mobs. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
@@ -696,11 +698,12 @@
if("Prevent Digestion")
user.digestable = FALSE
if(user.client.prefs_vr)
user.client.prefs_vr.digestable = user.digestable
user.client.prefs.digestable = user.digestable
if(href_list["toggledvor"])
var/choice = alert(user, "This button is for those who don't like vore at all. Devouring you is currently: [user.devourable ? "Allowed" : "Prevented"]", "", "Allow Devourment", "Cancel", "Prevent Devourment")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
@@ -709,11 +712,12 @@
if("Prevent Devourment")
user.devourable = FALSE
if(user.client.prefs_vr)
user.client.prefs_vr.devourable = user.devourable
user.client.prefs.devourable = user.devourable
if(href_list["toggledfeed"])
var/choice = alert(user, "This button is to toggle your ability to be fed to others. Feeding predators is currently: [user.feeding ? "Allowed" : "Prevented"]", "", "Allow Feeding", "Cancel", "Prevent Feeding")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
@@ -722,19 +726,19 @@
if("Prevent Feeding")
user.feeding = FALSE
if(user.client.prefs_vr)
user.client.prefs_vr.feeding = user.feeding
user.client.prefs.feeding = user.feeding
if(href_list["toggledlickable"])
if(user.client.prefs_vr)
var/choice = alert(user, "This button is to toggle your ability to be licked. Being licked is currently: [user.client.prefs_vr.lickable ? "Allowed" : "Prevented"]", "", "Allow Licking", "Cancel", "Prevent Licking")
switch(choice)
if("Cancel")
return FALSE
if("Allow Licking")
user.client.prefs_vr.lickable = TRUE
if("Prevent Licking")
user.client.prefs_vr.lickable = FALSE
var/choice = alert(user, "This button is to toggle your ability to be licked. Being licked is currently: [user.client.prefs.lickable ? "Allowed" : "Prevented"]", "", "Allow Licking", "Cancel", "Prevent Licking")
if(!user || !user.client)
return
switch(choice)
if("Cancel")
return FALSE
if("Allow Licking")
user.client.prefs.lickable = TRUE
if("Prevent Licking")
user.client.prefs.lickable = FALSE
//Refresh when interacted with, returning 1 makes vore_look.Topic update
return TRUE