diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index 2e3f8b07600..0a2e49d907c 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -13,6 +13,9 @@ #define O_ORCH "orchestrator" #define O_FACT "refactory" +//Alraune organs +#define A_FRUIT "fruit gland" + //species defines #define SPECIES_AKULA "Akula" #define SPECIES_ALRAUNE "Alraune" diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 162cdd371d7..b5a73224fc7 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -199,6 +199,12 @@ var/global/list/datum/dna/gene/dna_genes[0] src.base_species = CS.base_species src.blood_color = CS.blood_color + if(istype(character.species,/datum/species/alraune)) + var/datum/species/alraune/CS = character.species + //src.species_traits = CS.traits.Copy() //No traits + src.base_species = CS.base_species + src.blood_color = CS.blood_color + // +1 to account for the none-of-the-above possibility SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1) SetUIValueRange(DNA_UI_TAIL_STYLE, tail_style + 1, tail_styles_list.len + 1, 1) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index a7e7d2ddae2..f4fcffbd348 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -233,6 +233,11 @@ var/datum/species/xenochimera/CS = H.species var/datum/species/xenochimera/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src) new_CS.blood_color = dna.blood_color + + if(istype(H.species,/datum/species/alraune)) + var/datum/species/alraune/CS = H.species + var/datum/species/alraune/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src) + new_CS.blood_color = dna.blood_color // VOREStation Edit End H.force_update_organs() //VOREStation Add - Gotta do this too diff --git a/code/global_vr.dm b/code/global_vr.dm index 8b4ab024fc7..154613a4bb1 100644 --- a/code/global_vr.dm +++ b/code/global_vr.dm @@ -5,3 +5,30 @@ robot_module_types += "Sci-borg" robot_module_types += "Pupdozer" return 1 + +var/global/list/acceptable_fruit_types= list( + "ambrosia", + "apple", + "banana", + "berry", + "cabbage", + "carrot", + "cherry", + "chili", + "eggplant", + "grape", + "greengrapes", + "lemon", + "lime", + "onion", + "orange", + "peanut", + "potato", + "pumpkin", + "rice", + "soybean", + "sugarcane", + "tomato", + "watermelon", + "wheat", + "whitebeet") \ No newline at end of file diff --git a/code/modules/client/preference_setup/vore/07_traits.dm b/code/modules/client/preference_setup/vore/07_traits.dm index e01f7380667..c57f4851469 100644 --- a/code/modules/client/preference_setup/vore/07_traits.dm +++ b/code/modules/client/preference_setup/vore/07_traits.dm @@ -73,14 +73,16 @@ if(!(path in negative_traits)) pref.neg_traits -= path - if(pref.species == pref.custom_base && pref.species != SPECIES_CUSTOM) + var/datum/species/selected_species = all_species[pref.species] + if(selected_species.selects_bodytype) // Allowed! else if(!pref.custom_base || !(pref.custom_base in custom_species_bases)) pref.custom_base = SPECIES_HUMAN /datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character) character.custom_species = pref.custom_species - if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA) + var/datum/species/selected_species = all_species[pref.species] + if(selected_species.selects_bodytype) var/datum/species/custom/CS = character.species var/S = pref.custom_base ? pref.custom_base : "Human" var/datum/species/custom/new_CS = CS.produceCopy(S, pref.pos_traits + pref.neu_traits + pref.neg_traits, character) @@ -92,7 +94,8 @@ . += "Custom Species " . += "[pref.custom_species ? pref.custom_species : "-Input Name-"]
" - if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA) + var/datum/species/selected_species = all_species[pref.species] + if(selected_species.selects_bodytype) . += "Icon Base: " . += "[pref.custom_base ? pref.custom_base : "Human"]
" diff --git a/code/modules/mob/living/carbon/human/human_defines_vr.dm b/code/modules/mob/living/carbon/human/human_defines_vr.dm index d3bb4f0b57f..f856e4ab399 100644 --- a/code/modules/mob/living/carbon/human/human_defines_vr.dm +++ b/code/modules/mob/living/carbon/human/human_defines_vr.dm @@ -6,4 +6,4 @@ var/wagging = 0 //UGH. var/flapping = 0 var/vantag_pref = VANTAG_NONE //What's my status? - var/impersonate_bodytype //For impersonating a bodytype \ No newline at end of file + var/impersonate_bodytype //For impersonating a bodytype diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index 703986ceb58..ba9e6344957 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -13,6 +13,8 @@ min_age = 18 max_age = 250 health_hud_intensity = 1.5 + base_species = SPECIES_ALRAUNE + selects_bodytype = TRUE body_temperature = T20C breath_type = "carbon_dioxide" @@ -47,7 +49,8 @@ /mob/living/carbon/human/proc/succubus_drain, /mob/living/carbon/human/proc/succubus_drain_finalize, /mob/living/carbon/human/proc/succubus_drain_lethal, - /mob/living/carbon/human/proc/bloodsuck) //Give them the voremodes related to wrapping people in vines and sapping their fluids + /mob/living/carbon/human/proc/bloodsuck, + /mob/living/carbon/human/proc/alraune_fruit_select) //Give them the voremodes related to wrapping people in vines and sapping their fluids color_mult = 1 icobase = 'icons/mob/human_races/r_human_vr.dmi' @@ -85,6 +88,7 @@ O_KIDNEYS = /obj/item/organ/internal/kidneys/alraune, O_BRAIN = /obj/item/organ/internal/brain/alraune, O_EYES = /obj/item/organ/internal/eyes/alraune, + A_FRUIT = /obj/item/organ/internal/fruitgland, ) /datum/species/alraune/can_breathe_water() @@ -331,5 +335,164 @@ /obj/item/organ/internal/liver/alraune icon = 'icons/mob/species/alraune/organs.dmi' icon_state = "phytoextractor" - name = "phytoextractor" - desc = "A bulbous gourd-like structure." \ No newline at end of file + name = "enzoretector" + desc = "A bulbous gourd-like structure." + +//Begin fruit gland and its code. +/obj/item/organ/internal/fruitgland //Amazing name, I know. + icon = 'icons/mob/species/alraune/organs.dmi' + icon_state = "phytoextractor" + name = "fruit gland" + desc = "A bulbous gourd-like structure." + organ_tag = A_FRUIT + var/generated_reagents = list("sugar" = 2) //This actually allows them. This could be anything, but sugar seems most fitting. + var/usable_volume = 250 //Five fruit. + var/transfer_amount = 50 + var/empty_message = list("Your have no fruit on you.", "You have a distinct lack of fruit..") + var/full_message = list("You have a multitude of fruit that is ready for harvest!", "You have fruit that is ready to be picked!") + var/emote_descriptor = list("fruit right off of the Alraune!", "a fruit from the Alraune!") + var/verb_descriptor = list("grabs", "snatches", "picks") + var/self_verb_descriptor = list("grab", "snatch", "pick") + var/short_emote_descriptor = list("picks", "grabs") + var/self_emote_descriptor = list("grab", "pick", "snatch") + var/fruit_type = "apple" + var/mob/organ_owner = null + var/gen_cost = 0.5 + +/obj/item/organ/internal/fruitgland/New() + ..() + create_reagents(usable_volume) + + +/obj/item/organ/internal/fruitgland/process() + if(!owner) return + var/obj/item/organ/external/parent = owner.get_organ(parent_organ) + var/before_gen + if(parent && generated_reagents && organ_owner) //Is it in the chest/an organ, has reagents, and is 'activated' + before_gen = reagents.total_volume + if(reagents.total_volume < reagents.maximum_volume) + if(organ_owner.nutrition >= gen_cost) + do_generation() + + if(reagents) + if(reagents.total_volume == reagents.maximum_volume * 0.05) + to_chat(organ_owner, "[pick(empty_message)]") + else if(reagents.total_volume == reagents.maximum_volume && before_gen < reagents.maximum_volume) + to_chat(organ_owner, "[pick(full_message)]") + +/obj/item/organ/internal/fruitgland/proc/do_generation() + organ_owner.nutrition -= gen_cost + for(var/reagent in generated_reagents) + reagents.add_reagent(reagent, generated_reagents[reagent]) + + +/mob/living/carbon/human/proc/alraune_fruit_select() //So if someone doesn't want fruit/vegetables, they don't have to select one. + set name = "Select fruit" + set desc = "Select what fruit/vegetable you wish to grow." + set category = "Object" + var/obj/item/organ/internal/fruitgland/fruit_gland + for(var/F in contents) + if(istype(F, /obj/item/organ/internal/fruitgland)) + fruit_gland = F + break + + if(fruit_gland) + var/selection = input(src, "Choose your character's fruit type. Choosing nothing will result in a default of apples.", "Fruit Type", fruit_gland.fruit_type) as null|anything in acceptable_fruit_types + if(selection) + fruit_gland.fruit_type = selection + verbs |= /mob/living/carbon/human/proc/alraune_fruit_pick + verbs -= /mob/living/carbon/human/proc/alraune_fruit_select + fruit_gland.organ_owner = src + fruit_gland.emote_descriptor = list("fruit right off of [fruit_gland.organ_owner]!", "a fruit from [fruit_gland.organ_owner]!") + + else + to_chat(src, "You lack the organ required to produce fruit.") + return + +/mob/living/carbon/human/proc/alraune_fruit_pick() + set name = "Pick Fruit" + set desc = "Pick fruit off of [src]." + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.canClick()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/organ/internal/fruitgland/fruit_gland + for(var/I in contents) + if(istype(I, /obj/item/organ/internal/fruitgland)) + fruit_gland = I + break + if (fruit_gland) //Do they have the gland? + if(fruit_gland.reagents.total_volume < fruit_gland.transfer_amount) + to_chat(src, "[pick(fruit_gland.empty_message)]") + return + + var/datum/seed/S = plant_controller.seeds["[fruit_gland.fruit_type]"] + S.harvest(usr,0,0,1) + + var/index = rand(0,2) + + if (usr != src) + var/emote = fruit_gland.emote_descriptor[index] + var/verb_desc = fruit_gland.verb_descriptor[index] + var/self_verb_desc = fruit_gland.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(fruit_gland.short_emote_descriptor)] a fruit.", + "You [pick(fruit_gland.self_emote_descriptor)] a fruit.") + + fruit_gland.reagents.remove_any(fruit_gland.transfer_amount) + +//End of fruit gland code. + +/datum/species/alraune/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H) + ASSERT(to_copy) + ASSERT(istype(H)) + + if(ispath(to_copy)) + to_copy = "[initial(to_copy.name)]" + if(istext(to_copy)) + to_copy = all_species[to_copy] + + var/datum/species/alraune/new_copy = new() + + //Initials so it works with a simple path passed, or an instance + new_copy.base_species = to_copy.name + new_copy.icobase = to_copy.icobase + new_copy.deform = to_copy.deform + new_copy.tail = to_copy.tail + new_copy.tail_animation = to_copy.tail_animation + new_copy.icobase_tail = to_copy.icobase_tail + new_copy.color_mult = to_copy.color_mult + new_copy.primitive_form = to_copy.primitive_form + new_copy.appearance_flags = to_copy.appearance_flags + new_copy.flesh_color = to_copy.flesh_color + new_copy.base_color = to_copy.base_color + new_copy.blood_mask = to_copy.blood_mask + new_copy.damage_mask = to_copy.damage_mask + new_copy.damage_overlays = to_copy.damage_overlays + + //Set up a mob + H.species = new_copy + H.icon_state = lowertext(new_copy.get_bodytype()) + + if(new_copy.holder_type) + H.holder_type = new_copy.holder_type + + if(H.dna) + H.dna.ready_dna(H) + + return new_copy + +/datum/species/alraune/get_bodytype() + return base_species + +/datum/species/alraune/get_race_key() + var/datum/species/real = all_species[base_species] + return real.race_key diff --git a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm index f2847a1523a..45c5f4b8f3e 100644 --- a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm @@ -1,15 +1,18 @@ /datum/species //var/vore_numbing = 0 - var/gets_food_nutrition = 1 // If this is set to 0, the person can't get nutrition from food. + var/gets_food_nutrition = TRUE // If this is set to 0, the person can't get nutrition from food. var/metabolism = 0.0015 - var/lightweight = 0 //Oof! Nonhelpful bump stumbles. - var/trashcan = 0 //It's always sunny in the wrestling ring. + var/lightweight = FALSE //Oof! Nonhelpful bump stumbles. + var/trashcan = FALSE //It's always sunny in the wrestling ring. + var/base_species = null // Unused outside of a few species + var/selects_bodytype = FALSE // Allows the species to choose from body types intead of being forced to be just one. /datum/species/custom name = SPECIES_CUSTOM name_plural = "Custom" - var/base_species = "Human" + selects_bodytype = TRUE + base_species = SPECIES_HUMAN unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm index 618382f3a8f..05237f5742a 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm @@ -1,7 +1,7 @@ #define DAM_SCALE_FACTOR 0.01 #define METAL_PER_TICK 150 /datum/species/protean - name = "Protean" + name = SPECIES_PROTEAN name_plural = "Proteans" blurb = "Sometimes very advanced civilizations will produce the ability to swap into manufactured, robotic bodies. And sometimes \ VERY advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \ @@ -139,7 +139,7 @@ if(H.backbag == 1) //Somewhat misleading, 1 == no bag (not boolean) H.equip_to_slot_or_del(permit, slot_l_hand) - H.equip_to_slot_or_del(metal_stack, slot_r_hand) + H.equip_to_slot_or_del(metal_stack, slot_r_hand) else H.equip_to_slot_or_del(permit, slot_in_backpack) H.equip_to_slot_or_del(metal_stack, slot_in_backpack) @@ -172,7 +172,7 @@ var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs if(refactory && !(refactory.status & ORGAN_DEAD)) - + //MHydrogen adds speeeeeed if(refactory.get_stored_material("mhydrogen") >= METAL_PER_TICK) H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory) @@ -233,7 +233,7 @@ var/obj/item/organ/internal/nano/refactory/refactory = origin.resolve() if(!istype(refactory) || refactory.status & ORGAN_DEAD) expire() - + //Out of materials if(!refactory.use_stored_material(material_name,material_use)) expire() @@ -255,7 +255,7 @@ on_created_text = "You feel yourself become nearly impervious to physical attacks as plasteel nanites are made." on_expired_text = "Your refactory finishes consuming the plasteel, and you return to your normal nanites." - + material_name = "plasteel" incoming_brute_damage_percent = 0.5 @@ -266,7 +266,7 @@ on_created_text = "You feel yourself become more reflective, able to resist heat and fire better for a time." on_expired_text = "Your refactory finishes consuming the diamond, and you return to your normal nanites." - + material_name = "diamond" incoming_fire_damage_percent = 0.2 @@ -277,7 +277,7 @@ on_created_text = "You feel new nanites being produced from your stockpile of steel, healing you slowly." on_expired_text = "Your steel supply has either run out, or is no longer needed, and your healing stops." - + material_name = "steel" /datum/modifier/protean/steel/tick() diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm index aa8af0e273e..5315840a82f 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm @@ -5,7 +5,7 @@ /datum/species/xenochimera //Scree's race. - name = "Xenochimera" + name = SPECIES_XENOCHIMERA name_plural = "Xenochimeras" icobase = 'icons/mob/human_races/r_xenochimera.dmi' deform = 'icons/mob/human_races/r_def_xenochimera.dmi' @@ -14,7 +14,8 @@ slowdown = -0.2 //scuttly, but not as scuttly as a tajara or a teshari. brute_mod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though. burn_mod = 1.15 //As vulnerable to burn as a Tajara. - var/base_species = "Xenochimera" + base_species = "Xenochimera" + selects_bodytype = TRUE num_alternate_languages = 2 secondary_langs = list("Sol Common") @@ -300,7 +301,7 @@ /////SPIDER RACE///// ///////////////////// /datum/species/spider //These actually look pretty damn spooky! - name = "Vasilissan" + name = SPECIES_VASILISSAN name_plural = "Vasilissans" icobase = 'icons/mob/human_races/r_spider.dmi' deform = 'icons/mob/human_races/r_def_spider.dmi' diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 7b608e5c560..3d118f285b4 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -22,7 +22,7 @@ var/fuzzy = 1 // Preference toggle for sharp/fuzzy icon. var/tail_alt = 0 // Tail layer toggle. var/can_be_drop_prey = 0 - var/can_be_drop_pred = 1 //Mobs are pred by default. + var/can_be_drop_pred = 1 // Mobs are pred by default. // // Hook for generic creation of stuff on new creatures diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index b01e3a9e2c2..b28f145cca1 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -995,70 +995,6 @@ rimplant.reagents.remove_any(rimplant.transfer_amount) -/obj/item/weapon/implant/reagent_generator/pumila_apple - name = "apple laying implant" - desc = "This is an implant that allows the user to grow apples." - generated_reagents = list("sugar" = 2) //This actually allows them to. - usable_volume = 250 //Five apples. Let's not get /too/ crazy here. - transfer_amount = 50 - - empty_message = list("Your have no apples on you.", "You have a distinct lack of apples..") - full_message = list("You have multiple apples on you, ready for harvest!", "There are a multitude of apples awaiting harvest on you!") - emote_descriptor = list("an apple right off of Pumila!", "a large apple off Pumila!") - var/verb_descriptor = list("grabs", "snatches", "picks") - var/self_verb_descriptor = list("grab", "snatch", "pick") - var/short_emote_descriptor = list("picks", "grabs") - self_emote_descriptor = list("grab", "pick", "snatch") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_pumila_apple - -/obj/item/weapon/implant/reagent_generator/pumila_apple/post_implant(mob/living/carbon/source) - processing_objects += src - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/pumila_apple - implant_type = /obj/item/weapon/implant/reagent_generator/pumila_apple - -/mob/living/carbon/human/proc/use_reagent_implant_pumila_apple() - set name = "Grab Apple" - set desc = "Grab an apple off of Pumila." - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.canClick()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/roiz/rimplant - for(var/I in contents) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume < rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - var/datum/seed/S = plant_controller.seeds["apple"] //crosses fingers. - S.harvest(usr,0,0,1) - - var/index = rand(0,2) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] [pick(rimplant.short_emote_descriptor)] an apple.", - "You [pick(rimplant.self_emote_descriptor)] an apple.") - - rimplant.reagents.remove_any(rimplant.transfer_amount) /* /obj/item/weapon/implant/reagent_generator/pumila_nectar //Bugged. Two implants at once messes things up. generated_reagents = list("honey" = 2) @@ -1998,7 +1934,7 @@ KA.desc = initial(KA.desc) KA.icon = initial(KA.icon) ..() - + //ArgobargSoup:Lynn Shady /obj/item/device/flashlight/pen/fluff/lynn name = "Lynn's penlight" diff --git a/config/custom_items.txt b/config/custom_items.txt index 63aa433f408..95a98545d61 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -613,12 +613,6 @@ character_name: Pumila item_path: /obj/item/clothing/under/fluff/aluranevines } -{ -ckey: natje -character_name: Pumila -item_path: /obj/item/weapon/implanter/reagent_generator/pumila_apple -} - { ckey: nepox character_name: Annie Rose