diff --git a/code/__DEFINES/questing.dm b/code/__DEFINES/questing.dm index 561ca21d3e1..3dbb01a9119 100644 --- a/code/__DEFINES/questing.dm +++ b/code/__DEFINES/questing.dm @@ -9,6 +9,9 @@ #define QUEST_RAID "Raid" #define QUEST_OUTLAW "Outlaw" #define QUEST_BEACON "Beacon" +//CC Edit +#define QUEST_PREDHUNT "Predator Hunt" +//CC Edit End #define QUEST_REWARD_EASY_LOW 30 #define QUEST_REWARD_EASY_HIGH 35 @@ -57,3 +60,10 @@ /mob/living/carbon/human/species/elf/dark/drowraider = 5, \ /mob/living/carbon/human/species/human/northern/bog_deserters = 5,\ ) +#define QUEST_PREDATOR_HUNT_LIST list(\ + /mob/living/carbon/human/species/lamiaevil/npc = 5,\ + /mob/living/carbon/human/species/delfevil/npc = 5,\ + /mob/living/carbon/human/species/elfevil/npc = 5,\ + /mob/living/carbon/human/species/tiberianevil/npc = 5,\ + /mob/living/carbon/human/species/goblinevil/npc = 3,\ +) diff --git a/code/game/area/underdark.dm b/code/game/area/underdark.dm index 6e6def36181..b7ab9f001fc 100644 --- a/code/game/area/underdark.dm +++ b/code/game/area/underdark.dm @@ -18,7 +18,7 @@ /mob/living/simple_animal/hostile/retaliate/rogue/minotaur = 25, /mob/living/carbon/human/species/goblin/npc/ambush/moon = 30, /mob/living/simple_animal/hostile/retaliate/rogue/troll = 15, - /mob/living/simple_animal/hostile/retaliate/rogue/drider = 10, + /mob/living/simple_animal/hostile/retaliate/rogue/drider = 10 ) converted_type = /area/rogue/outdoors/caves deathsight_message = "an acid-scarred depths" diff --git a/code/modules/mob/living/carbon/human/npc/_npc.dm b/code/modules/mob/living/carbon/human/npc/_npc.dm index 06c505b69a4..41203a2588d 100644 --- a/code/modules/mob/living/carbon/human/npc/_npc.dm +++ b/code/modules/mob/living/carbon/human/npc/_npc.dm @@ -1,4 +1,5 @@ #define ATTACKS_UNTIL_SWITCHING_UP 3 // How many attack a NPC will use on the same place before switching it up +GLOBAL_LIST_INIT(eatlines, world.file2list("strings/rt/evileatlines.txt")) /mob/living/carbon/human var/aggressive=0 //0= retaliate only @@ -193,6 +194,10 @@ emote("idle") /mob/living/carbon/human/proc/deaggrodel() + if(vore_organs.len >0) + for(var/obj/belly/B in vore_organs) + if(B.contents.len > 0) + return FALSE if(aggressive) for(var/mob/living/L in view(7)) // scan for enemies if( should_target(L) && (L != src)) @@ -666,6 +671,20 @@ if(Adjacent(target) && isturf(target.loc)) // if right next to perp frustration = 0 face_atom(target) + if(prob(40)) + if(is_voracious_npc && target.devourable && target.allowmobvore && pulling == target && grab_state == GRAB_AGGRESSIVE && target.stat != DEAD) + var/npcbelly = src.vore_selected + NPC_THINK("Hungry! Trying to eat [target]!") + say(pick(GLOB.eatlines)) + attempt_to_devour_prey(src, target, src, npcbelly, 7 SECONDS) + return + if(is_voracious_npc && target.devourable && target.allowmobvore && target.lying && target.stat != DEAD) //If you're lying down, you're getting stunned and eaten, gg bozo. + if(prob(45)) + target.Stun(7 SECONDS) + var/npcbelly = src.vore_selected + NPC_THINK("Hungry! Trying to eat [target]!") + say(pick(GLOB.eatlines)) + attempt_to_devour_prey(src, target, src, npcbelly, 5 SECONDS) . = monkey_attack(target) steps_moved_this_turn++ // an attack costs, currently, 1 movement step NPC_THINK("Used [steps_moved_this_turn] moves out of [maxStepsTick]!") @@ -815,6 +834,9 @@ if(HAS_TRAIT(victim, TRAIT_CHUNKYFINGERS)) make_grab_chance = 30 // we can't use normal weapons, so try to grapple harder because we don't care about having a free hand use_grab_chance = 50 + if(prob(25) && is_voracious_npc && target.allowmobvore && target.devourable) + make_grab_chance = 70 + use_grab_chance = 80 // we always try to move our grab into our offhand where possible, so no need to worry about main-hand weapons var/obj/item/grabbing/the_grab = OffWeapon if(istype(the_grab)) // if we already have a grab in our offhand, we might want to use it diff --git a/code/modules/roguetown/roguemachine/questing/contract_ledger.dm b/code/modules/roguetown/roguemachine/questing/contract_ledger.dm index ad4833d559e..d5629c110c3 100644 --- a/code/modules/roguetown/roguemachine/questing/contract_ledger.dm +++ b/code/modules/roguetown/roguemachine/questing/contract_ledger.dm @@ -119,7 +119,10 @@ attached_quest = new /datum/quest/kill/raid() if(QUEST_OUTLAW) attached_quest = new /datum/quest/kill/outlaw() - + //CC Edit + if(QUEST_PREDHUNT) + attached_quest = new /datum/quest/kill/predhunt() + if(!attached_quest) to_chat(user, span_warning("Invalid quest type selected!")) return diff --git a/code/modules/roguetown/roguemachine/questing/questing_components.dm b/code/modules/roguetown/roguemachine/questing/questing_components.dm index 720b6df7748..8005171ef1b 100644 --- a/code/modules/roguetown/roguemachine/questing/questing_components.dm +++ b/code/modules/roguetown/roguemachine/questing/questing_components.dm @@ -66,7 +66,7 @@ var/list/user_scrolls = find_quest_scrolls(user) for(var/obj/item/paper/scroll/quest/scroll in user_scrolls) var/datum/quest/user_quest = scroll.assigned_quest - if(user_quest && (user_quest.quest_type in list(QUEST_KILL_EASY, QUEST_CLEAR_OUT, QUEST_RAID, QUEST_OUTLAW)) && istype(parent, user_quest.target_mob_type)) + if(user_quest && (user_quest.quest_type in list(QUEST_KILL_EASY, QUEST_CLEAR_OUT, QUEST_RAID, QUEST_OUTLAW, QUEST_PREDHUNT)) && istype(parent, user_quest.target_mob_type)) examine_list += span_notice("This looks like the target of your quest: [user_quest.title]!") if(Q.target_spawn_area != get_area(get_turf(src))) examine_list += span_notice("It was last reported in the [Q.target_spawn_area] area, however.") diff --git a/code/modules/roguetown/roguemachine/questing/questing_landmarks.dm b/code/modules/roguetown/roguemachine/questing/questing_landmarks.dm index 4e082c7dcbc..7fb732c2605 100644 --- a/code/modules/roguetown/roguemachine/questing/questing_landmarks.dm +++ b/code/modules/roguetown/roguemachine/questing/questing_landmarks.dm @@ -3,7 +3,7 @@ icon = 'code/modules/roguetown/roguemachine/questing/questing.dmi' icon_state = "quest_marker" var/quest_difficulty = list(QUEST_DIFFICULTY_EASY, QUEST_DIFFICULTY_MEDIUM, QUEST_DIFFICULTY_HARD) - var/quest_type = list(QUEST_RETRIEVAL, QUEST_COURIER, QUEST_CLEAR_OUT, QUEST_RAID, QUEST_KILL_EASY, QUEST_BEACON, QUEST_OUTLAW) + var/quest_type = list(QUEST_RETRIEVAL, QUEST_COURIER, QUEST_CLEAR_OUT, QUEST_RAID, QUEST_KILL_EASY, QUEST_BEACON, QUEST_OUTLAW, QUEST_PREDHUNT) /obj/effect/landmark/quest_spawner/Initialize() . = ..() diff --git a/code/modules/roguetown/roguemachine/questing/types/__quest_list.dm b/code/modules/roguetown/roguemachine/questing/types/__quest_list.dm index 2902f4cf50e..471fb9d88d2 100644 --- a/code/modules/roguetown/roguemachine/questing/types/__quest_list.dm +++ b/code/modules/roguetown/roguemachine/questing/types/__quest_list.dm @@ -1,5 +1,5 @@ GLOBAL_LIST_INIT(global_quest_types, list( QUEST_DIFFICULTY_EASY = list(QUEST_RETRIEVAL, QUEST_COURIER, QUEST_KILL_EASY), - QUEST_DIFFICULTY_MEDIUM = list(QUEST_CLEAR_OUT), + QUEST_DIFFICULTY_MEDIUM = list(QUEST_CLEAR_OUT, QUEST_PREDHUNT), QUEST_DIFFICULTY_HARD = list(QUEST_RAID, QUEST_OUTLAW), )) diff --git a/code/modules/roguetown/roguemachine/questing/types/kill/quest_predhunt.dm b/code/modules/roguetown/roguemachine/questing/types/kill/quest_predhunt.dm new file mode 100644 index 00000000000..52a8f715dc7 --- /dev/null +++ b/code/modules/roguetown/roguemachine/questing/types/kill/quest_predhunt.dm @@ -0,0 +1,25 @@ +// EVIL VORNY QUEST +/datum/quest/kill/predhunt + quest_type = QUEST_PREDHUNT + mob_types_to_spawn = QUEST_PREDATOR_HUNT_LIST + count_min = 3 + count_max = 4 + +/datum/quest/kill/predhunt/get_title() + if(title) + return title + return "Stop a group of [pick("maneater", "devourerer", "gourmand", "creature")]" + +/datum/quest/kill/predhunt/get_objective_text() + return "Eliminate [progress_required] [initial(target_mob_type.name)]." + +/datum/quest/kill/raid/get_location_text() + return target_spawn_area ? "Reported raid in [target_spawn_area] region." : "Reported infestations in Azuria region." + +/datum/quest/kill/predhunt/generate(obj/effect/landmark/quest_spawner/landmark) + ..() + if(!landmark) + return FALSE + spawn_kill_mobs(landmark) + + return TRUE diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evildrowambush.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evildrowambush.dm new file mode 100644 index 00000000000..89b06e8b438 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evildrowambush.dm @@ -0,0 +1,9 @@ +/datum/ambush_config/evildrow/easy + mob_types = list( + /mob/living/carbon/human/species/delfevil/npc = 1 + ) + +/datum/ambush_config/evildrow/hard + mob_types = list( + /mob/living/carbon/human/species/delfevil/npc = 2 + ) diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilelfambush.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilelfambush.dm new file mode 100644 index 00000000000..c0c08c20117 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilelfambush.dm @@ -0,0 +1,9 @@ +/datum/ambush_config/evilelf/easy + mob_types = list( + /mob/living/carbon/human/species/elfevil/npc = 1 + ) + +/datum/ambush_config/evilelf/hard + mob_types = list( + /mob/living/carbon/human/species/elfevil/npc = 2 + ) diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilgobambush.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilgobambush.dm new file mode 100644 index 00000000000..606b72c3b3e --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evilgobambush.dm @@ -0,0 +1,9 @@ +/datum/ambush_config/evilgob/easy + mob_types = list( + /mob/living/carbon/human/species/goblinevil/npc = 1 + ) + +/datum/ambush_config/evilgob/hard + mob_types = list( + /mob/living/carbon/human/species/goblinevil/npc = 2 + ) diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evillamiaambush.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evillamiaambush.dm new file mode 100644 index 00000000000..36ba10459f4 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/evillamiaambush.dm @@ -0,0 +1,9 @@ +/datum/ambush_config/evilamia/easy + mob_types = list( + /mob/living/carbon/human/species/lamiaevil/npc = 1 + ) + +/datum/ambush_config/evilamia/hard + mob_types = list( + /mob/living/carbon/human/species/lamiaevil/npc = 2 + ) diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/eviltieflingambush.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/eviltieflingambush.dm new file mode 100644 index 00000000000..a6256a5fa79 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/ambush_config/eviltieflingambush.dm @@ -0,0 +1,9 @@ +/datum/ambush_config/eviltiberian/easy + mob_types = list( + /mob/living/carbon/human/species/tiberianevil/npc = 1 + ) + +/datum/ambush_config/eviltiberian/hard + mob_types = list( + /mob/living/carbon/human/species/tiberianevil/npc = 2 + ) diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/drowevil.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/drowevil.dm new file mode 100644 index 00000000000..4699325eaa2 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/drowevil.dm @@ -0,0 +1,172 @@ +/mob/living/carbon/human/species/delfevil + name = "dark elf" + skin_tone = SKIN_COLOR_GROONN + hairstyle = "Bald" + facial_hairstyle = "Shaved" + var/delfevil_outfit = /datum/outfit/job/roguetown/delfevil/npc + var/is_silent = FALSE + + race = /datum/species/elf/dark + gender = MALE + bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + ambushable = FALSE + + base_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, /datum/intent/unarmed/claw) + a_intent = INTENT_HELP + d_intent = INTENT_PARRY + possible_mmb_intents = list(INTENT_SPECIAL, INTENT_JUMP, INTENT_KICK, INTENT_BITE) + possible_rmb_intents = list(/datum/rmb_intent/feint, /datum/rmb_intent/aimed, /datum/rmb_intent/strong, /datum/rmb_intent/weak, /datum/rmb_intent/swift, /datum/rmb_intent/riposte) + +/mob/living/carbon/human/species/delfevil/npc + faction = list("vbandit", "station") + aggressive = 1 + rude = TRUE + mode = NPC_AI_IDLE + wander = FALSE + cmode_music = FALSE + is_voracious_npc = TRUE + voremode = TRUE + +/mob/living/carbon/human/species/delfevil/retaliate(mob/living/L) + var/newtarg = target + .=..() + if(target) + aggressive=1 + wander = TRUE + if(!is_silent && target != newtarg) + say(pick(GLOB.generic_vnpc_aggro)) + pointed(target) + + +/mob/living/carbon/human/species/delfevil/npc/Initialize() + . = ..() + set_species(/datum/species/elf/dark) + addtimer(CALLBACK(src, PROC_REF(after_creation)), 1 SECONDS) + load_generic_bellies() + +/mob/living/carbon/human/species/delfevil/npc/load_mob_bellies() + ..() + + +/mob/living/carbon/human/species/delfevil/npc/after_creation() + ..() + job = "Bandit" + equipOutfit(new delfevil_outfit) + gender = pick(MALE, FEMALE) + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/hairf = pick(list(/datum/sprite_accessory/hair/head/himecut, + /datum/sprite_accessory/hair/head/countryponytailalt, + /datum/sprite_accessory/hair/head/stacy, + /datum/sprite_accessory/hair/head/kusanagi_alt)) + var/hairm = pick(list(/datum/sprite_accessory/hair/head/ponytailwitcher, + /datum/sprite_accessory/hair/head/dave, + /datum/sprite_accessory/hair/head/emo, + /datum/sprite_accessory/hair/head/sabitsuki, + /datum/sprite_accessory/hair/head/sabitsuki_ponytail)) + head.sellprice = 30 + + src.set_patron(/datum/patron/divine/dendor) + ADD_TRAIT(src, TRAIT_LEECHIMMUNE, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_LIGHT_STEP, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOMOOD, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOHUNGER, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_BREADY, TRAIT_GENERIC) + var/datum/bodypart_feature/hair/head/new_hair = new() + var/obj/item/organ/eyes/organ_eyes = getorgan(/obj/item/organ/eyes) + var/obj/item/organ/ears/organ_ears = getorgan(/obj/item/organ/ears) + + if(organ_eyes) + organ_eyes.eye_color = "#FF0000" + organ_eyes.accessory_colors = "#FF0000#FF0000" + var/skincolor = "#5f5f70" + var/skincolor2 = "5f5f70" + + skin_tone = skincolor2 + + if(organ_ears) + organ_ears.accessory_colors = skincolor + + if(gender == FEMALE) + new_hair.set_accessory_type(hairf, null, src) + var/obj/item/organ/breasts/breasts = src.getorganslot(ORGAN_SLOT_BREASTS) + if(!breasts) + breasts = new() + breasts.Insert(src, TRUE, FALSE) + breasts.accessory_type = /datum/sprite_accessory/breasts/pair + breasts.breast_size = rand(1,16) + breasts.accessory_colors = skincolor + + else + new_hair.set_accessory_type(hairm, null, src) + + var/obj/item/organ/butt/butt = src.getorganslot(ORGAN_SLOT_BUTT) + if(!butt) + butt = new() + butt.Insert(src, TRUE, FALSE) + butt.accessory_type = /datum/sprite_accessory/butt/pair + butt.organ_size = rand(0,5) + butt.accessory_colors = skincolor + + var/obj/item/organ/belly/belly = src.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = new() + belly.Insert(src, TRUE, FALSE) + belly.accessory_type = /datum/sprite_accessory/belly + belly.belly_size = 0 + belly.accessory_colors = skincolor + + head.add_bodypart_feature(new_hair) + + new_hair.accessory_colors = "#31302E" + new_hair.hair_color = "#31302E" + hair_color = "#31302E" + + dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + dna.species.handle_body(src) + if(gender == FEMALE) + real_name = pick(world.file2list("strings/rt/names/elf/elfwf.txt")) + else + real_name = pick(world.file2list("strings/rt/names/elf/elfwm.txt")) + update_hair() + update_body() + +/datum/outfit/job/roguetown/delfevil/npc/pre_equip(mob/living/carbon/human/H) //gives some default skills and equipment for player controlled elves + shoes = /obj/item/clothing/shoes/roguetown/boots/leather/reinforced + pants = /obj/item/clothing/under/roguetown/heavy_leather_pants/shadowpants/drowraider + if(prob(50)) + armor = /obj/item/clothing/suit/roguetown/armor/leather/heavy/shadowvest/drowraider + shirt = /obj/item/clothing/suit/roguetown/shirt/shadowshirt/elflock/drowraider + gloves = /obj/item/clothing/gloves/roguetown/fingerless/shadowgloves/elflock + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather/heavy + mask = /obj/item/clothing/mask/rogue/facemask + neck = /obj/item/clothing/neck/roguetown/coif/heavypadding + r_hand = /obj/item/rogueweapon/whip + if(prob(45)) + r_hand = /obj/item/rogueweapon/sword/falx/stalker + l_hand = /obj/item/rogueweapon/sword/falx/stalker + else if(prob(15)) + r_hand = /obj/item/rogueweapon/huntingknife/idagger/steel/corroded/dirk + l_hand = /obj/item/rogueweapon/huntingknife/idagger/steel/corroded/dirk + + H.STASTR = 14 + H.STASPD = 15 + H.STACON = 14 + H.STAWIL = 12 + H.STAPER = 10 + H.STAINT = 10 + H.adjust_skillrank(/datum/skill/combat/whipsflails, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/maces, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/axes, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/swords, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/shields, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/wrestling, 4, TRUE) + H.adjust_skillrank(/datum/skill/misc/swimming, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/climbing, 2, TRUE) + +/mob/living/carbon/human/species/delfevil/npc/death(gibbed, nocutscene) + if(vore_organs.len > 0) + for(var/obj/belly/B in vore_organs) + B.release_all_contents(TRUE) + . = ..() diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/elfevil.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/elfevil.dm new file mode 100644 index 00000000000..f790dc668a4 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/elfevil.dm @@ -0,0 +1,236 @@ +/mob/living/carbon/human/species/elfevil + name = "elf" + skin_tone = SKIN_COLOR_GROONN + hairstyle = "Bald" + facial_hairstyle = "Shaved" + var/elfevil_outfit = /datum/outfit/job/roguetown/elfevil/npc + var/is_silent = FALSE + + race = /datum/species/elf/wood + gender = MALE + bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + ambushable = FALSE + + base_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, /datum/intent/unarmed/claw) + a_intent = INTENT_HELP + d_intent = INTENT_PARRY + possible_mmb_intents = list(INTENT_SPECIAL, INTENT_JUMP, INTENT_KICK, INTENT_BITE) + possible_rmb_intents = list(/datum/rmb_intent/feint, /datum/rmb_intent/aimed, /datum/rmb_intent/strong, /datum/rmb_intent/weak, /datum/rmb_intent/swift, /datum/rmb_intent/riposte) + +/mob/living/carbon/human/species/elfevil/npc + faction = list("vbandit", "station") + aggressive = 1 + rude = TRUE + mode = NPC_AI_IDLE + wander = FALSE + cmode_music = FALSE + is_voracious_npc = TRUE + voremode = TRUE + + +/mob/living/carbon/human/species/elfevil/npc/Initialize() + . = ..() + set_species(/datum/species/elf/wood) + addtimer(CALLBACK(src, PROC_REF(after_creation)), 1 SECONDS) + load_generic_bellies() + +/mob/living/carbon/human/species/elfevil/retaliate(mob/living/L) + var/newtarg = target + .=..() + if(target) + aggressive=1 + wander = TRUE + if(!is_silent && target != newtarg) + say(pick(GLOB.generic_vnpc_aggro)) + pointed(target) + + +/mob/living/carbon/human/species/elfevil/npc/load_mob_bellies() + ..() + + +/mob/living/carbon/human/species/elfevil/npc/after_creation() + ..() + job = "Bandit" + equipOutfit(new elfevil_outfit) + gender = pick(MALE, FEMALE) + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/hairf = pick(list(/datum/sprite_accessory/hair/head/himecut, + /datum/sprite_accessory/hair/head/countryponytailalt, + /datum/sprite_accessory/hair/head/stacy, + /datum/sprite_accessory/hair/head/kusanagi_alt)) + var/hairm = pick(list(/datum/sprite_accessory/hair/head/ponytailwitcher, + /datum/sprite_accessory/hair/head/dave, + /datum/sprite_accessory/hair/head/emo, + /datum/sprite_accessory/hair/head/sabitsuki, + /datum/sprite_accessory/hair/head/sabitsuki_ponytail)) + head.sellprice = 30 + + src.set_patron(/datum/patron/divine/dendor) + ADD_TRAIT(src, TRAIT_LEECHIMMUNE, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_LIGHT_STEP, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOMOOD, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOHUNGER, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_BREADY, TRAIT_GENERIC) + var/datum/bodypart_feature/hair/head/new_hair = new() + var/obj/item/organ/eyes/organ_eyes = getorgan(/obj/item/organ/eyes) + var/obj/item/organ/ears/organ_ears = getorgan(/obj/item/organ/ears) + + if(organ_eyes) + organ_eyes.eye_color = "#FF0000" + organ_eyes.accessory_colors = "#FF0000#FF0000" + var/skinchoose = rand(1,5) + var/skincolor = "#fff0e9" + var/skincolor2 = "fff0e9" + switch(skinchoose) //choosing the skincolor of the elf + if(1) + skincolor = "#fff0e9" + skincolor2 = "fff0e9" + if(2) + skincolor = "#edc6b3" + skincolor2 = "edc5b3" + if(3) + skincolor = "#ba9882" + skincolor2 = "ba9882" + if(4) + skincolor = "#9c6f52" + skincolor2 = "9c6f52" + if(5) + skincolor = "#5d4c41" + skincolor2 = "5d4c41" + + + skin_tone = skincolor2 + + if(organ_ears) + organ_ears.accessory_colors = skincolor + + if(gender == FEMALE) + new_hair.set_accessory_type(hairf, null, src) + var/obj/item/organ/breasts/breasts = src.getorganslot(ORGAN_SLOT_BREASTS) + if(!breasts) + breasts = new() + breasts.Insert(src, TRUE, FALSE) + breasts.accessory_type = /datum/sprite_accessory/breasts/pair + breasts.breast_size = rand(1,16) + breasts.accessory_colors = skincolor + + else + new_hair.set_accessory_type(hairm, null, src) + + var/obj/item/organ/butt/butt = src.getorganslot(ORGAN_SLOT_BUTT) + if(!butt) + butt = new() + butt.Insert(src, TRUE, FALSE) + butt.accessory_type = /datum/sprite_accessory/butt/pair + butt.organ_size = rand(0,5) + butt.accessory_colors = skincolor + + var/obj/item/organ/belly/belly = src.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = new() + belly.Insert(src, TRUE, FALSE) + belly.accessory_type = /datum/sprite_accessory/belly + belly.belly_size = 0 + belly.accessory_colors = skincolor + + head.add_bodypart_feature(new_hair) + + new_hair.accessory_colors = "#31302E" + new_hair.hair_color = "#31302E" + hair_color = "#31302E" + + dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + dna.species.handle_body(src) + if(gender == FEMALE) + real_name = pick(world.file2list("strings/rt/names/elf/elfwf.txt")) + else + real_name = pick(world.file2list("strings/rt/names/elf/elfwm.txt")) + update_hair() + update_body() + +/datum/outfit/job/roguetown/elfevil/npc/pre_equip(mob/living/carbon/human/H) //gives some default skills and equipment for player controlled elves + H.STASTR = 12 + var/chance_zjumper = 5 + var/chance_treeclimber = 30 + H.STASPD = 15 + if(prob(chance_zjumper)) + ADD_TRAIT(H, TRAIT_ZJUMP, TRAIT_GENERIC) + H.find_targets_above = TRUE + if(prob(chance_treeclimber)) + H.tree_climber = TRUE + H.find_targets_above = TRUE // so they can taunt + H.STACON = 13 + H.STAWIL = 12 + H.STAINT = 12 + H.adjust_skillrank(/datum/skill/combat/polearms, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/maces, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/axes, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/swords, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/shields, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/wrestling, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/swimming, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/climbing, 2, TRUE) + var/loadout = rand(1,4) + switch(loadout) + if(1) //duelist elf + armor = /obj/item/clothing/suit/roguetown/armor/leather + head = /obj/item/clothing/head/roguetown/duelhat + mask = /obj/item/clothing/mask/rogue/duelmask + cloak = /obj/item/clothing/cloak/half + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + shirt = /obj/item/clothing/suit/roguetown/shirt/undershirt/black + pants = /obj/item/clothing/under/roguetown/trou/leather + beltl = /obj/item/storage/belt/rogue/pouch/coins/poor + shoes = /obj/item/clothing/shoes/roguetown/boots + neck = /obj/item/clothing/neck/roguetown/gorget + gloves = /obj/item/clothing/gloves/roguetown/fingerless_leather + backl = /obj/item/storage/backpack/rogue/satchel + backr = /obj/item/rogueweapon/shield/buckler + belt = /obj/item/storage/belt/rogue/leather + H.adjust_skillrank_up_to(/datum/skill/combat/swords, SKILL_LEVEL_EXPERT, TRUE) + r_hand = /obj/item/rogueweapon/sword/rapier + if(2) //desert elf + shirt = /obj/item/clothing/suit/roguetown/armor/gambeson/heavy/raneshen + pants = /obj/item/clothing/under/roguetown/trou/leather/pontifex/raneshen + head = /obj/item/clothing/head/roguetown/roguehood/shalal/hijab + gloves = /obj/item/clothing/gloves/roguetown/angle + belt = /obj/item/storage/belt/rogue/leather + backl = /obj/item/storage/backpack/rogue/satchel + beltl = /obj/item/storage/belt/rogue/pouch/coins/poor + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + shoes = /obj/item/clothing/shoes/roguetown/boots + cloak = /obj/item/clothing/cloak/raincloak/furcloak/brown + r_hand = /obj/item/rogueweapon/sword/saber/iron + l_hand = /obj/item/rogueweapon/sword/saber/iron + if(3) //thief elf + armor = /obj/item/clothing/suit/roguetown/armor/leather + shirt = /obj/item/clothing/suit/roguetown/armor/gambeson + backl = /obj/item/storage/backpack/rogue/backpack + backr = /obj/item/gun/ballistic/revolver/grenadelauncher/bow + pants = /obj/item/clothing/under/roguetown/trou/leather + shoes = /obj/item/clothing/shoes/roguetown/boots + neck = /obj/item/storage/belt/rogue/pouch/coins/poor + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + gloves = /obj/item/clothing/gloves/roguetown/fingerless + belt = /obj/item/storage/belt/rogue/leather/knifebelt/iron + cloak = /obj/item/clothing/cloak/raincloak/mortus + beltl = /obj/item/quiver/Warrows + beltr = /obj/item/rogueweapon/mace/cudgel + r_hand = /obj/item/rogueweapon/huntingknife/idagger/steel + l_hand = /obj/item/rogueweapon/huntingknife/idagger/steel + if(4) //zinzoid wrestler nudist + H.STASTR = 18 + H.STACON = 15 + H.STASPD = 10 //slower, beefy motherfucker + H.STAINT = 4 //dumbass + H.adjust_skillrank(/datum/skill/combat/wrestling, 5, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 4, TRUE) + +/mob/living/carbon/human/species/elfevil/npc/death(gibbed, nocutscene) + if(vore_organs.len > 0) + for(var/obj/belly/B in vore_organs) + B.release_all_contents(TRUE) + . = ..() diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/goblinpevil.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/goblinpevil.dm new file mode 100644 index 00000000000..1bdea646a5d --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/goblinpevil.dm @@ -0,0 +1,358 @@ +GLOBAL_LIST_INIT(evilgoblin_aggro, world.file2list("strings/rt/evilgobinaggrolines.txt")) + +/mob/living/carbon/human/species/goblinevil + name = "goblin" + skin_tone = SKIN_COLOR_GROONN + hairstyle = "Bald" + facial_hairstyle = "Shaved" + var/goblinevil_outfit = /datum/outfit/job/roguetown/goblinevil/npc + var/is_silent = FALSE + + race = /datum/species/goblinp + gender = MALE + bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + ambushable = FALSE + + base_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, /datum/intent/unarmed/claw) + a_intent = INTENT_HELP + d_intent = INTENT_PARRY + possible_mmb_intents = list(INTENT_SPECIAL, INTENT_JUMP, INTENT_KICK, INTENT_BITE) + possible_rmb_intents = list(/datum/rmb_intent/feint, /datum/rmb_intent/aimed, /datum/rmb_intent/strong, /datum/rmb_intent/weak, /datum/rmb_intent/swift, /datum/rmb_intent/riposte) + +/mob/living/carbon/human/species/goblinevil/npc + faction = list("orcs", "station") + aggressive = 1 + rude = TRUE + mode = NPC_AI_IDLE + wander = FALSE + cmode_music = FALSE + is_voracious_npc = TRUE + voremode = TRUE + +/mob/living/carbon/human/species/goblinevil/retaliate(mob/living/L) + var/newtarg = target + .=..() + if(target) + aggressive=1 + wander = TRUE + if(!is_silent && target != newtarg) + say(pick(GLOB.evilgoblin_aggro)) + pointed(target) + +/mob/living/carbon/human/species/goblinevil/npc/Initialize() + . = ..() + set_species(/datum/species/goblinp) + addtimer(CALLBACK(src, PROC_REF(after_creation)), 1 SECONDS) + load_gob_bellies() + +/mob/living/carbon/human/species/goblinevil/npc/load_mob_bellies() + ..() + +/mob/living/carbon/human/species/goblinevil/npc/after_creation() + ..() + job = "Goblin" + equipOutfit(new goblinevil_outfit) + gender = pick(MALE, FEMALE) + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/hairf = pick(list(/datum/sprite_accessory/hair/head/lowbraid, + /datum/sprite_accessory/hair/head/countryponytailalt)) + var/hairm = pick(list(/datum/sprite_accessory/hair/head/ponytailwitcher, + /datum/sprite_accessory/hair/head/lowbraid)) + head.sellprice = 30 + + src.set_patron(/datum/patron/inhumen/graggar) + ADD_TRAIT(src, TRAIT_LEECHIMMUNE, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_LIGHT_STEP, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOMOOD, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOHUNGER, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_BREADY, TRAIT_GENERIC) + + var/datum/bodypart_feature/hair/head/new_hair = new() + var/obj/item/organ/eyes/organ_eyes = getorgan(/obj/item/organ/eyes) + var/obj/item/organ/ears/organ_ears = getorgan(/obj/item/organ/ears) + + if(organ_eyes) + organ_eyes.eye_color = "#FF0000" + organ_eyes.accessory_colors = "#FF0000#FF0000" + + skin_tone = "50715C" + + if(organ_ears) + organ_ears.accessory_colors = "#50715C" + + if(gender == FEMALE) + new_hair.set_accessory_type(hairf, null, src) + var/obj/item/organ/breasts/breasts = src.getorganslot(ORGAN_SLOT_BREASTS) + if(!breasts) + breasts = new() + breasts.Insert(src, TRUE, FALSE) + breasts.accessory_type = /datum/sprite_accessory/breasts/pair + breasts.breast_size = rand(1,16) + breasts.accessory_colors = "#50715C" + + else + new_hair.set_accessory_type(hairm, null, src) + + var/obj/item/organ/butt/butt = src.getorganslot(ORGAN_SLOT_BUTT) + if(!butt) + butt = new() + butt.Insert(src, TRUE, FALSE) + butt.accessory_type = /datum/sprite_accessory/butt/pair + butt.organ_size = rand(0,5) + butt.accessory_colors = "#50715C" + + var/obj/item/organ/belly/belly = src.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = new() + belly.Insert(src, TRUE, FALSE) + belly.accessory_type = /datum/sprite_accessory/belly + belly.belly_size = 0 + belly.accessory_colors = "#50715C" + + head.add_bodypart_feature(new_hair) + + new_hair.accessory_colors = "#31302E" + new_hair.hair_color = "#31302E" + hair_color = "#31302E" + + dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + dna.species.handle_body(src) + if(gender == FEMALE) + real_name = pick(world.file2list("strings/rt/names/other/halforcf.txt")) + else + real_name = pick(world.file2list("strings/rt/names/other/halforcm.txt")) + update_hair() + update_body() + +/datum/outfit/job/roguetown/goblinevil/npc/pre_equip(mob/living/carbon/human/H) //gives some default skills and equipment for player controlled orcs + H.STASTR = 12 + var/chance_zjumper = 5 + var/chance_treeclimber = 30 + H.STASPD = 14 + if(prob(chance_zjumper)) + ADD_TRAIT(H, TRAIT_ZJUMP, TRAIT_GENERIC) + H.find_targets_above = TRUE + if(prob(chance_treeclimber)) + H.tree_climber = TRUE + H.find_targets_above = TRUE // so they can taunt + H.STACON = 14 + H.STAWIL = 14 + H.STAINT = 4 + var/loadout = rand(1,5) + switch(loadout) + if(1) //tribal spear + r_hand = /obj/item/rogueweapon/spear/stone + armor = /obj/item/clothing/suit/roguetown/armor/leather/hide/goblin + if(2) //tribal axe + r_hand = /obj/item/rogueweapon/stoneaxe + armor = /obj/item/clothing/suit/roguetown/armor/leather/hide/goblin + if(3) //tribal club + r_hand = /obj/item/rogueweapon/mace/woodclub + armor = /obj/item/clothing/suit/roguetown/armor/leather/hide/goblin + if(prob(10)) + head = /obj/item/clothing/head/roguetown/helmet/leather/goblin + if(4) //lightly armored sword/flail/daggers + if(prob(50)) + r_hand = /obj/item/rogueweapon/sword/iron + else + r_hand = /obj/item/rogueweapon/mace/spiked + if(prob(30)) + l_hand = /obj/item/rogueweapon/shield/wood + if(prob(23)) + r_hand = /obj/item/rogueweapon/huntingknife/stoneknife + l_hand = /obj/item/rogueweapon/huntingknife/stoneknife + armor = /obj/item/clothing/suit/roguetown/armor/leather/goblin + if(prob(80)) + head = /obj/item/clothing/head/roguetown/helmet/leather/goblin + if(5) //heavy armored sword/flail/shields + if(prob(30)) + armor = /obj/item/clothing/suit/roguetown/armor/plate/cuirass/iron/goblin + else + armor = /obj/item/clothing/suit/roguetown/armor/leather/goblin + if(prob(80)) + head = /obj/item/clothing/head/roguetown/helmet/goblin + else + head = /obj/item/clothing/head/roguetown/helmet/leather/goblin + H.adjust_skillrank(/datum/skill/combat/polearms, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/maces, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/axes, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/swords, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/shields, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 3, TRUE) + H.adjust_skillrank(/datum/skill/combat/wrestling, 3, TRUE) // Trash mob + H.adjust_skillrank(/datum/skill/misc/swimming, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/climbing, 2, TRUE) + +//Credit to Syribirb for doing the entirety of the belly descriptions! +//EVIL BELLYCODE-------------------------------------------------------------- +/mob/living/proc/load_gob_bellies() + //Loading goblin bellies for goblin NPCs + var/obj/belly/M = new /obj/belly(src) + vore_selected = M + M.immutable = TRUE + M.can_taste = TRUE + M.name = vore_stomach_name ? vore_stomach_name : "maw" + M.desc = vore_stomach_flavor ? vore_stomach_flavor : "Finally the little beast gets its hands on you. Tired and numb, you can resist no longer as the greenskin yanks your armor down to bring you level with their lips. Jagged white teeth gleam at the edges of your vision, and you get one final glimpse of a dripping and pulsing throat before it overtakes you entirely.

Its tongue drags across your features, tasting you as claws dig into your sides. You can feel those jagged teeth finally scrape across your scalp and towards the back of your head. It holds you there for a sadistic minute or two. Shrill laughter rumbles against your scalp, leaving drool to ooze down your chest and hot breath to billow down your neck…" + M.digest_mode = vore_default_mode + M.mode_flags = vore_default_flags + M.item_digest_mode = vore_default_item_mode + M.contaminates = vore_default_contaminates + M.contamination_flavor = vore_default_contamination_flavor + M.contamination_color = vore_default_contamination_color + M.escapable = vore_escape_chance > 0 + M.escapechance = vore_escape_chance + M.escapechance_absorbed = vore_escape_chance_absorbed + M.digestchance = 0 + M.absorbchance = 0 + M.human_prey_swallow_time = swallowTime + M.nonhuman_prey_swallow_time = swallowTime + M.digest_brute = 0 + M.digest_burn = 0 + M.digest_mode = "Hold" + M.vore_verb = "swallow" + M.examine_messages = list( + "%pred has %prey's head stuck in their mouth!", + "Drool oozes down %prey's frame as they're crudely tasted with their struggling frame shoved ever deeper…") + M.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "The predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes harmlessly.", + "The predator's calm breathing and thumping heartbeat pulses around you.", + "The warm walls kneads harmlessly against you.", + "The liquids churn around you, though there doesn't seem to be much effect.", + "The sound of bodily movements drown out everything for a moment.", + "The predator's movements gently force you into a different position.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + M.escape_attempt_messages_prey = "You start to kick away from %pred's grasp!" + M.escape_messages_outside = "%prey manages to escape %pred's clutches!" + M.escape_messages_prey = "You managed to get away from %pred's grasp!" + M.escape_fail_messages_prey = "You managed to slip up, getting further trapped!" + M.autotransferable = 1 + M.autotransferlocation = "throat" + M.autotransferwait = 300 + M.autotransferchance = 100 + M.autotransfer_min_amount = 1 + M.autotransfer_whitelist = 53 + M.autotransfer_enabled = 1 + M.belly_fullscreen = "vbo_maw14" + M.belly_fullscreen_color = "#823232" + M.belly_fullscreen_color2 = "#823232" + + var/obj/belly/T = new /obj/belly(src) + T.immutable = TRUE + T.can_taste = TRUE + T.name = vore_stomach_name ? vore_stomach_name : "throat" + T.desc = vore_stomach_flavor ? vore_stomach_flavor : "You can hear the tiny thing outside struggling to keep you contained. Each noisome slurp drags their tongue further down your face, smearing you in spit and matting against your scalp. As the muscles of their throat catch your head, and eventually your neck.

GHlLRK. GLmp… glnrk… Strained, repetitive swallows work over your form as your head… and steadily the rest of you become nothing but a prominent BULGE on the gobbie's neck. Teeth scrape back across your skin, leaving dull puffy scratches. You're sunk into ever-deeper tunnels of tightened flesh as gravity steadily reverses on you.

The tightness of that throat leaves the smug beast's claws free to slide up your body, grabbing still your kicking thighs and legs just to use the new grip to cram you in deeper. You're half submerged in the overly tight tunnel of the short beast's esophagus, helpless but to feel it's tongue coil up your legs and taste the salt of your skin." + T.digest_mode = vore_default_mode + T.mode_flags = vore_default_flags + T.item_digest_mode = vore_default_item_mode + T.contaminates = vore_default_contaminates + T.contamination_flavor = vore_default_contamination_flavor + T.contamination_color = vore_default_contamination_color + T.escapable = vore_escape_chance > 0 + T.escapechance = 10 + T.escapechance_absorbed = vore_escape_chance_absorbed + T.digestchance = 0 + T.absorbchance = 0 + T.human_prey_swallow_time = swallowTime + T.nonhuman_prey_swallow_time = swallowTime + T.digest_brute = 0 + T.digest_burn = 0 + T.digest_mode = "Hold" + T.vore_verb = "swallow" + T.examine_messages = list( + "%pred has %prey's head stuck in their mouth!", + "Drool oozes down %prey's frame as they're crudely tasted with their struggling frame shoved ever deeper…") + T.emote_lists[DM_HOLD] = list( + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "The predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes harmlessly.", + "The predator's calm breathing and thumping heartbeat pulses around you.", + "The warm walls kneads harmlessly against you.", + "The liquids churn around you, though there doesn't seem to be much effect.", + "The sound of bodily movements drown out everything for a moment.", + "The predator's movements gently force you into a different position.") + T.emote_lists[DM_DIGEST] = list( + "The burning acids eat away at your form.", + "The muscular stomach flesh grinds harshly against you.", + "The caustic air stings your chest when you try to breathe.", + "The slimy guts squeeze inward to help the digestive juices soften you up.", + "The onslaught against your body doesn't seem to be letting up; you're food now.", + "The predator's body ripples and crushes against you as digestive enzymes pull you apart.", + "The juices pooling beneath you sizzle against your sore skin.", + "The churning walls slowly pulverize you into meaty nutrients.", + "The stomach glorps and gurgles as it tries to work you into slop.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + T.escape_attempt_messages_prey = "You start to climb up %pred's greedy throat!" + T.escape_messages_outside = "%prey manages to slide out from the now pissed off predator." + T.escape_messages_prey = "You managed to slide out from %pred's greedy throat" + T.escape_fail_messages_prey = "%pred stifles your escape attempt with another greedy swallow." + T.autotransferable = 1 + T.autotransferlocation = "stomach" + T.autotransferwait = 300 + T.autotransferchance = 100 + T.autotransfer_min_amount = 1 + T.autotransfer_whitelist = 53 + T.autotransfer_enabled = 1 + T.belly_fullscreen = "vboanim_belly1" + T.belly_fullscreen_color = "#823232" + T.belly_fullscreen_color2 = "#823232" + + var/obj/belly/B = new /obj/belly(src) + B.immutable = TRUE + B.can_taste = TRUE + B.name = vore_stomach_name ? vore_stomach_name : "stomach" + B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Finally, you're deposited in a stinking, fetid bog of a stomach. Your face is humiliatingly squeezed through a sphincter at the very end before being MASHED against its deepest pit. A slop of acids and the goblin's previous meals slosh as your face parts the goop… and then the rest of you is forced to curl to fill what little space you have.

In a smooth slurp, the rest of your body falls down their throat and into a rounded, wobbling bulge on the greenskin's midriff. Fabric RIPS on the outside as they struggle to even stand with you weighing them down. You can hear a few strained breaths, a hiccup- and then a ragged BELCH that causes the whole chamber to rumble around you.

BwhhhhHHHRRRP.

It tightens and robs you of your air as you're left to contemplate how you even FIT in here. It's vice-tight and sweltering, and the disgusting pit forces you to twist, turn, and roll within the creechur as your outline is perfectly visible from the outside. You can even feel the thing wetly drool atop the rounded orb. Its claws dig into the underside of your heft, weighing just how much MEAL it took in.

Glrp. Glllrgl." + B.digest_mode = vore_default_mode + B.mode_flags = vore_default_flags + B.item_digest_mode = vore_default_item_mode + B.contaminates = vore_default_contaminates + B.contamination_flavor = vore_default_contamination_flavor + B.contamination_color = vore_default_contamination_color + B.escapable = vore_escape_chance > 0 + B.escapechance_absorbed = vore_escape_chance_absorbed + B.digestchance = vore_digest_chance + B.absorbchance = vore_absorb_chance + B.human_prey_swallow_time = swallowTime + B.nonhuman_prey_swallow_time = swallowTime + B.vore_verb = "swallow" + B.digest_brute = 0.5 + B.digest_burn = 0.5 + B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "The predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes harmlessly.", + "The predator's calm breathing and thumping heartbeat pulses around you.", + "The warm walls kneads harmlessly against you.", + "The liquids churn around you, though there doesn't seem to be much effect.", + "The sound of bodily movements drown out everything for a moment.", + "The predator's movements gently force you into a different position.") + B.emote_lists[DM_DIGEST] = list( + "The burning acids eat away at your form.", + "The muscular stomach flesh grinds harshly against you.", + "The caustic air stings your chest when you try to breathe.", + "The slimy guts squeeze inward to help the digestive juices soften you up.", + "The onslaught against your body doesn't seem to be letting up; you're food now.", + "The predator's body ripples and crushes against you as digestive enzymes pull you apart.", + "The juices pooling beneath you sizzle against your sore skin.", + "The churning walls slowly pulverize you into meaty nutrients.", + "The stomach glorps and gurgles as it tries to work you into slop.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + B.escape_attempt_messages_prey = "You begin to attack %pred's taught stomach effectively!" + B.escape_messages_outside = "%pred lurches over, horking up %prey. Ugh..." + B.escape_messages_prey = "A sudden reflex, and you manage to make %pred cough you up. Slimy, but alive!" + B.escape_fail_messages_prey = "%pred's stomach clenches down hard, preventing your escape." + B.escapechance = 5 + B.belly_fullscreen = "vbo_belly5" + B.belly_fullscreen_color = "#823232" + B.belly_fullscreen_color2 = "#823232" + +/mob/living/carbon/human/species/goblinevil/npc/death(gibbed, nocutscene) + if(vore_organs.len > 0) + for(var/obj/belly/B in vore_organs) + B.release_all_contents(TRUE) + . = ..() diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/lamiaevil.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/lamiaevil.dm new file mode 100644 index 00000000000..bbbd2716403 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/lamiaevil.dm @@ -0,0 +1,428 @@ +GLOBAL_LIST_INIT(lamia_aggro, world.file2list("strings/rt/evillamiaaggrolines.txt")) + +/mob/living/carbon/human/species/lamiaevil + name = "lamia" + skin_tone = SKIN_COLOR_GROONN + hairstyle = "Bald" + facial_hairstyle = "Shaved" + var/lamiaevil_outfit = /datum/outfit/job/roguetown/lamiaevil/npc + var/is_silent = FALSE + + race = /datum/species/demihuman + gender = MALE + bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + ambushable = FALSE + + base_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, /datum/intent/unarmed/claw) + a_intent = INTENT_HELP + d_intent = INTENT_PARRY + possible_mmb_intents = list(INTENT_SPECIAL, INTENT_JUMP, INTENT_KICK, INTENT_BITE) + possible_rmb_intents = list(/datum/rmb_intent/feint, /datum/rmb_intent/aimed, /datum/rmb_intent/strong, /datum/rmb_intent/weak, /datum/rmb_intent/swift, /datum/rmb_intent/riposte) + +/mob/living/carbon/human/species/lamiaevil/npc + faction = list("vbandit", "station") + aggressive = 1 + rude = TRUE + mode = NPC_AI_IDLE + wander = FALSE + cmode_music = FALSE + is_voracious_npc = TRUE + voremode = TRUE + +/mob/living/carbon/human/species/lamiaevil/npc/Initialize() + . = ..() + set_species(/datum/species/demihuman) + addtimer(CALLBACK(src, PROC_REF(after_creation)), 1 SECONDS) + load_lamia_bellies() + +/mob/living/carbon/human/species/lamiaevil/retaliate(mob/living/L) + var/newtarg = target + .=..() + if(target) + aggressive=1 + wander = TRUE + if(!is_silent && target != newtarg) + say(pick(GLOB.lamia_aggro)) + pointed(target) + + +/mob/living/carbon/human/species/lamiaevil/npc/load_mob_bellies() + ..() + + +/mob/living/carbon/human/species/lamiaevil/npc/after_creation() + ..() + job = "Bandit" + equipOutfit(new lamiaevil_outfit) + gender = pick(MALE, FEMALE) + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/hairf = pick(list(/datum/sprite_accessory/hair/head/himecut, + /datum/sprite_accessory/hair/head/countryponytailalt, + /datum/sprite_accessory/hair/head/stacy, + /datum/sprite_accessory/hair/head/kusanagi_alt)) + var/hairm = pick(list(/datum/sprite_accessory/hair/head/ponytailwitcher, + /datum/sprite_accessory/hair/head/dave, + /datum/sprite_accessory/hair/head/emo, + /datum/sprite_accessory/hair/head/sabitsuki, + /datum/sprite_accessory/hair/head/sabitsuki_ponytail)) + head.sellprice = 30 + + src.set_patron(/datum/patron/divine/dendor) + ADD_TRAIT(src, TRAIT_LEECHIMMUNE, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_LIGHT_STEP, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOMOOD, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOHUNGER, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_BREADY, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NATURAL_ARMOR, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_CHUNKYFINGERS, TRAIT_GENERIC) + var/datum/bodypart_feature/hair/head/new_hair = new() + var/obj/item/organ/eyes/organ_eyes = getorgan(/obj/item/organ/eyes) + var/obj/item/organ/ears/organ_ears = getorgan(/obj/item/organ/ears) + + if(organ_eyes) + organ_eyes.eye_color = "#FF0000" + organ_eyes.accessory_colors = "#FF0000#FF0000" + var/skinchoose = rand(1,5) + var/skincolor = "#fff0e9" + var/skincolor2 = "fff0e9" + switch(skinchoose) //choosing the skincolor of the snek + if(1) + skincolor = "#fff0e9" + skincolor2 = "fff0e9" + if(2) + skincolor = "#edc6b3" + skincolor2 = "edc5b3" + if(3) + skincolor = "#ba9882" + skincolor2 = "ba9882" + if(4) + skincolor = "#9c6f52" + skincolor2 = "9c6f52" + if(5) + skincolor = "#5d4c41" + skincolor2 = "5d4c41" + var/tailchoose = rand(1,5) + var/tailcolor = "#520f0f" + switch(tailchoose) //choosing the skincolor of the snek + if(1) + tailcolor = "#520f0f" + if(2) + tailcolor = "#1e5704" + if(3) + tailcolor = "#161c69" + if(4) + tailcolor = "#dfb988" + if(5) + tailcolor = "#9e6905" + Taurize(/obj/item/bodypart/taur/lamia, tailcolor) + + skin_tone = skincolor2 + + if(organ_ears) + organ_ears.accessory_colors = skincolor + + if(gender == FEMALE) + new_hair.set_accessory_type(hairf, null, src) + var/obj/item/organ/breasts/breasts = src.getorganslot(ORGAN_SLOT_BREASTS) + if(!breasts) + breasts = new() + breasts.Insert(src, TRUE, FALSE) + breasts.accessory_type = /datum/sprite_accessory/breasts/pair + breasts.breast_size = rand(1,16) + breasts.accessory_colors = skincolor + + else + new_hair.set_accessory_type(hairm, null, src) + + var/obj/item/organ/butt/butt = src.getorganslot(ORGAN_SLOT_BUTT) + if(!butt) + butt = new() + butt.Insert(src, TRUE, FALSE) + butt.accessory_type = /datum/sprite_accessory/butt/pair + butt.organ_size = rand(0,5) + butt.accessory_colors = skincolor + + var/obj/item/organ/belly/belly = src.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = new() + belly.Insert(src, TRUE, FALSE) + belly.accessory_type = /datum/sprite_accessory/belly + belly.belly_size = 0 + belly.accessory_colors = skincolor + + head.add_bodypart_feature(new_hair) + + new_hair.accessory_colors = "#31302E" + new_hair.hair_color = "#31302E" + hair_color = "#31302E" + + dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + dna.species.handle_body(src) + if(gender == FEMALE) + real_name = pick(world.file2list("strings/rt/names/elf/elfwf.txt")) + else + real_name = pick(world.file2list("strings/rt/names/elf/elfwm.txt")) + update_hair() + update_body() + +/datum/outfit/job/roguetown/lamiaevil/npc/pre_equip(mob/living/carbon/human/H) //tribal ass sneks in your area + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + if(prob(50)) + wrists = /obj/item/clothing/wrists/roguetown/bracers/copper + if(prob(50)) + head = /obj/item/clothing/head/roguetown/helmet/leather + neck = /obj/item/clothing/neck/roguetown/gorget/copper + if(prob(50)) + neck = /obj/item/clothing/neck/roguetown/leather + H.skin_armor = new /obj/item/clothing/suit/roguetown/armor/skin_armor/natural_armor/dense(H) + H.STASTR = 12 + H.STASPD = 16 + H.STACON = 14 + H.STAWIL = 14 + H.STAPER = 10 + H.STAINT = 3 //stupid snakes + H.adjust_skillrank(/datum/skill/combat/unarmed, 4, TRUE) + H.adjust_skillrank(/datum/skill/combat/wrestling, 4, TRUE) + H.adjust_skillrank(/datum/skill/misc/athletics, 4, TRUE) + H.adjust_skillrank(/datum/skill/misc/swimming, 4, TRUE) + + + +//Credit to Syribirb for doing the entirety of the belly descriptions! +//EVIL BELLYCODE-------------------------------------------------------------- +/mob/living/proc/load_lamia_bellies() + //Loading genderless catchall bellies + var/obj/belly/M = new /obj/belly(src) + vore_selected = M + M.immutable = TRUE + M.can_taste = TRUE + M.name = vore_stomach_name ? vore_stomach_name : "maw" + M.desc = vore_stomach_flavor ? vore_stomach_flavor : "Smooth scales cling to your legs. Before you know it, you’re dragged into waiting, warm coils. The girth of %pred’s tail climbs up your body, and they look down at you with a pleased gleam in their eye. Hands gently hug you within those waiting binds, and you’re left to merely struggle as they lazily use their lower body to overpower you

Hair drapes across your chest, and their grin only gets more pleased as they rest their head there for just a few moments.Glrg…rrgl…There’s a thick groan from their midriff, they’re hungry- but first things first they need to hear your heartbeat… your fear. You can see their soft lips part in a too-white, fanged grin from below you.

You can hardly move, your arms squirm against too-smooth scales as the constriction is nearly crushing. Still though, the rest of their body is afforded that lazy attitude. You can feel their tailtip

Warm, gooey tongue oozes up your chest, leaving a slimy trail of spit until they pass your jaw an push up your cheek. “Delicioussss… morsssel.” The naga giggles, their lashes fluttering as they pepper a kiss along the opposite side of your face. Up, up. They’re teasing you.

Their lips rest on your ear, gently nibbling at the lobe as their warm breath washes over your head. A playful little bite before you hear their wet maw expand… ‘schlp.’ Their jaw unnaturally unhinges, and you’re overtaken in their lips as the flesh of it is the last thing you see. Fangs scrape across your scalp as drool oozes across your face and down your neck.

Schlrp." + M.digest_mode = vore_default_mode + M.mode_flags = vore_default_flags + M.item_digest_mode = vore_default_item_mode + M.contaminates = vore_default_contaminates + M.contamination_flavor = vore_default_contamination_flavor + M.contamination_color = vore_default_contamination_color + M.escapable = vore_escape_chance > 0 + M.escapechance_absorbed = vore_escape_chance_absorbed + M.digestchance = 0 + M.absorbchance = 0 + M.human_prey_swallow_time = swallowTime + M.nonhuman_prey_swallow_time = swallowTime + M.digest_brute = 0 + M.digest_burn = 0 + M.digest_mode = "Hold" + M.vore_verb = "swallow" + M.examine_messages = list( + "%pred is currently pushing their mouth over %prey’s face! They’re wrapped tightly in thick coils as the snake’s lithe body smothers them. The naga’s jaw is unhinging as fangs scrape across their victim’s head… it seems they’re meant to be food soon enough.") + M.emote_lists[DM_HOLD] = list( + "Coils swim around your every inch, catching your arms every time they come loose, clenching around the soft parts of your body as if feeling and appraising you.", + "A curious tailtip works across your thighs, gently teasing across sensitive skin as you’re shoved into %pred’s waiting mouth.", + "Drool oozes down your chest as the jaw surrounding your head unhinges all the more. Fangs slide across your skin as you’re shoved deeper by the effort of %pred’s lower body.", + "Hands dance across your skin, gently feeling your musculature and soft areas both as the naga takes in the delectable prey they managed to capture. Their upper body embraces you lazily, free to let their tail do all the work.") + M.struggle_messages_inside = list( + "Thick coils keep you pinned as you writhe to get any solace from the constriction. Their tailtip darts across your thigh, teasingly re-coiling your leg as their tail swims about your frame.", + "You thrash against %pred, but they hardly put any effort into using their upper body to keep you restrained. The coils do all the work as they simply reach a delicate hand down your midriff and giggle around your head.", + "You stretch in those coils in an attempt to slip their grip, but all that you manage to do is shove your face deep into that waiting maw. %pred’s tongue smothers your entire face as you’re washed in their warm breath.", + "You push out against the winding tail that holds you still, but %pred just bites on your head in response. Twin fangs scrape against the back of your head, and the pulsing of the throat ahead of you is a grim foreshadowing of your fate…", + "A thick GLRNK sounds as their throat muscles try to catch you, but your tossing makes it difficult. Pushing out against the smooth scales around you, you claw for any way to resist the lithe creature atop you.", + "As you recklessly thrash against %pred, their drool oozes down your chest messily. You’re making swallowing hard, so their tongue simply sets its molten girth to tasting you until you calm within the squeezing of their coils.", + "You’re able to push their head off of you! Their delicate features flutter lashes back at you curiously, drool oozing down their chin. Their face is faintly flushed, and when they open their mouth again, you can see the pulse of a throat before they try to plunge you straight back in. Schlrp…" + ) + M.struggle_messages_outside = list( + "%Prey thrashes against %pred’s tight coils! There’s a muffled squeal from inside the naga’s mouth as their head gets slowly shoved deeper.", + "%Prey writhes against the thick snake-like lower body holding them tight. Despite their thrashings, %pred seems keen on holding them tight inside their mouth.", + "%Pred rests gingerly atop %prey as they rail and thrash against the thick, warm coils surrounding them. They hardly put any upper-body effort into keeping them restrained." + ) + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + M.escape_attempt_messages_prey = "You start to kick away from %pred's grasp!" + M.escape_messages_outside = "%prey manages to escape %pred's clutches!" + M.escape_messages_prey = "You managed to get away from %pred's grasp!" + M.escape_fail_messages_prey = "You managed to slip up, getting further trapped!" + M.escapechance = 25 + M.autotransferable = 1 + M.autotransferlocation = "throat" + M.autotransferwait = 300 + M.autotransferchance = 100 + M.autotransfer_min_amount = 1 + M.autotransfer_whitelist = 53 + M.autotransfer_enabled = 1 + M.belly_fullscreen = "vbo_maw14" + M.belly_fullscreen_color = "#823232" + M.belly_fullscreen_color2 = "#823232" + + var/obj/belly/T = new /obj/belly(src) + T.immutable = TRUE + T.can_taste = TRUE + T.name = vore_stomach_name ? vore_stomach_name : "throat" + T.desc = vore_stomach_flavor ? vore_stomach_flavor : "TSCHLr-Ghk… glrk…

Your frame travels down the naga’s throat in a thick bulge. Your body noisily works its way down their surprisingly accommodating throat. Drool oozes into your every inch as slowly but steadily their hands glide down your body. A sighed breath washes across your frame, warm and humid as they’re finally content they have you restrained. As you’re steadily slid deeper your world becomes nothing but noisy, grinding muscles ushering you forward and wet walls smothering your face.

You can still feel their coils all across your lower body, their back arching as they lift you against gravity. Their tailtip THAPS your behind as they giggle, still more than happy to play with you as they simply slide you down. Every writhe and struggle you make like this, suspended, is perfectly set to be a feast for their eyes. Your body bounces with each swallow deeper.

Your face is crammed against a tight sphincter leading to their stomach, your legs still vainly attempting to kick outside. It’s hard with the exertion of battle, every sore spot you have is being lovingly caressed by the naga’s insides as your muscles scream for relaxation…" + T.digest_mode = vore_default_mode + T.mode_flags = vore_default_flags + T.item_digest_mode = vore_default_item_mode + T.contaminates = vore_default_contaminates + T.contamination_flavor = vore_default_contamination_flavor + T.contamination_color = vore_default_contamination_color + T.escapable = vore_escape_chance > 0 + T.escapechance_absorbed = vore_escape_chance_absorbed + T.digestchance = 0 + T.absorbchance = 0 + T.human_prey_swallow_time = swallowTime + T.nonhuman_prey_swallow_time = swallowTime + T.digest_brute = 0 + T.digest_burn = 0 + T.digest_mode = "Hold" + T.vore_verb = "swallow" + T.examine_messages = list( + "%pred has %prey halfway shoved down their throat! Their lower body kicks and writhes as their back arches, trying to break free of the tight coils! A thick bulge is visible on the naga’s neck, clearly showing their struggling outline..") + T.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace + "A thick pulse of muscle travels over your body, pulling you deeper towards the naga’s stomach.", + "Wet drool oozes into your every inch, you can feel the snake’s tongue coil against you just as much as its tail. It tries its best to drag you in too.", + "A hitched sigh oozes up around your lower body, their breath hot against your hips as you slide deeper.", + "The naga locks their teeth around your hips to suckle across your frame, tasting you as you slide down.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + T.struggle_messages_inside = list( + "You push against the noisily swallowing muscles of their throat, earning a GLRT from the hardworking walls.", + "The bulge you make in %pred’s throat swells as your body writhes, but the most you can do is inadvertently smother your face in their internal slime.", + "You kick and thrash against %pred’s coils on your lower body! They tighten in response, gleefully squeezing your hips to get you under control.", + "You arch your back and push your legs against the tight coils outside, only to have %pred’s claws firmly SMACK and grip your behind. They use it like a handhold to try to shove you deeper.", + "Your hips swing against %pred’s jaws, only to have their tongue slide around them, coiling to tug you deeper.", + "Your hips push and jump against the tightening grip across your lower body, only to have their tailtip disarmingly sliide between your legs. It grips your thighs once again, preceding a new tightening of their coils." + ) + T.struggle_messages_outside = list( + "%prey pushes against the tight coils as they’re flipped upside-down and shoved into %pred’s throat!", + "The wriggling bulge that is %prey pushes out from the naga’s throat, you can see their outline shift within.", + "%prey’s legs kick against the coils holding them aloft! You hear another messy, slobbery swallow from the naga below as they try to contain them." + ) + T.autotransferable = 1 + T.autotransferlocation = "stomach" + T.autotransferwait = 300 + T.autotransferchance = 100 + T.autotransfer_min_amount = 1 + T.autotransfer_whitelist = 53 + T.autotransfer_enabled = 1 + T.escape_attempt_messages_prey = "You start to climb up %pred's greedy throat!" + T.escape_messages_outside = "%prey manages to slide out from the now pissed off predator." + T.escape_messages_prey = "You managed to slide out from %pred's greedy throat" + T.escape_fail_messages_prey = "%pred stifles your escape attempt with another greedy swallow." + T.escapechance = 10 + T.belly_fullscreen = "vboanim_belly1" + T.belly_fullscreen_color = "#823232" + T.belly_fullscreen_color2 = "#823232" + + var/obj/belly/B = new /obj/belly(src) + B.immutable = TRUE + B.can_taste = TRUE + B.name = vore_stomach_name ? vore_stomach_name : "stomach" + B.desc = vore_stomach_flavor ? vore_stomach_flavor : "You’re finally dropped from %pred’s coils, only for their mouth to snap up your hips. Its warmth overtakes them, and soon enough the rest of your body is sliding down their squeezing throat with just the help of gravity.

The thick bulge you’ve created begins to disappear past their collarbone and bloat their midriff as you’re deposited inside a clinging, tight stomach. The air is tainted with the smell of gall and the acrid waftings from some grinding, glorping chamber below.

Your face is crammed into the lower half of that chamber, immersed in a thick, warm, viscous solution. It doesn’t tingle or even burn, it simply soaks your every inch… you feel a SMACK against your frame from the outside as the naga takes in your form with a kind of pleasure.

The whole chamber squeezes you tight, bubbling the excess air up %pred’s throat in a liquidy bwhhHHRRP!!!. You’re left to simply stew as the every winding motion of the pred outside causes the bulge you make to wobble to and fro atop their hips. Your frame is forced to curl to accommodate the new tightness, and eventually you can finally right yourself as you’re prepared for the looong gut inside their tail…" + B.digest_mode = vore_default_mode + B.mode_flags = vore_default_flags + B.item_digest_mode = vore_default_item_mode + B.contaminates = vore_default_contaminates + B.contamination_flavor = vore_default_contamination_flavor + B.contamination_color = vore_default_contamination_color + B.escapable = vore_escape_chance > 0 + B.escapechance_absorbed = vore_escape_chance_absorbed + B.digestchance = vore_digest_chance + B.absorbchance = vore_absorb_chance + B.human_prey_swallow_time = swallowTime + B.nonhuman_prey_swallow_time = swallowTime + B.vore_verb = "swallow" + B.examine_messages = "%pred has a grotesquely bloated midriff! It glorps and churns over some poor unfortunate, their outline quite clear beneath the half-snake’s skin." + B.digest_brute = 0 + B.digest_burn = 0 + B.autotransferable = 1 + B.autotransferlocation = "tail" + B.autotransferwait = 300 + B.autotransferchance = 100 + B.autotransfer_min_amount = 1 + B.autotransfer_whitelist = 53 + B.autotransfer_enabled = 1 + B.escape_attempt_messages_prey = "You begin to attack %pred's taught stomach effectively!" + B.escape_messages_outside = "%pred lurches over, horking up %prey. Ugh..." + B.escape_messages_prey = "A sudden reflex, and you manage to make %pred cough you up. Slimy, but alive!" + B.escape_fail_messages_prey = "%pred's stomach clenches down hard, preventing your escape." + B.escapechance = 5 + B.emote_lists[DM_HOLD] = list( + "The guts around you steadily pulse, washing new, bubbling fluids across your entire body.", + "A clench pushes more of that slop up to your neck, making sure you’re properly softened and lubricated for the winding guts below.", + "A liquid gurgle emanates from a chamber beneath you. That looong tailgut awaits, preparing itself to break you down.", + "%pred simply goes about their day outside, each step sending a ripple through the thick, bloated gut that you occupy.", + "You can hear %pred's heartbeat faintly through the walls, as well as their breath. There's a little delicate hitch in their breathing as a clench rolls through their middle.", + "A hand passes over the bulge you make in %pred’s midriff from the outside, giving you a grope from beneath.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + B.struggle_messages_inside = list( + "You kick against the tightening, wringing walls inside %pred! A liquid glrt and a clench of those muscles bring you right back into line.", + "You let out muffled squeals as you try to break free of the guts that surround you! They cling tightly, sticking to your face and drowning you in thick, viscous goo.", + "You arch your back, pushing out your arms to try to resist the slow churning of %pred’s midriff, but you’re just smothering yourself in their walls.", + "As you thrash inside that gut, you make it slosh atop %pred’s hips. You can feel a new vibration ring through the whole chamber as they let out a pleased sigh.", + "You try to resist the slow churn of those muscles, pushing out against them, but you feel a hand on the outside cram itself against your outline to still you. The whole chamber clenches, and another belch bubbles up the Naga’s throat…" + ) + B.struggle_messages_outside = list( + "%pred’s midriff wobbles with a shifting prey, their outline pushing a hand out of the smooth skin of their gut.", + "%pred stifles a belch as their fat stomach jumps with motion from within. There’s a faint squeal from beneath their skin.", + "%pred’s gut lets out a worrying GLRT as it clenches over some poor unfortunate. You can see their outline struggling to break free." + ) + B.belly_fullscreen = "vbo_belly5" + B.belly_fullscreen_color = "#823232" + B.belly_fullscreen_color2 = "#823232" + + var/obj/belly/TL = new /obj/belly(src) + TL.immutable = TRUE + TL.can_taste = TRUE + TL.name = vore_stomach_name ? vore_stomach_name : "tail" + TL.desc = vore_stomach_flavor ? vore_stomach_flavor : "That gut finally begins to wobble side to side as you feel another sphincter open beneath you. It eventually catches your legs, allowing them space to straighten out. Even if you resist now, you’d only be shoving yourself through the slick passage. The muscles tighten, catch and pull. You find yourself sinking deeper into %pred’s guts than you thought possible as their midriff finally shrinks away, transferring the bulge of your frame into their long, winding tail.

Glrp… glrrglrg…slrsh.

It’s devilishly tight across your entire body, and you’re immediately coated in a thicker, tingling slime as your pre-lubed frame obediently sliiiides past %pred’s hip-bones. They let out a pleased sigh as your weight passes their organs, bullying them out of the way. A shudder runs through their hips, a slow rolling and bucking helping your passage until you’re finally completely immersed in their tail.

It’s a slow process as a slimy grool of digestive fluids and previous meals smeared across the seemingly endless walls is wrung into your body with every slow, deliberate inch you’re passed deeper. The walls push in tightly against you. Up and down are no longer a constant as your body is straightened out. Whenever you’re face down, you feel the ground drag beneath you with the snake’s every motion, smothering your face against the walls." + TL.digest_mode = vore_default_mode + TL.mode_flags = vore_default_flags + TL.item_digest_mode = vore_default_item_mode + TL.contaminates = vore_default_contaminates + TL.contamination_flavor = vore_default_contamination_flavor + TL.contamination_color = vore_default_contamination_color + TL.escapable = vore_escape_chance > 0 + TL.escapechance_absorbed = vore_escape_chance_absorbed + TL.digestchance = vore_digest_chance + TL.absorbchance = vore_absorb_chance + TL.human_prey_swallow_time = swallowTime + TL.nonhuman_prey_swallow_time = swallowTime + TL.vore_verb = "swallow" + TL.examine_messages = "There’s a thick, still wriggling bulge in %pred’s tail. They’ve clearly had a meal recently. It wetly glrts as it works the poor unfortunate over." + TL.digest_brute = 3 + TL.digest_burn = 3 + TL.escape_attempt_messages_prey = "You begin to attack %pred's taught stomach effectively!" + TL.escape_messages_outside = "%pred lurches over, horking up %prey. Ugh..." + TL.escape_messages_prey = "A sudden reflex, and you manage to make %pred cough you up. Slimy, but alive!" + TL.escape_fail_messages_prey = "%pred's stomach clenches down hard, preventing your escape." + TL.escapechance = 5 + TL.emote_lists[DM_DIGEST] = list( + "The churning walls that surround you clench tightly over your body, washing you in tingling fluids.", + "A bubble passes through the winding guts with a glrp, giving you a fresh breath of acrid digestion.", + "The snake slithers outside, dragging your body against the ground. You feel stretched by the tightly clinging muscles as they strain to keep you in place.", + "You feel %pred sit atop you from outside, the thick bulge compressed by their weight. It just helps smear you against their internal walls.", + "A sudden sliding of that tail causes you to slosh. You can hear those muscles glrrrgl as they try to contain the motion.", + "You hear some liquid slop shift from somewhere deeper in the winding tunnel that surrounds you. slrsh…") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + TL.struggle_messages_inside = list( + "You push out against the winding guts surrounding you, but your arms slip against the built-up slop atop the villi that hold you tight.", + "You arch your back and try to wiggle within %pred, but the tight walls of that tail smother your face as you smear yourself against them.", + "You thrash inside %pred, and the muscles of their tail strain to contain you. You can hear their vibrating, groaning shifting as they barely give way.", + "A tight pulse wrings your body as you try to resist the motions of that tail. It lets out a wet gurgle as yet more fluids drown over you.", + "You try to rock the tail outside to throw off %pred’s balance, but you instead just make a liquid slosh as you’re washed in the acrid gutslime coating you.", + "You struggle to throw off the tight muscles pushing you deeper, only managing to induce an upset, liquid gurgle that passes down the length of %pred’s tail.", + "Your body slips against the vice tight internal walls while you attempt to resist their motion, but they make a firm clench across your body that makes it hard to move.", + "The tail surrounding you tosses you against each wall with every slither. It’s surprising that the naga can even move normally with you inside, but their agility feels largely unaffected." + ) + TL.struggle_messages_outside = list( + "One of the bulges inside %pred’s long tail pushes out, you swear you can see a face outlined beneath the groaning, gurgling scales.", + "You hear a frustrated grunt muffled by %pred’s long tail. Someone is pushing out against the walls from inside, causing all manner of unholy noises to groan out from within.", + "%pred’s tail bulges with the resisting outline of someone within, before it visibly clenches across their frame. You can see it, straightened out and prone, slid across the ground with every slither." + ) + TL.belly_fullscreen = "vboanim_snakebelly1" + TL.belly_fullscreen_color = "#823232" + TL.belly_fullscreen_color2 = "#823232" + +/mob/living/carbon/human/species/lamiaevil/npc/death(gibbed, nocutscene) + if(vore_organs.len > 0) + for(var/obj/belly/B in vore_organs) + B.release_all_contents(TRUE) + . = ..() diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/tieflingevil.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/tieflingevil.dm new file mode 100644 index 00000000000..2ffc9efe2a9 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/tieflingevil.dm @@ -0,0 +1,256 @@ +GLOBAL_LIST_INIT(generic_vnpc_aggro, world.file2list("strings/rt/vnpcaggrolines.txt")) + +/mob/living/carbon/human/species/tiberianevil + name = "tiefling" + skin_tone = SKIN_COLOR_GROONN + hairstyle = "Bald" + facial_hairstyle = "Shaved" + var/tiberianevil_outfit = /datum/outfit/job/roguetown/tiberianevil/npc + var/is_silent = FALSE + + race = /datum/species/tieberian + gender = MALE + bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm, + /obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg) + ambushable = FALSE + + base_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, /datum/intent/unarmed/claw) + a_intent = INTENT_HELP + d_intent = INTENT_PARRY + possible_mmb_intents = list(INTENT_SPECIAL, INTENT_JUMP, INTENT_KICK, INTENT_BITE) + possible_rmb_intents = list(/datum/rmb_intent/feint, /datum/rmb_intent/aimed, /datum/rmb_intent/strong, /datum/rmb_intent/weak, /datum/rmb_intent/swift, /datum/rmb_intent/riposte) + +/mob/living/carbon/human/species/tiberianevil/npc + faction = list("tiberianbandit", "station") + aggressive = 1 + rude = TRUE + mode = NPC_AI_IDLE + wander = FALSE + cmode_music = FALSE + is_voracious_npc = TRUE + voremode = TRUE + + + +/mob/living/carbon/human/species/tiberianevil/npc/Initialize() + . = ..() + set_species(/datum/species/tieberian) + addtimer(CALLBACK(src, PROC_REF(after_creation)), 1 SECONDS) + load_generic_bellies() + +/mob/living/carbon/human/species/tiberianevil/retaliate(mob/living/L) + var/newtarg = target + .=..() + if(target) + aggressive=1 + wander = TRUE + if(!is_silent && target != newtarg) + say(pick(GLOB.generic_vnpc_aggro)) + pointed(target) + +/mob/living/carbon/human/species/tiberianevil/npc/load_mob_bellies() + ..() + + +/mob/living/carbon/human/species/tiberianevil/npc/after_creation() + ..() + job = "Bandit" + equipOutfit(new tiberianevil_outfit) + gender = pick(MALE, FEMALE) + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/hairf = pick(list(/datum/sprite_accessory/hair/head/himecut, + /datum/sprite_accessory/hair/head/countryponytailalt, + /datum/sprite_accessory/hair/head/stacy, + /datum/sprite_accessory/hair/head/kusanagi_alt)) + var/hairm = pick(list(/datum/sprite_accessory/hair/head/ponytailwitcher, + /datum/sprite_accessory/hair/head/dave, + /datum/sprite_accessory/hair/head/emo, + /datum/sprite_accessory/hair/head/sabitsuki, + /datum/sprite_accessory/hair/head/sabitsuki_ponytail)) + head.sellprice = 30 + + src.set_patron(/datum/patron/divine/dendor) + ADD_TRAIT(src, TRAIT_LEECHIMMUNE, INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_LIGHT_STEP, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOMOOD, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_NOHUNGER, TRAIT_GENERIC) + ADD_TRAIT(src, TRAIT_BREADY, TRAIT_GENERIC) + var/datum/bodypart_feature/hair/head/new_hair = new() + var/obj/item/organ/eyes/organ_eyes = getorgan(/obj/item/organ/eyes) + var/obj/item/organ/ears/organ_ears = getorgan(/obj/item/organ/ears) + + if(organ_eyes) + organ_eyes.eye_color = "#FF0000" + organ_eyes.accessory_colors = "#FF0000#FF0000" + var/skinchoose = rand(1,5) + var/skincolor = "#549ab6" + var/skincolor2 = "549ab6" + switch(skinchoose) //choosing the skincolor of the tiefling + if(1) + skincolor = "#C62D4C" + skincolor2 = "C62D4C" + if(2) + skincolor = "#B289C6" + skincolor2 = "B289C6" + if(3) + skincolor = "#a191cc" + skincolor2 = "a191cc" + if(4) + skincolor = "#549ab6" + skincolor2 = "549ab6" + if(5) + skincolor = "#2c2421" + skincolor2 = "2c2421" + skin_tone = skincolor2 + var/obj/item/organ/tail/tail = src.getorganslot(ORGAN_SLOT_TAIL) + if(!tail) + tail = new() + tail.Insert(src, TRUE, FALSE) + var/tailchoose = rand(1,8) + switch(tailchoose) //choosing the TAIL for the tiefling + if(1) + tail.accessory_type = /datum/sprite_accessory/tail/tiefling + if(2) + tail.accessory_type = /datum/sprite_accessory/tail/tiefling/heart + if(3) + tail.accessory_type = /datum/sprite_accessory/tail/large_snake + if(4) + tail.accessory_type = /datum/sprite_accessory/tail/large_snake_plain + if(5) + tail.accessory_type = /datum/sprite_accessory/tail/batl + if(6) + tail.accessory_type = /datum/sprite_accessory/tail/bats + if(7) + tail.accessory_type = /datum/sprite_accessory/tail/murid + if(8) + tail.accessory_type = /datum/sprite_accessory/tail/guilmon + tail.accessory_colors = skincolor + if(organ_ears) + organ_ears.accessory_colors = skincolor + + if(gender == FEMALE) + new_hair.set_accessory_type(hairf, null, src) + var/obj/item/organ/breasts/breasts = src.getorganslot(ORGAN_SLOT_BREASTS) + if(!breasts) + breasts = new() + breasts.Insert(src, TRUE, FALSE) + breasts.accessory_type = /datum/sprite_accessory/breasts/pair + breasts.breast_size = rand(1,16) + breasts.accessory_colors = skincolor + + else + new_hair.set_accessory_type(hairm, null, src) + + var/obj/item/organ/butt/butt = src.getorganslot(ORGAN_SLOT_BUTT) + if(!butt) + butt = new() + butt.Insert(src, TRUE, FALSE) + butt.accessory_type = /datum/sprite_accessory/butt/pair + butt.organ_size = rand(0,5) + butt.accessory_colors = skincolor + + var/obj/item/organ/belly/belly = src.getorganslot(ORGAN_SLOT_BELLY) + if(!belly) + belly = new() + belly.Insert(src, TRUE, FALSE) + belly.accessory_type = /datum/sprite_accessory/belly + belly.belly_size = 0 + belly.accessory_colors = skincolor + + head.add_bodypart_feature(new_hair) + + new_hair.accessory_colors = "#31302E" + new_hair.hair_color = "#31302E" + hair_color = "#31302E" + + dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + dna.species.handle_body(src) + if(gender == FEMALE) + real_name = pick(world.file2list("strings/rt/names/other/tieff.txt")) + else + real_name = pick(world.file2list("strings/rt/names/other/tiefm.txt")) + update_hair() + update_body() + +/datum/outfit/job/roguetown/tiberianevil/npc/pre_equip(mob/living/carbon/human/H) //gives some default skills and equipment for player controlled elves + H.STASTR = 12 + var/chance_zjumper = 5 + var/chance_treeclimber = 30 + H.STASPD = 15 + if(prob(chance_zjumper)) + ADD_TRAIT(H, TRAIT_ZJUMP, TRAIT_GENERIC) + H.find_targets_above = TRUE + if(prob(chance_treeclimber)) + H.tree_climber = TRUE + H.find_targets_above = TRUE // so they can taunt + H.STACON = 12 + H.STAWIL = 12 + H.STAINT = 12 + H.adjust_skillrank(/datum/skill/combat/polearms, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/maces, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/axes, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/swords, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/shields, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 2, TRUE) + H.adjust_skillrank(/datum/skill/combat/wrestling, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/swimming, 2, TRUE) + H.adjust_skillrank(/datum/skill/misc/climbing, 2, TRUE) + var/loadout = rand(1,4) + switch(loadout) + if(1) //duelist tief + armor = /obj/item/clothing/suit/roguetown/armor/leather + head = /obj/item/clothing/head/roguetown/duelhat + mask = /obj/item/clothing/mask/rogue/duelmask + cloak = /obj/item/clothing/cloak/half + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + shirt = /obj/item/clothing/suit/roguetown/shirt/undershirt/black + pants = /obj/item/clothing/under/roguetown/trou/leather + beltl = /obj/item/storage/belt/rogue/pouch/coins/poor + shoes = /obj/item/clothing/shoes/roguetown/boots + neck = /obj/item/clothing/neck/roguetown/gorget + gloves = /obj/item/clothing/gloves/roguetown/fingerless_leather + backl = /obj/item/storage/backpack/rogue/satchel + backr = /obj/item/rogueweapon/shield/buckler + belt = /obj/item/storage/belt/rogue/leather + H.adjust_skillrank_up_to(/datum/skill/combat/swords, SKILL_LEVEL_EXPERT, TRUE) + r_hand = /obj/item/rogueweapon/sword/rapier + if(2) //desert tief + shirt = /obj/item/clothing/suit/roguetown/armor/gambeson/heavy/raneshen + pants = /obj/item/clothing/under/roguetown/trou/leather/pontifex/raneshen + head = /obj/item/clothing/head/roguetown/roguehood/shalal/hijab + gloves = /obj/item/clothing/gloves/roguetown/angle + belt = /obj/item/storage/belt/rogue/leather + backl = /obj/item/storage/backpack/rogue/satchel + beltl = /obj/item/storage/belt/rogue/pouch/coins/poor + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + shoes = /obj/item/clothing/shoes/roguetown/boots + cloak = /obj/item/clothing/cloak/raincloak/furcloak/brown + r_hand = /obj/item/rogueweapon/sword/saber/iron + if(3) //thief elf + armor = /obj/item/clothing/suit/roguetown/armor/leather + shirt = /obj/item/clothing/suit/roguetown/armor/gambeson + backl = /obj/item/storage/backpack/rogue/backpack + backr = /obj/item/gun/ballistic/revolver/grenadelauncher/bow + pants = /obj/item/clothing/under/roguetown/trou/leather + shoes = /obj/item/clothing/shoes/roguetown/boots + neck = /obj/item/storage/belt/rogue/pouch/coins/poor + wrists = /obj/item/clothing/wrists/roguetown/bracers/leather + gloves = /obj/item/clothing/gloves/roguetown/fingerless + belt = /obj/item/storage/belt/rogue/leather/knifebelt/iron + cloak = /obj/item/clothing/cloak/raincloak/mortus + beltl = /obj/item/quiver/Warrows + beltr = /obj/item/rogueweapon/mace/cudgel + r_hand = /obj/item/rogueweapon/huntingknife/idagger/steel + if(4) //zinzoid wrestler nudist + H.STASTR = 18 + H.STACON = 15 + H.STASPD = 10 //slower, beefy motherfucker + H.STAINT = 4 //dumbass + H.adjust_skillrank(/datum/skill/combat/wrestling, 5, TRUE) + H.adjust_skillrank(/datum/skill/combat/unarmed, 4, TRUE) + +/mob/living/carbon/human/species/tiberianevil/npc/death(gibbed, nocutscene) + if(vore_organs.len > 0) + for(var/obj/belly/B in vore_organs) + B.release_all_contents(TRUE) + . = ..() diff --git a/modular_causticcove/code/modules/mob/living/carbon/vnpc/v_npc.dm b/modular_causticcove/code/modules/mob/living/carbon/vnpc/v_npc.dm new file mode 100644 index 00000000000..edebc2b16b2 --- /dev/null +++ b/modular_causticcove/code/modules/mob/living/carbon/vnpc/v_npc.dm @@ -0,0 +1,247 @@ +//Anything related to NPC that does vore. +/mob/living + var/vore_stomach_name // The name for the first belly if not "stomach" + var/vore_stomach_flavor // The flavortext for the first belly if not the default + var/vore_default_mode = DM_DIGEST // Default bellymode (DM_DIGEST, DM_HOLD, DM_ABSORB) + var/vore_default_flags = 0 // No flags + var/vore_digest_chance = 0 // Chance to switch to digest mode if resisted + var/vore_absorb_chance = 0 // Chance to switch to absorb mode if resisted + var/vore_escape_chance = 25 // Chance of resisting out of mob + var/vore_escape_chance_absorbed = 20// Chance of absorbed prey finishing an escape. Requires a successful escape roll against the above as well. + var/vore_default_item_mode = IM_DIGEST_FOOD //How belly will interact with items + var/vore_default_contaminates = FALSE //Will it contaminate? // CHOMPedit: Put back to true like it always was. + var/vore_default_contamination_flavor = "Generic" //Contamination descriptors + var/vore_default_contamination_color = "green" //Contamination color + var/swallowTime = 5 SECONDS + +/mob/living/carbon/human + //are they able to eat nerds. + var/is_voracious_npc = FALSE + +/mob/living/carbon/human/proc/increase_belly_size() + var/obj/item/organ/belly/_belly = getorganslot("belly") + if(!_belly) + return + _belly.belly_size = 3 + src.regenerate_icons() + +/mob/living/carbon/human/proc/decrease_belly_size() + var/obj/item/organ/belly/_belly = getorganslot("belly") + if(!_belly) + return + _belly.belly_size = 0 + src.regenerate_icons() + +/mob/living/proc/load_mob_bellies() + //A much more detailed version of the default /living implementation + var/obj/belly/B = new /obj/belly(src) + vore_selected = B + B.immutable = TRUE + B.can_taste = TRUE + B.name = vore_stomach_name ? vore_stomach_name : "stomach" + B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside %pred." + B.digest_mode = vore_default_mode + B.mode_flags = vore_default_flags + B.item_digest_mode = vore_default_item_mode + B.contaminates = vore_default_contaminates + B.contamination_flavor = vore_default_contamination_flavor + B.contamination_color = vore_default_contamination_color + B.escapable = vore_escape_chance > 0 + B.escapechance = vore_escape_chance + B.escapechance_absorbed = vore_escape_chance_absorbed + B.digestchance = vore_digest_chance + B.absorbchance = vore_absorb_chance + B.human_prey_swallow_time = swallowTime + B.nonhuman_prey_swallow_time = swallowTime + B.vore_verb = "swallow" + B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "The predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes harmlessly.", + "The predator's calm breathing and thumping heartbeat pulses around you.", + "The warm walls kneads harmlessly against you.", + "The liquids churn around you, though there doesn't seem to be much effect.", + "The sound of bodily movements drown out everything for a moment.", + "The predator's movements gently force you into a different position.") + B.emote_lists[DM_DIGEST] = list( + "The burning acids eat away at your form.", + "The muscular stomach flesh grinds harshly against you.", + "The caustic air stings your chest when you try to breathe.", + "The slimy guts squeeze inward to help the digestive juices soften you up.", + "The onslaught against your body doesn't seem to be letting up; you're food now.", + "The predator's body ripples and crushes against you as digestive enzymes pull you apart.", + "The juices pooling beneath you sizzle against your sore skin.", + "The churning walls slowly pulverize you into meaty nutrients.", + "The stomach glorps and gurgles as it tries to work you into slop.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + B.belly_fullscreen = "a_tumby" + B.belly_fullscreen_color = "#823232" + B.belly_fullscreen_color2 = "#823232" +//-------------------------------------------------------------------------- +//Credit to Syribirb for doing the entirety of the belly descriptions! +/mob/living/proc/load_generic_bellies() + //Loading genderless catchall bellies + var/obj/belly/M = new /obj/belly(src) + vore_selected = M + M.immutable = TRUE + M.can_taste = TRUE + M.name = vore_stomach_name ? vore_stomach_name : "maw" + M.desc = vore_stomach_flavor ? vore_stomach_flavor : "You're forcefully picked from the ground and lifted up to face your assailant. Their hands grip at your arms, holding them to your sides and restraining you. Your body is sore from fighting, you have a hard time breaking free of them. You're tugged in against their chest, the heat of their post-battle state settling into yours. You can hear their breath heave, their body taking a moment to rest as they look you over. There's a chuckle from up above, and when you finally look up to face them, there's a predatory look in %pred's eye.

They heft you a second time, lifting you up to their face as their lips part. A molten tongue slips up your cheek, leaving a wet trail of slobber across your face. They make an appreciative little hum as their eyes flutter down at you. Apparently you're delicious. Their breath breaks against your face in warm billows. Their lips part, and you finally get a flash of their pulsing, dripping throat.

That's the last thing you see before you're smothered against their tongue. Teeth scrape against your scalp as their lips come around your neck. The wet muscle glides across your face as they taste you. Breath billows around your body, drool oozes down your chest... It's easy to see where this is going." + M.digest_mode = vore_default_mode + M.mode_flags = vore_default_flags + M.item_digest_mode = vore_default_item_mode + M.contaminates = vore_default_contaminates + M.contamination_flavor = vore_default_contamination_flavor + M.contamination_color = vore_default_contamination_color + M.escapable = vore_escape_chance > 0 + M.escapechance_absorbed = vore_escape_chance_absorbed + M.digestchance = 0 + M.absorbchance = 0 + M.human_prey_swallow_time = swallowTime + M.nonhuman_prey_swallow_time = swallowTime + M.digest_brute = 0 + M.digest_burn = 0 + M.digest_mode = "Hold" + M.vore_verb = "swallow" + M.examine_messages = list( + "%pred is currently lapping against %prey's face! Threatening to swallow them down at any moment…") + M.emote_lists[DM_HOLD] = list( + "You're adjusted in that maw for a few moments, before you finally get another glimpse of daylight! Of course, those lips slurp you back in within an instant as you struggle for air.", + "%pred's tongue passes over your face, coating you in thick slobber as the rest of their maw clings tightly to your head. Wet half-swallows prepare you for the upcoming plunge…", + "%pred lets out a wet slurp around your neck, their hands wandering your body as they try to get a better handhold to shove you in!", + "A groan emanates from %pred's midriff as you struggle against them. You can feel it rumble against you, their body anticipating a meal.") + M.struggle_messages_inside = list( + "You struggle against %pred's grip! Your body squirms against their grasp as their warm frame rubs up against you.", + "Your resistance only pushes your face harder against %pred's molten tongue. You can feel their throat pulse against your scalp… schlrp", + "Slobber oozes down your chest as you resist %pred's attempt to shove you in deeper. Their warm breath heaves across your face and neck, strained with the effort of trying to restrain you.", + "You rail against %pred's greedy swallows, trying your hardest not to get sucked down their throat!", + "Your arms push out against the tight grip holding them to your sides, and you try to kick your way free of your binds! You can feel that mouth tighten, trying its best to swallow you down as you resist." + ) + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + M.escape_attempt_messages_prey = "You start to kick away from %pred's grasp!" + M.escape_messages_outside = "%prey manages to escape %pred's clutches!" + M.escape_messages_prey = "You managed to get away from %pred's grasp!" + M.escape_fail_messages_prey = "You managed to slip up, getting further trapped!" + M.escapechance = 25 + M.autotransferable = 1 + M.autotransferlocation = "throat" + M.autotransferwait = 300 + M.autotransferchance = 100 + M.autotransfer_min_amount = 1 + M.autotransfer_whitelist = 53 + M.autotransfer_enabled = 1 + M.belly_fullscreen = "vbo_maw14" + M.belly_fullscreen_color = "#823232" + M.belly_fullscreen_color2 = "#823232" + + var/obj/belly/T = new /obj/belly(src) + T.immutable = TRUE + T.can_taste = TRUE + T.name = vore_stomach_name ? vore_stomach_name : "throat" + T.desc = vore_stomach_flavor ? vore_stomach_flavor : "They finally lift up your body and toss you back into their throat. Wet walls grip at you from every angle as you slide back down that wet, pulsing tunnel. Molten heat surges from the walls around you and into your body, and you're coated in the thick grool of their internal fluids.

From every angle all you can hear is messy gulps, slurps, and swallows. Muscles grinding in an attempt to pack away a meal they can hardly handle. You are a bulge, writhing as you pass down %pred's throat.

It won't be long now, you hear another anticipatory groan from beneath as you're pulled ever deeper into %pred. Your legs are pulled up over their head as gravity fully reverses.You feel hands claw and grip at your hips, shoving you down yet further…" + T.digest_mode = vore_default_mode + T.mode_flags = vore_default_flags + T.item_digest_mode = vore_default_item_mode + T.contaminates = vore_default_contaminates + T.contamination_flavor = vore_default_contamination_flavor + T.contamination_color = vore_default_contamination_color + T.escapable = vore_escape_chance > 0 + T.escapechance_absorbed = vore_escape_chance_absorbed + T.digestchance = 0 + T.absorbchance = 0 + T.human_prey_swallow_time = swallowTime + T.nonhuman_prey_swallow_time = swallowTime + T.digest_brute = 0 + T.digest_burn = 0 + T.digest_mode = "Hold" + T.vore_verb = "swallow" + T.examine_messages = list( + "%pred has %prey halfway shoved into their maw! The lower half of their body writhes and shifts against their grip, but their upper half is already nothing but a bulge.") + T.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace + "You hear %pred's heartbeat through the pulsing walls that hold you. Their tongue crawls down your midriff as you feel yourself sinking deeper.", + "A thick swallow splits the air, another pulse wrings your entire body as you're slowly consumed.", + "Hands slide down your lower body, gripping into your hips and ass for a better hold to shove you deeper.", + "Another gulp. Every push further into their throat sends a bounce through your entire frame.", + "Your body is compressed by another push deeper, the thick grool of %pred's throat oozing into every inch of your clothing as teeth scrape up your frame.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + T.struggle_messages_inside = list( + "You push back against %pred's throat, but your arms are pinned to your sides. It's all you can do to attempt to shift your lower body in a way that's slightly less convenient for them to swallow.", + "You thrash against the squeezing throat muscles, your hips bouncing against the warm, wet jaws that slide up your body.", + "You kick against %pred's entrenched hands, but their nails just dig deep into your thighs. You find yourself hard pressed to break their grip as they shove you in more firmly.", + "A wet groan comes from the grinding muscles around you as you try to slip your way back out of that throat. You have to buck against the grip on your hips, your arms struggling against wet, slick muscles.", + "Your back arches as you attempt to wriggle your way up out of the clenching throat that surrounds you. The effort makes your face press up against the clenching esophagus all the more, smearing you in %pred's fluids." + ) + T.struggle_messages_outside = list( + "%prey kicks against %pred's grip on their legs! The bulge inside that throat shifts faintly…", + "%prey arches their back, thrashing against the bulging throat holding them! You can see their face in a perfect outline.", + "%prey wriggles against the tight throat that holds them. A wet GLRNK marks a stark descent and a bounce that ripples through their frame as they're lowered just a few inches deeper." + ) + T.autotransferable = 1 + T.autotransferlocation = "stomach" + T.autotransferwait = 300 + T.autotransferchance = 100 + T.autotransfer_min_amount = 1 + T.autotransfer_whitelist = 53 + T.autotransfer_enabled = 1 + T.escape_attempt_messages_prey = "You start to climb up %pred's greedy throat!" + T.escape_messages_outside = "%prey manages to slide out from the now pissed off predator." + T.escape_messages_prey = "You managed to slide out from %pred's greedy throat" + T.escape_fail_messages_prey = "%pred stifles your escape attempt with another greedy swallow." + T.escapechance = 10 + T.belly_fullscreen = "vboanim_belly1" + T.belly_fullscreen_color = "#823232" + T.belly_fullscreen_color2 = "#823232" + + var/obj/belly/B = new /obj/belly(src) + B.immutable = TRUE + B.can_taste = TRUE + B.name = vore_stomach_name ? vore_stomach_name : "stomach" + B.desc = vore_stomach_flavor ? vore_stomach_flavor : "SCHLRP...ghlp... BHHHRRRRRRRP!!!

Your body is finally dropped through the rest of %pred's throat as you sliiide down their esophagus and into the pit of their gut. Face-first, you're smooshed into a thick grool comprising of all of their previous meals and a warm acrid fluid.

A hand braces your fall from beneath, you can feel it through the tight grip of the stomach that surrounds you. It helps push the underside of that gut smothering against your face. Your body is forced to curl in on itself by the gripping muscles. The atmosphere here is tainted with the smell of digestion, it creeps into your every breath.

By no force other than the tightness of the chamber that grips you, you finally manage to right yourself, feeling the sheer wobbly bloat you've forced upon the predator outside. The muscles that surround you churn, groan, and strain as they try their best to keep you contained. Your outline is nothing but a pretty decoration on %pred's midriff..." + B.digest_mode = vore_default_mode + B.mode_flags = vore_default_flags + B.item_digest_mode = vore_default_item_mode + B.contaminates = vore_default_contaminates + B.contamination_flavor = vore_default_contamination_flavor + B.contamination_color = vore_default_contamination_color + B.escapable = vore_escape_chance > 0 + B.escapechance_absorbed = vore_escape_chance_absorbed + B.digestchance = vore_digest_chance + B.absorbchance = vore_absorb_chance + B.human_prey_swallow_time = swallowTime + B.nonhuman_prey_swallow_time = swallowTime + B.vore_verb = "swallow" + B.examine_messages = "%pred is bloated with some wriggling meal. Their stomach stretches over a bouncing, thick bulge, ripping through their clothing. Whoever it is occasionally shifts, pushing against the audibly straining, groaning muscles. They're still alive in there…" + B.digest_brute = 0.5 + B.digest_burn = 0.5 + B.escape_attempt_messages_prey = "You begin to attack %pred's taught stomach effectively!" + B.escape_messages_outside = "%pred lurches over, horking up %prey. Ugh..." + B.escape_messages_prey = "A sudden reflex, and you manage to make %pred cough you up. Slimy, but alive!" + B.escape_fail_messages_prey = "%pred's stomach clenches down hard, preventing your escape." + B.escapechance = 5 + B.emote_lists[DM_DIGEST] = list( + "You feel a hand pass over your frame from outside, then SQUISH you in against %pred's midriff. It forces an idle belch up out of their lips…", + "The noises of indigestion ripple from all around you as %pred's body struggles to take in such a massive meal. Each vibration of muscle straining against muscle ripples the entire chamber in wet grrrrgls.", + "The stomach that surrounds you randomly clenches, forcing the acids up your body. You're drenched in %pred's internal fluids as you try to keep yourself righted.", + "%pred simply goes about their day outside, each step sending a ripple through the thick, bloated gut that you occupy.", + "You can hear %pred's heartbeat faintly through the walls, as well as their breath. There's a little delicate hitch in their breathing as a clench rolls through their middle.", + "A vibration splits the air with a wet glrbl as that whole gut shifts you once again with a forceful clench.") + can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default. + B.struggle_messages_inside = list( + "You kick against the clenching walls that surround you, only to be greeted by yet more digestive noises.", + "Your thrashing splashes the thick slop that surrounds you, forcing %pred's gut to slosh and wobble atop their midriff.", + "You push your arms out against the tight stomach walls. You're greeted by another muscular clench, forcing them back in and threatening to flip you.", + "As you wriggle and thrash against the tight stomach walls, your face is crammed up against them. You're smeared in thick digestive juices as you inadvertently smother yourself in those molten innards.", + "A few struggles cause that gut to bounce, and a resulting clench causes gravity to reverse. Your face is squished against the pit of that stomach, and deprived of air you have to wriggle desperately to right yourself." + ) + B.struggle_messages_outside = list( + "%pred's bloated gut bounces with the shifting meal inside.", + "You can see hands push out from within %pred's gut, before a liquid glorp and a clench shoves them back in.", + "A rumble passes through %pred's fattened middle, the round of it wobbling with struggling prey.", + "A thick bulge squirms inside the bloat of %pred's gut, and a clench forces out a muffled belch as the outline of some poor preything is briefly made visible." + ) + B.belly_fullscreen = "vbo_belly5" + B.belly_fullscreen_color = "#823232" + B.belly_fullscreen_color2 = "#823232" +//-------------------------------------------------------------------------- + diff --git a/roguetown.dme b/roguetown.dme index 874ac9afabb..76a901a373b 100644 --- a/roguetown.dme +++ b/roguetown.dme @@ -3213,4 +3213,16 @@ #include "modular_causticcove\code\game\objects\items\clothes\causthats.dm" #include "modular_causticcove\code\modules\chemistry\reagents\caustic_sauces.dm" #include "modular_causticcove\code\modules\chemistry\reagents\caustic_sauces_reactions.dm" +#include "code\modules\roguetown\roguemachine\questing\types\kill\quest_predhunt.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\v_npc.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\goblinpevil.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\elfevil.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\lamiaevil.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\tieflingevil.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\drowevil.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\ambush_config\evilgobambush.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\ambush_config\eviltieflingambush.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\ambush_config\evillamiaambush.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\ambush_config\evilelfambush.dm" +#include "modular_causticcove\code\modules\mob\living\carbon\vnpc\ambush_config\evildrowambush.dm" // END_INCLUDE diff --git a/strings/rt/evileatlines.txt b/strings/rt/evileatlines.txt new file mode 100644 index 00000000000..81aa91c5389 --- /dev/null +++ b/strings/rt/evileatlines.txt @@ -0,0 +1,5 @@ +*begins to hoist up their foe for something awful... +*starts to lower their maw. Uh oh. +*parts their lips, about to do something evil. +*pins their target down, attempting to stuff them somewhere! +*pounces upon their prey, panting wildly! diff --git a/strings/rt/evilgobinaggrolines.txt b/strings/rt/evilgobinaggrolines.txt new file mode 100644 index 00000000000..4fb48a736bd --- /dev/null +++ b/strings/rt/evilgobinaggrolines.txt @@ -0,0 +1,27 @@ +,g Oi! Who's stompin' in my turf?! +,g Intruder! Get 'em! +,g Look what crawled in! +,g THAT ONE IS MINE!!! +,g You lost, tall-one? +,g I see ya! Come out! +,g Hehehe… shiny things! +,g Grab 'em before they run! +,g You picked the wrong cave! +,g Oi lads! We got a live one! +,g Thought you could sneak past me? +,g Get back here, squishy! +,g I'm gonna break ya! +,g Stop right there! +,g That armor's mine now! +,g Dinner just walked in! +,g I smell fear! +,g Run! I like chasin'! +,g I'll hang your skull up! +,g You ain't leavin' alive! +,g Grab the shiny bits after! +,g Found the sneaky rat! +,g Oi! Come fight! +,g I'll take your boots! AFter I'm through with you that is... +*wipes off drool from their lips, and glares. +*points and grins. +*waves their weapon haphazardly. diff --git a/strings/rt/evillamiaaggrolines.txt b/strings/rt/evillamiaaggrolines.txt new file mode 100644 index 00000000000..169586e3396 --- /dev/null +++ b/strings/rt/evillamiaaggrolines.txt @@ -0,0 +1,4 @@ +*tastes the air, getting quite a grin over their face as they eye you up. You can see too-white fangs through their delicate smile. +*flutters their lashes toward you, opening their mouth wide in a display of their pulsing, dripping throat. There’s almost no limit to how their jaw can spread. It’s only an instant before their jaw KLAKs shut gain. +*looks toward you, then back towards their thick, fattened tail. A noticeable bulge in it groans and gurgles, passing a little deeper as they smile. They give it a smack before lunging toward you again. +*crooks a finger toward you, spreading their arms wide as they make space. Their lashes flutter as they invite you to surrender to their embrace. A wet gllrrgl from their midriff belies their true intentions… diff --git a/strings/rt/vnpcaggrolines.txt b/strings/rt/vnpcaggrolines.txt new file mode 100644 index 00000000000..b5f5d13b450 --- /dev/null +++ b/strings/rt/vnpcaggrolines.txt @@ -0,0 +1,4 @@ +*eyes you up in a predatory manner, licking their lips. Their lashes flutter as they bite their lower lip afterward. +*sighs with a kind of longing. Their gut lets out a thick, churning rumble you can hear from where you’re standing. +*giggles as they pause combat to point at you, then at their midriff. There’s a wry smirk on their face that says they only see this ending one way. +*rubs their midriff a moment, winking in your direction. A monstrous gwrrrgl resounds from that waiting pit…