diff --git a/code/__DEFINES/voreconstants.dm b/code/__DEFINES/voreconstants.dm index 4252972c6f..3b6e3c0a31 100644 --- a/code/__DEFINES/voreconstants.dm +++ b/code/__DEFINES/voreconstants.dm @@ -1,6 +1,5 @@ // Overhauled vore system - -/* #define DM_HOLD "Hold" +#define DM_HOLD "Hold" #define DM_DIGEST "Digest" #define DM_HEAL "Heal" #define DM_ABSORB "Absorb" @@ -8,6 +7,10 @@ #define VORE_STRUGGLE_EMOTE_CHANCE 40 +// Stance for hostile mobs to be in while devouring someone. +#define HOSTILE_STANCE_EATING 99 + + var/global/list/player_sizes_list = list("Macro" = RESIZE_HUGE, "Big" = RESIZE_BIG, "Normal" = RESIZE_NORMAL, "Small" = RESIZE_SMALL, "Tiny" = RESIZE_TINY) @@ -36,7 +39,24 @@ var/global/list/death_sounds = list( 'sound/vore/death8.ogg', 'sound/vore/death9.ogg', 'sound/vore/death10.ogg') -*/ + +var/global/list/vore_sounds = list( + "Gulp" = 'sound/vore/gulp.ogg', + "Insert" = 'sound/vore/insert.ogg', + "Insertion1" = 'sound/vore/insertion1.ogg', + "Insertion2" = 'sound/vore/insertion2.ogg', + "Insertion3" = 'sound/vore/insertion3.ogg', + "Schlorp" = 'sound/vore/schlorp.ogg', + "Squish1" = 'sound/vore/squish1.ogg', + "Squish2" = 'sound/vore/squish2.ogg', + "Squish3" = 'sound/vore/squish3.ogg', + "Squish4" = 'sound/vore/squish4.ogg') + +var/global/list/struggle_sounds = list( + "Squish1" = 'sound/vore/squish1.ogg', + "Squish2" = 'sound/vore/squish2.ogg', + "Squish3" = 'sound/vore/squish3.ogg', + "Squish4" = 'sound/vore/squish4.ogg') //Species listing diff --git a/code/__HELPERS/text_vr.dm b/code/__HELPERS/text_vr.dm new file mode 100644 index 0000000000..a16b6c0cfc --- /dev/null +++ b/code/__HELPERS/text_vr.dm @@ -0,0 +1,9 @@ +//Readds quotes and apostrophes to HTML-encoded strings +/proc/readd_quotes(var/t) + var/list/repl_chars = list(""" = "\"","'" = "'") + for(var/char in repl_chars) + var/index = findtext(t, char) + while(index) + t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+5) + index = findtext(t, char) + return t diff --git a/code/__HELPERS/type2type_vr.dm b/code/__HELPERS/type2type_vr.dm new file mode 100644 index 0000000000..e6df531806 --- /dev/null +++ b/code/__HELPERS/type2type_vr.dm @@ -0,0 +1,107 @@ +/* +// Contains VOREStation type2type functions +// list2text - takes delimiter and returns text +// text2list - takes delimiter, and creates list +// +*/ + +// Concatenates a list of strings into a single string. A seperator may optionally be provided. +/proc/list2text(list/ls, sep) + if (ls.len <= 1) // Early-out code for empty or singleton lists. + return ls.len ? ls[1] : "" + + var/l = ls.len // Made local for sanic speed. + var/i = 0 // Incremented every time a list index is accessed. + + if (sep <> null) + // Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc... + #define S1 sep, ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + + . = "[ls[++i]]" // Make sure the initial element is converted to text. + + // Having the small concatenations come before the large ones boosted speed by an average of at least 5%. + if (l-1 & 0x01) // 'i' will always be 1 here. + . = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2. + if (l-i & 0x02) + . = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. + if (l-i & 0x04) + . = text("[][][][][][][][][]", ., S4) // And so on.... + if (l-i & 0x08) + . = text("[][][][][][][][][][][][][][][][][]", ., S4, S4) + if (l-i & 0x10) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16) + if (l-i & 0x20) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) + if (l-i & 0x40) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + + #undef S64 + #undef S16 + #undef S4 + #undef S1 + else + // Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc... + #define S1 ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + + . = "[ls[++i]]" // Make sure the initial element is converted to text. + + if (l-1 & 0x01) // 'i' will always be 1 here. + . += S1 // Append 1 element if the remaining elements are not a multiple of 2. + if (l-i & 0x02) + . = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. + if (l-i & 0x04) + . = text("[][][][][]", ., S4) // And so on... + if (l-i & 0x08) + . = text("[][][][][][][][][]", ., S4, S4) + if (l-i & 0x10) + . = text("[][][][][][][][][][][][][][][][][]", ., S16) + if (l-i & 0x20) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) + if (l-i & 0x40) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + + #undef S64 + #undef S16 + #undef S4 + #undef S1 + +// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator) +/proc/text2list(text, delimiter="\n") + var/delim_len = length(delimiter) + if (delim_len < 1) + return list(text) + + . = list() + var/last_found = 1 + var/found + + do + found = findtext(text, delimiter, last_found, 0) + . += copytext(text, last_found, found) + last_found = found + delim_len + while (found) diff --git a/code/citadel/chemistry.dm b/code/citadel/chemistry.dm deleted file mode 100644 index 885f2fa44e..0000000000 --- a/code/citadel/chemistry.dm +++ /dev/null @@ -1,1006 +0,0 @@ -datum - reagents - proc - get_reagent_data(var/reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A - if (R.id == reagent) - return R.data - - return 0 - - - - - - - - - - - - - - -datum - reagent - semen - data = list("adjective"=null, "type"=null, "digested"=null, "digested_DNA"=null, "digested_type"=null, "donor_DNA"=null) - name = "Semen" - id = "semen" - description = "A clear-ish white-ish liquid produced by the... sexual parts of mammals." - reagent_state = LIQUID - color = "#DFDFDF" // rgb: 223, 223, 223 - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(M.getBruteLoss() && prob(20)) M.heal_organ_damage(1,0) - if(holder.has_reagent("capsaicin")) - holder.remove_reagent("capsaicin", 2) - M.nutrition++ - ..() - return - - reaction_turf(var/turf/open/T, var/volume) - if(!istype(T)) return - //var/datum/reagent/semen/self = src - src = null - if(!(volume >= 3)) return - var/obj/effect/decal/cleanable/sex/sex_prop = locate() in T - if(!sex_prop) - sex_prop = new/obj/effect/decal/cleanable/sex/semen(T) - - on_merge(var/list/new_data) - if(data&&new_data) - for(var/I in new_data) - if(data[I]==null) - data[I]=new_data[I] - - femjuice - data = list("adjective"=null, "type"=null, "digested"=null, "digested_DNA"=null, "digested_type"=null, "donor_DNA"=null) - name = "Female Ejaculate" - id = "femjuice" - description = "It's really just urine." - reagent_state = LIQUID - color = "#AFAFAF" - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(M.getBruteLoss() && prob(20)) M.heal_organ_damage(1,0) - if(holder.has_reagent("capsaicin")) - holder.remove_reagent("capsaicin", 2) - M.nutrition++ - ..() - return - - reaction_turf(var/turf/open/T, var/volume) - if(!istype(T)) return - //var/datum/reagent/femjuice/self = src - src = null - if(!(volume >= 3)) return - var/obj/effect/decal/cleanable/sex/sex_prop = locate() in T - if(!sex_prop) - sex_prop = new/obj/effect/decal/cleanable/sex/femjuice(T) - - on_merge(var/list/new_data) - if(data&&new_data) - for(var/I in new_data) - if(data[I]==null) - data[I]=new_data[I] - - milk - data = list("adjective"=null, "type"=null, "digested"=null, "digested_DNA"=null, "digested_type"=null, "donor_DNA"=null) - reaction_turf(var/turf/open/T, var/volume) - if(!istype(T)) return - //var/datum/reagent/milk/self = src - src = null - if(!(volume >= 3)) return - var/obj/effect/decal/cleanable/sex/sex_prop = locate() in T - if(!sex_prop) - sex_prop = new/obj/effect/decal/cleanable/sex/milk(T) - - on_merge(var/list/new_data) - if(data&&new_data) - for(var/I in new_data) - if(data[I]==null) - data[I]=new_data[I] - - shrinkchem - name = "Shrink Chemical" - id = "shrinkchem" - description = "Shrinks people. Eaten by larger chemicals." - reagent_state = LIQUID - color = "#C8A5FF" // rgb: 200, 165, 220 - - var/cnt_digested=0 - var/original_size=-1 - - on_mob_life(var/mob/living/M as mob) - if(original_size==-1) - original_size=M.sizeplay_size - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - //if(volume%10==5) - // if(!holder.has_reagent("growchem")) - // M.sizeplay_shrink() - // M<<"You shrink." - if(volume>=1) - cnt_digested++ - if(cnt_digested==5&&volume>1) - if(!holder.has_reagent("growchem")) - M.sizeplay_shrink() - M<<"You shrink." - if(cnt_digested==20) - cnt_digested=0 - original_size=M.sizeplay_size - if(volume<=1&&volume>0&&original_size>M.sizeplay_size) - M<<"You grow back a little." - M.sizeplay_grow() - holder.remove_reagent(src.id, 1) - return - - growchem - name = "Grow Chemical" - id = "growchem" - description = "Enlarges people. Eats smaller chemicals." - reagent_state = LIQUID - color = "#FFA5DC" // rgb: 200, 165, 220 - - var/cnt_digested=0 - var/original_size=-1 - - on_mob_life(var/mob/living/M as mob) - if(original_size==-1) - original_size=M.sizeplay_size - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(holder.has_reagent("shrinkchem")) - holder.remove_reagent("shrinkchem",holder.get_reagent_amount("shrinkchem")-0.1) - //if(volume%10==5) - // M.sizeplay_grow() - // M<<"You grow." - if(volume>=1) - cnt_digested++ - if(cnt_digested==5&&volume>1) - M.sizeplay_grow() - M<<"You grow." - if(cnt_digested==20) - cnt_digested=0 - original_size=M.sizeplay_size - if(volume<=1&&volume>0&&original_size=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()) - var/mob/living/carbon/humz=M - var/bonersize=humz.dna.cock["has"] - if(cnt_digested==20&&bonersize==humz.dna.COCK_NONE) - cnt_digested=0 - humz.dna.cock["has"]=humz.dna.COCK_NORMAL - M<<"You grow a cock." - M.set_cock_block() - humz.updateappearance() - if(cnt_digested==10&&bonersize==humz.dna.COCK_NORMAL) - cnt_digested=0 - humz.dna.cock["has"]=humz.dna.COCK_HYPER - M<<"Your cock is now huge." - M.set_cock_block() - humz.updateappearance() - if(bonersize!=humz.dna.COCK_NORMAL&&bonersize!=humz.dna.COCK_NONE) - cnt_digested=min(1,cnt_digested) - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - decockchem - name = "Wundbonite-" - id = "decockchem" - description = "Type C shrink chemical." - reagent_state = LIQUID - color = "#DFDFFF" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(volume>=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()&&!holder.has_reagent("cockchem")) - var/mob/living/carbon/humz=M - var/bonersize=humz.dna.cock["has"] - if(cnt_digested==20&&bonersize==humz.dna.COCK_NORMAL) - cnt_digested=0 - humz.dna.cock["has"]=humz.dna.COCK_NONE - M<<"You no longer have a cock." - M.set_cock_block() - humz.updateappearance() - if(cnt_digested==10&&bonersize==humz.dna.COCK_HYPER) - cnt_digested=0 - humz.dna.cock["has"]=humz.dna.COCK_NORMAL - M<<"Your cock shrinks." - M.set_cock_block() - humz.updateappearance() - if(cnt_digested==10&&bonersize==humz.dna.COCK_DOUBLE) - cnt_digested=0 - humz.dna.cock["has"]=humz.dna.COCK_NORMAL - M<<"You no longer have two cocks." - M.set_cock_block() - humz.updateappearance() - if(bonersize!=humz.dna.COCK_NORMAL&&bonersize!=humz.dna.COCK_HYPER&&bonersize!=humz.dna.COCK_DOUBLE) - cnt_digested=min(1,cnt_digested) - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - vagchem - name = "Fisbonite+" - id = "vagchem" - description = "Type V growth chemical." - reagent_state = LIQUID - color = "#FFDFDF" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(holder.has_reagent("devagchem")) - holder.remove_reagent("devagchem",holder.get_reagent_amount("devagchem")) - if(volume>=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()) - var/mob/living/carbon/humz=M - var/vaghas=humz.dna.vagina - if(vaghas) - cnt_digested=min(1,cnt_digested) - else - if(cnt_digested==20) - cnt_digested=0 - humz.dna.vagina=1 - M<<"A slit forms between your legs. You have a vaigna, now." - M.set_cock_block() - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - devagchem - name = "Fisbonite-" - id = "devagchem" - description = "Type V shrink chemical." - reagent_state = LIQUID - color = "#DFDFFF" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(volume>=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()&&!holder.has_reagent("vagchem")) - var/mob/living/carbon/humz=M - var/vaghas=humz.dna.vagina - if(!vaghas) - cnt_digested=min(1,cnt_digested) - else - if(cnt_digested==20) - cnt_digested=0 - humz.dna.vagina=0 - M<<"You no longer have a vagina." - M.set_cock_block() - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - boobchem - name = "Lactoverbrinitemosidine+" - id = "boobchem" - description = "Type B growth chemical." - reagent_state = LIQUID - color = "#FFEEEE" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(holder.has_reagent("deboobchem")) - holder.remove_reagent("deboobchem",holder.get_reagent_amount("deboobchem")) - if(volume>=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()) - //var/mob/living/carbon/humz=M - var/boobhas=M.gender==FEMALE - if(boobhas) - cnt_digested=min(1,cnt_digested) - else - if(cnt_digested==20) - cnt_digested=0 - M.gender=FEMALE - if(M.has_dna()) - var/datum/dna/Mdna=M.has_dna() - Mdna.uni_identity = setblock(Mdna.uni_identity, DNA_GENDER_BLOCK, construct_block((M.gender!=MALE)+1, 2)) - M<<"You now have boobs." - //M.updateappearance() - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - deboobchem - name = "Lactoverbrinitemosidine-" - id = "deboobchem" - description = "Type V shrink chemical." - reagent_state = LIQUID - color = "#EEEEFF" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(volume>=1) - cnt_digested++ - if(istype(M,/mob/living/carbon)&&M.has_dna()&&!holder.has_reagent("boobchem")) - //var/mob/living/carbon/humz=M - var/boobhas=M.gender==FEMALE - if(!boobhas) - cnt_digested=min(1,cnt_digested) - else - if(cnt_digested==20) - cnt_digested=0 - M.gender=MALE - if(M.has_dna()) - var/datum/dna/Mdna=M.has_dna() - Mdna.uni_identity = setblock(Mdna.uni_identity, DNA_GENDER_BLOCK, construct_block((M.gender!=MALE)+1, 2)) - M<<"You no longer have boobs." - //M.updateappearance() - else - cnt_digested=min(1,cnt_digested) - holder.remove_reagent(src.id, 1) - return - - stomexchem - name = "Bio-Expansion Chemical" - id = "stomexchem" - description = "Enlarges belly by reacting directly with the digestive acids. May react oddly to other bodily fluids." - reagent_state = LIQUID - color = "#C8FFDC" // rgb: 200, 255, 220 - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(volume>=1) - cnt_digested++ - //if(volume%10==5) - if(cnt_digested==10) - cnt_digested=0 - if(M.vore_ability[num2text(VORE_METHOD_ORAL)]=1) - cnt_digested++ - //if(volume%10==5) - if(cnt_digested==10) - cnt_digested=0 - if(M.vore_stomach_datum.factor_offset>-1) - M.vore_stomach_datum.factor_offset=max(M.vore_stomach_datum.factor_offset-1,-1) - if(M.vore_stomach_datum.factor_offset<0) - M<<"Your stomach feels backwards." - for(var/datum/vore_organ/VD in M.vore_organ_list()) - if(!VD.exterior&&VD.digestion_factor>VORE_DIGESTION_SPEED_SLOW) //I should add a "max_factor()" and "min_factor()", as well as "cap_factor()" - VD.digestion_factor=VORE_DIGESTION_SPEED_SLOW //But, that will have to wait until each organ has its own cap. - else - M<<"Your stomach feels calmer." - for(var/datum/vore_organ/VD in M.vore_organ_list()) - if(!VD.exterior&&VD.digestion_factor>VORE_DIGESTION_SPEED_FAST) - VD.digestion_factor=VORE_DIGESTION_SPEED_FAST - holder.remove_reagent(src.id, 1) - return - - hurtnomchem - name = "Hahrname" - id="hurtnomchem" - description = "A highly voracious acid that only eats through things when it wants to." - reagent_state = LIQUID - color = "#FFEEBB" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == 2.0) - return - if(!M) M = holder.my_atom - if(holder.has_reagent("healnomchem")) - var/rmv_cnt=holder.remove_reagent("healnomchem", 1) - holder.remove_reagent(src.id, rmv_cnt) - return - if(volume>=1) - cnt_digested++ - //if(volume%10==5) - if(cnt_digested==10) - cnt_digested=0 - if(M.vore_stomach_datum.factor_offset<1) - M.vore_stomach_datum.factor_offset=min(M.vore_stomach_datum.factor_offset+1,1) - if(M.vore_stomach_datum.factor_offset>0) - M<<"You feel a burning in your chest." - for(var/datum/vore_organ/VD in M.vore_organ_list()) - if(!VD.exterior&&VD.healing_factor) - VD.healing_factor=0 - if(!VD.exterior&&VD.digestion_factor=1) - cnt_digested++ - //if(volume%10==5) - if(cnt_digested==10) - cnt_digested=0 - var/dig_changed=0 - for(var/datum/vore_organ/VD in M.vore_organ_list()) - if(VD.healing_factor) - VD.healing_factor=0 - dig_changed=1 - if(VD.digestion_factor_down()) - dig_changed=1 - if(dig_changed) - M << "Your body calms down from antacid." - holder.remove_reagent(src.id, 0.5) - return - - noantacid - name = "Anti-antacid" - id="noantacid" - description = "Burns your stomach." - reagent_state = LIQUID - color = "#FFDD99" - - var/cnt_digested=0 - - on_mob_life(var/mob/living/M as mob) - if(M.stat == DEAD) - return - if(!M) M = holder.my_atom - - if(holder.has_reagent("noantacid")) - var/rmv_cnt=holder.remove_reagent("noantacid", 0.5) - holder.remove_reagent(src.id, rmv_cnt) - return - - if(volume>=1) - cnt_digested++ - //if(volume%10==5) - if(cnt_digested==10) - cnt_digested=0 - var/dig_changed=0 - for(var/datum/vore_organ/VD in M.vore_organ_list()) - if(VD.healing_factor) - VD.healing_factor=0 - dig_changed=1 - if(VD.digestion_factor_up()) - dig_changed=1 - if(dig_changed) - M << "Your chest burns from anti-antacid!" - holder.remove_reagent(src.id, 0.5) - return - - vorechem - name = "Vorarium" - id = "vorechem" - description = "Can be used to do an assortment of things." - color = "#FF55A0" //I dunno =D - - narkychem - name = "Narkanian Honey" - id = "narkychem" - description = "This lets you see lots of colours." - color = "#CCAAFF" - data = list("active"=0,"count"=1,"adjective"=null,"type"=null,"digested"=null, "digested_DNA"=null, "digested_type"=null, "donor_DNA"=null) - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(data) - M.druggy = max(M.druggy, 30) - switch(data["count"]) - if(1 to 5) - if(prob(5)) M.emote("giggle") - else if(prob(10)) - if(prob(50))M.emote("dance") - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2)) - M.dir = i - sleep(1) - if(5 to 10) - M.druggy = max(M.druggy, 35) - if(prob(5)) M.emote("giggle") - else if(prob(20)) - if(prob(30))M.emote("dance") - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2)) - M.dir = i - sleep(1) - if (10 to INFINITY) - M.druggy = max(M.druggy, 40) - if(prob(5)) M.emote("giggle") - else if(prob(30)) - if(prob(20))M.emote("dance") - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2)) - M.dir = i - sleep(1) - data["count"]++ - holder.remove_reagent(src.id, 0.5) - //..() - return - on_merge(var/list/new_data) - if(data&&new_data) - for(var/I in new_data) - if(data[I]==null) - data[I]=new_data[I] - - vomitchem - name = "Emetic" - id = "vomitchem" - description = "Makes you vomit." - color = "#FFDD99" - data = list("count"=1) - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(data) - switch(data["count"]) - if(6,8) - M.emote("choke") - if (10 to INFINITY) - M.Stun(rand(1,2)) - M.visible_message("[M] throws up!", \ - "[M] throws up!") - playsound(M.loc, 'sound/effects/splat.ogg', 50, 1) - var/turf/location = M.loc - if(istype(location, /turf/open)) - location.add_vomit_floor(M) - M.nutrition -= 50 - M.adjustToxLoss(-1) - if(M.vore_stomach_datum.contents.len) - M.vore_stomach_datum.release(M.vore_stomach_datum.FLAVOUR_SILENT) - if(M.vore_tail_datum.contents.len) - M.vore_tail_datum.release(M.vore_tail_datum.FLAVOUR_HURL) - if(M.vore_breast_datum.contents.len) //ADD THIS TO LACTATE LATER - M.vore_breast_datum.release(M.vore_breast_datum.FLAVOUR_SILENT) - data["count"]=0 - holder.remove_any(holder.total_volume) - - if(!holder.has_reagent("novomitchem")) - data["count"]++ - holder.remove_reagent(src.id, 0.5) - //..() - return - - novomitchem - name = "Antiemetic" - id = "novomitchem" - description = "Makes you not vomit." - color = "#FFDD99" - data = list("count"=1) - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - holder.remove_reagent(src.id, 0.5) - //..() - return - - hornychem - name = "Aphrodisiac" - id = "hornychem" - description = "You so horny." - color = "#FF9999" - data = list("count"=1) - - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - if(data) - switch(data["count"]) - if(1 to 30) - if(prob(9)) M.emote("blush") - if (30 to INFINITY) - if(prob(3)) M.emote("blush") - if(prob(5)) M.emote("moan") - if(prob(3)) - if(M.vore_cock_datum.check_exist()&&M.vore_womb_datum.check_exist()) - if(prob(50)) M.vore_cock_datum.release(M.vore_cock_datum.FLAVOUR_HURL) //I forgot how to make this less stupid. - else M.vore_womb_datum.release(M.vore_womb_datum.FLAVOUR_HURL) //I knew it before, I swear! - else if(M.vore_cock_datum.check_exist()) - M.vore_cock_datum.release(M.vore_cock_datum.FLAVOUR_HURL) - else if(M.vore_womb_datum.check_exist()) - M.vore_womb_datum.release(M.vore_womb_datum.FLAVOUR_HURL) - data["count"]++ - holder.remove_reagent(src.id, 0.5) - //..() - return - -/datum/reagent/sodiumbicarbonate - name = "Sodium Bicarbonate" - id = "sodiumbicarbonate" - description = "A salt made of sodium bicarbonate." - reagent_state = SOLID - color = "#FFFFFF" // rgb: 255,255,255 - - - - - - - - -/datum/chemical_reaction/sodiumbicarbonate - name = "Sodiumbicarbonate" - id = "sodiumbicarbonate" - result = "sodiumbicarbonate" - required_reagents = list("sodiumchloride" = 1, "ammonia" = 1, "carbon" = 1, "oxygen" = 2) - result_amount = 5 - - - -/datum/chemical_reaction/antacid - name = "antacid" - id = "antacid" - result = "antacid" - required_reagents = list("sodiumbicarbonate" = 1, "vorechem" = 1) - result_amount = 2 -/datum/chemical_reaction/noantacid - name = "Noantacid" - id = "noantacid" - result = "noantacid" - required_reagents = list("sodiumchloride" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/growchem - name = "Growchem" - id = "growchem" - result = "growchem" - required_reagents = list("hydrogen" = 1, "vorechem" = 1) - result_amount = 2 -/datum/chemical_reaction/shrinkchem - name = "Shrinkchem" - id = "shrinkchem" - result = "shrinkchem" - required_reagents = list("sodium" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/stomexchem - name = "Stomexchem" - id = "stomexchem" - result = "stomexchem" - required_reagents = list("radium" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/vomitchem - name = "Vomitchem" - id = "vomitchem" - result = "vomitchem" - required_reagents = list("chlorine" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/novomitchem - name = "Novomitchem" - id = "novomitchem" - result = "novomitchem" - required_reagents = list("nitrogen" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/hornychem - name = "Hornychem" - id = "hornychem" - result = "hornychem" - required_reagents = list("lithium" = 1, "vorechem" = 1) - result_amount = 2 - -/datum/chemical_reaction/healnomchem - name = "HealNomchem" - id = "healnomchem" - result = "healnomchem" - required_reagents = list("omnizine" = 2, "vorechem" = 1) - result_amount = 1 - -/datum/chemical_reaction/hurtnomchem - name = "HurtNomchem" - id = "hurtnomchem" - result = "hurtnomchem" - required_reagents = list("facid" = 1, "vorechem" = 1) - result_amount = 2 - - -/datum/chemical_reaction/cockchem - name = "Cockchem" - id = "cockchem" - result = "cockchem" - required_reagents = list("growchem" = 2, "semen" = 3, "vorechem" = 1) - result_amount = 6 -/datum/chemical_reaction/decockchem - name = "Decockchem" - id = "decockchem" - result = "decockchem" - required_reagents = list("shrinkchem" = 2, "semen" = 3, "vorechem" = 1) - result_amount = 6 - -/datum/chemical_reaction/vagchem - name = "Vagchem" - id = "vagchem" - result = "vagchem" - required_reagents = list("growchem" = 2, "femjuice" = 3, "vorechem" = 1) - result_amount = 6 -/datum/chemical_reaction/devagchem - name = "Devagchem" - id = "devagchem" - result = "devagchem" - required_reagents = list("shrinkchem" = 2, "femjuice" = 3, "vorechem" = 1) - result_amount = 6 - -/datum/chemical_reaction/boobchem - name = "Boobchem" - id = "boobchem" - result = "boobchem" - required_reagents = list("growchem" = 2, "milk" = 3, "vorechem" = 1) - result_amount = 6 -/datum/chemical_reaction/deboobchem - name = "Deboobchem" - id = "deboobchem" - result = "deboobchem" - required_reagents = list("shrinkchem" = 2, "milk" = 3, "vorechem" = 1) - result_amount = 6 - -/obj/item/weapon/reagent_containers/pill/shrink - name = "shrink pill" - desc = "Used to shrink people." - icon_state = "pill18" - New() - ..() - reagents.add_reagent("shrinkchem", 10) - -/obj/item/weapon/reagent_containers/pill/grow - name = "grow pill" - desc = "Used to make people larger." - icon_state = "pill19" - New() - ..() - reagents.add_reagent("growchem", 10) - -/obj/item/weapon/reagent_containers/pill/stomex - name = "stomEx pill" - desc = "Used to make the subject more able in the field of vore." - icon_state = "pill9" - New() - ..() - reagents.add_reagent("stomexchem", 10) - -/datum/chemical_reaction/narkychem - name = "Narkychem" - id = "narkychem" - result = "narkychem" - required_reagents = list("vorechem" = 1, "spacemountainwind" = 1, "femjuice" = 2) - //required_catalysts = list("femjuice" = 2) - result_amount=4 - -/datum/chemical_reaction/narkychem/on_reaction(var/datum/reagents/holder, var/created_volume, var/data_send) - - //var/datum/reagent/femjuice/F = locate(/datum/reagent/femjuice) in holder.reagent_list - var/list/F=null - if(data_send) - F=data_send["femjuice"] - var/datum/reagent/narkychem/A = locate(/datum/reagent/narkychem) in holder.reagent_list - if(F) - A.on_merge(F) - /*if(F["digested"]!=null) - if(F["digested"]=="Narky Sawtooth") - if(A&&A.data) - A.data["active"]|=2 - if(F["donor_DNA"]!=null) - var/datum/dna/check_DNA=F["donor_DNA"] - if(check_DNA.mutantrace&&check_DNA.mutantrace=="narky") - if(A&&A.data) - A.data["active"]|=1*/ - //holder.remove_reagent("femjuice",created_volume) - -/obj/item/weapon/storage/box/pillbottles/vore - name = "box of vore pill bottles" - desc = "It has pictures of pill bottles on its front." - icon_state = "pillbox" - New() - ..() - for(var/obj/item/weapon/storage/pill_bottle/PB in src) - qdel(PB) - new /obj/item/weapon/storage/pill_bottle/shrinkpills( src ) - new /obj/item/weapon/storage/pill_bottle/shrinkpills( src ) - new /obj/item/weapon/storage/pill_bottle/shrinkpills( src ) - new /obj/item/weapon/storage/pill_bottle/growpills( src ) - new /obj/item/weapon/storage/pill_bottle/growpills( src ) - new /obj/item/weapon/storage/pill_bottle/growpills( src ) - new /obj/item/weapon/storage/pill_bottle/stomexpills( src ) - -/obj/item/weapon/storage/pill_bottle/shrinkpills - name = "bottle of shrink pills" - desc = "Contains pills used to shirnk people." - - New() - ..() - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - new /obj/item/weapon/reagent_containers/pill/shrink( src ) - -/obj/item/weapon/storage/pill_bottle/growpills - name = "bottle of grow pills" - desc = "Contains pills used to enlarge people." - - New() - ..() - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - new /obj/item/weapon/reagent_containers/pill/grow( src ) - -/obj/item/weapon/storage/pill_bottle/stomexpills - name = "bottle of stomEx pills" - desc = "Contains pills used to increase vore ability." - - New() - ..() - new /obj/item/weapon/reagent_containers/pill/stomex( src ) - new /obj/item/weapon/reagent_containers/pill/stomex( src ) - new /obj/item/weapon/reagent_containers/pill/stomex( src ) - new /obj/item/weapon/reagent_containers/pill/stomex( src ) - - - - - - - - -/*/obj/item/weapon/reagent_containers/food/snacks/narkypudding - name = "Narky Pudding" - desc = "So prettiful." - icon_state = "spacylibertyduff" - trash = /obj/item/trash/snack_bowl - New() - ..() - reagents.add_reagent("nutriment", 12) - reagents.add_reagent("narkychem", 12) - bitesize = 3 - -/datum/recipe/narkypudding - reagents = list("vorechem" = 5, "semen" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/faggot, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/narkypudding - make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/narkypudding/being_cooked = ..(container) - var/datum/reagent/R=container.reagents.has_reagent("semen") - var/datum/reagent/A=being_cooked.reagents.has_reagent("narkychem") - if(!R&&A)A.data["active"]|=1 //TEMP FIX - if(R&&R.data&&R.data["digested"]!=null) - if(R.data["digested"]=="Narky Sawtooth") - if(A&&A.data) - A.data["active"]|=2 - being_cooked.name=being_cooked.name+" (With Real Narky)" - //being_cooked.reagents.add_reagent("narkychem",12) - if(R&&R.data&&R.data["donor_DNA"]!=null) - var/datum/dna/check_DNA=R.data["donor_DNA"] - if(check_DNA.mutantrace()&&check_DNA.mutantrace()=="narky") - if(A&&A.data) - A.data["active"]|=1 - being_cooked.name="Special "+being_cooked.name - //being_cooked.reagents.add_reagent("narkychem",12) - return being_cooked*/ - - - - -/obj/item/weapon/reagent_containers/food/snacks/poor_toast - name = "poorly-drawn toast" - desc = "Filled with porrly-speld nutryents!" - icon_state = "poor_toast" - New() - ..() - reagents.add_reagent("nutriment", 10) - bitesize = 5 - -/obj/item/weapon/reagent_containers/food/snacks/poor_toast/burn - name = "poorly-drawn burnt toast" - desc = "No amount of scraping will remove the porlly-spelt burtn part! Do not feed this to Ian." - icon_state = "poor_toast_burn" - New() - ..() - if(prob(20)) - reagents.remove_reagent("nutriment", 8) - reagents.add_reagent("vomitchem", 8) - -/datum/recipe/poor_toast_burn - //reagents = list() - items = list( - /obj/item/weapon/reagent_containers/food/snacks/poor_toast - ) - result = /obj/item/weapon/reagent_containers/food/snacks/poor_toast/burn diff --git a/code/citadel/flavour.dm b/code/citadel/flavour.dm deleted file mode 100644 index bb936402fc..0000000000 --- a/code/citadel/flavour.dm +++ /dev/null @@ -1 +0,0 @@ -//proc/vore_start_normal(var/method,var/mob/living/pred, var/mob/living/prey, var/headfirst=1) \ No newline at end of file diff --git a/code/citadel/genetics.dm b/code/citadel/genetics.dm deleted file mode 100644 index baeee29768..0000000000 --- a/code/citadel/genetics.dm +++ /dev/null @@ -1,136 +0,0 @@ -var/const/COLOUR_LIST_SIZE=4 - -proc/sanitize_colour_list(var/list/lst=null) - if(!lst||!lst.len) - lst=new/list(COLOUR_LIST_SIZE) - if(lst.len!=COLOUR_LIST_SIZE) - var/new_lst[COLOUR_LIST_SIZE] - for(var/x=1,x<=COLOUR_LIST_SIZE,x++) - new_lst[x]=lst[x] - lst=new_lst - return lst - -proc/generate_colour_icon(var/fil_chk=null,var/state=null,var/list/lst=null,var/add_layer=0,var/offset_x=0,var/offset_y=0,var/overlay_only=0,var/human=0) - if(!fil_chk||!state)return null - lst=sanitize_colour_list(lst) - var/icon/chk=new/icon(fil_chk) - var/list/available_states=chk.IconStates() - var/list/rtn_lst = list() - if(!overlay_only&&available_states.Find("[state]")) - rtn_lst += image("icon"=fil_chk, "icon_state"="[state]", "pixel_y"=offset_y, "pixel_x"=offset_x, "layer"=add_layer) - var/chk_len=human ? 1 : lst.len - for(var/x=1,x<=chk_len,x++) - if(!lst[x]&&!human)continue - var/state_check="[state]_[x]" - if(x==1) - if(human) - state_check="[state]_h" - else - if(!available_states.Find("[state_check]")) - state_check="[state]_h" - if(available_states.Find("[state_check]")) - var/image/colourized = image("icon"=fil_chk, "icon_state"="[state_check]", "pixel_y"=offset_y, "pixel_x"=offset_x, "layer"=add_layer) - var/new_color = "#" + "[human ? human : lst[x]]" - colourized.color = new_color - rtn_lst += colourized - return rtn_lst - -/mob/living/carbon/human/var/heterochromia=0 - -/datum/dna - var/mutanttail //Narky code~ - var/mutantwing - var/wingcolor="FFF" - var/special_color[COLOUR_LIST_SIZE] - var/global/const/COCK_NONE=0 - var/global/const/COCK_NORMAL=1 - var/global/const/COCK_HYPER=2 - var/global/const/COCK_DOUBLE=3 - var/list/cock=list("has"=COCK_NONE,"type"="human","color"="900") - var/vagina=0 - var/datum/special_mutant/special - var/taur=0 //TEMP! - var/mob/living/simple_animal/naga_segment/naga=null //ALSO TEMP! -/* proc/generateExtraData() - var/list/EDL=list( - "race"=mutantrace, - "tail"=mutanttail, - "sc"=special_color, - "cock"=cock, - "vagina"=vagina) - return EDL - proc/addExtraData(var/list/EDL, var/setit=0) - if(EDL["race"]||setit) - mutantrace=EDL["race"] - if(EDL["tail"]||setit) - mutanttail=EDL["tail"] - if(EDL["sc"]||setit) - special_color=EDL["sc"] - if(EDL["cock"]||setit) - cock=EDL["cock"] - if(!isnull(EDL["vagina"])||setit) - vagina=EDL["vagina"]* - - proc/setExtraData(var/list/EDL)*/ - - - - - - - -/datum/special_mutant - proc/generate_overlay() - return 0 - proc/generate_underlay() - return 0 - - -/datum/dna/proc/mutantrace() //Easy legacy support! - if(species) - return species.id - else - return "human" - -/datum/dna/proc/generate_race_block() - var/block_gen="fff" - if(species_list[mutantrace()]) - //block_gen = construct_block(species_list.Find(mutantrace), species_list.len+1) - block_gen = construct_block(species_list.Find(species.id), species_list.len+1) - else - block_gen = construct_block(species_list.len+1, species_list.len+1) - return block_gen - -/mob/living/proc/set_mutantrace(var/new_mutantrace=null) - new_mutantrace=kpcode_race_san(new_mutantrace) - var/datum/dna/dna=has_dna(src) - if(!dna)return - if(new_mutantrace) - //dna.mutantrace=new_mutantrace - if(species_list.Find(new_mutantrace)) - //var/typ=species_list[species_list.Find(dna.species.id)] - //dna.species=new typ() - dna.species=kpcode_race_get(new_mutantrace) - dna.uni_identity = setblock(dna.uni_identity, DNA_MUTANTRACE_BLOCK, dna.generate_race_block()) - regenerate_icons() - - -/datum/dna/proc/generate_cock_block() - var/cock_block=0 - if(cock["has"]) - cock_block+=1 - if(vagina) - cock_block+=2 - return construct_block(cock_block+1, 4) - -/mob/living/proc/set_cock_block() - var/datum/dna/dna=has_dna(src) - if(!dna)return - dna.uni_identity = setblock(dna.uni_identity, DNA_COCK_BLOCK, dna.generate_cock_block()) - - -/mob/living/proc/is_taur() - if(istype(src,/mob/living/carbon/human)&&src:dna&&src:dna:taur) - if(src:dna:species&&kpcode_cantaur(src:dna:species)) - return 1 - return 0 \ No newline at end of file diff --git a/code/citadel/macro.dm b/code/citadel/macro.dm deleted file mode 100644 index 6ea38c8d70..0000000000 --- a/code/citadel/macro.dm +++ /dev/null @@ -1,220 +0,0 @@ -var/const/SIZEPLAY_TINY=1 -var/const/SIZEPLAY_MICRO=2 -var/const/SIZEPLAY_NORMAL=3 -var/const/SIZEPLAY_MACRO=4 -var/const/SIZEPLAY_HUGE=5 - -/mob/living - var/sizeplay_size=SIZEPLAY_NORMAL - - proc - sizeplay_set(var/newsize) - if(!istype(src,/mob/living/carbon)) - if(newsizeinitial(src.sizeplay_size)+1) - return - if(newsize==initial(src.sizeplay_size)) - //src.transform=get_matrix_norm() - //src.pixel_y=0 - stable_matrix(get_matrix_norm(),0) - src.sizeplay_size=newsize - return - else if(newsize>initial(src.sizeplay_size)) - //src.transform=get_matrix_large() - //src.pixel_y=16 - stable_matrix(get_matrix_large(),8) - src.sizeplay_size=newsize - return - return //Paranoid returns - - else if(newsize==SIZEPLAY_TINY) - //src.transform=get_matrix_smallest() - //src.pixel_y=-8 - stable_matrix(get_matrix_smallest(),-8) - src.sizeplay_size=newsize - else if(newsize==SIZEPLAY_MICRO) - //src.transform=get_matrix_small() - //src.pixel_y=-8 - stable_matrix(get_matrix_small(),-4) - src.sizeplay_size=newsize - else if(newsize==SIZEPLAY_MACRO) - //src.transform=get_matrix_large() - //src.pixel_y=16 - stable_matrix(get_matrix_large(),8) - src.sizeplay_size=newsize - else if(newsize==SIZEPLAY_HUGE) // Huge should be the largest size - // removed these comments - // not being used anyway - stable_matrix(get_matrix_largest(),16) - src.sizeplay_size=newsize - else - //src.transform=get_matrix_norm() - //src.pixel_y=0 - stable_matrix(get_matrix_norm(),0) - src.sizeplay_size=SIZEPLAY_NORMAL - // src.updateappearance - sizeplay_shrink() - //if(!istype(src,/mob/living/carbon)) - // return - if(sizeplay_size>SIZEPLAY_TINY) - src.sizeplay_set(sizeplay_size-1) - for(var/mob/living/M in src.stomach_contents) - M.sizeplay_shrink() - sizeplay_grow() - //if(!istype(src,/mob/living/carbon)) - // return - if(sizeplay_size2) - crumple() - else - ticks_away=0 - - if(stat == DEAD) - if(next) - next.previous=null - next=null - - //move bulges and digest procs here - - update_icon() - - return - - //Delete() - // if(previous) - // previous.Detach() - // ..() - - Move() - var/attachementNextPosition = loc - if(..()) - if(previous) - previous.Move(attachementNextPosition) - update_icon() - - proc/crumple(var/humhead=0) - if(!humhead) - loc=next.loc - if(previous) - previous.crumple() - - proc/update_icon() - //if(stat == CONSCIOUS || stat == UNCONSCIOUS) - if(!istype(loc,/turf/))return - if(!next&&!previous) - icon_state="tailSEVERED" - return - var/next_d=0 - if(next&&next.loc!=src.loc) - next_d=get_dir(src,next) - if(previous) - var/prev_d=0 - if(previous.loc!=src.loc) - prev_d=get_dir(src,previous) - if(next_d==prev_d) - icon_state="tail0-[prev_d]" - else if(prev_dDEBUG: Deleted an old vore panel with a tab of [VP.current_tab]." - //VP.loop=0 - return - -/obj/vore_preferences - - proc/GetOrgan(var/organ) - switch(organ) - if("cock") - return target.vore_cock_datum - if("balls") - return target.vore_balls_datum - if("womb") - return target.vore_womb_datum - if("breast") - return target.vore_breast_datum - if("tail") - return target.vore_tail_datum - if("insole") - return target.vore_insole_datum - if("insuit") - return target.vore_insuit_datum - else - return target.vore_stomach_datum - - proc/GenerateMethodSwitcher(var/method,var/alt_name) - var/dat="" - dat += "[alt_name] " - return dat - - proc/GenerateAbilitySwitcher(var/method,var/alt_name) - var/dat="" - dat += "[alt_name]: " - if(method!=VORE_METHOD_ORAL) - dat += AbilityHelper(method,VORE_SIZEDIFF_DISABLED,"Disable") - dat += AbilityHelper(method,VORE_SIZEDIFF_TINY,"Tiny") - dat += AbilityHelper(method,VORE_SIZEDIFF_SMALLER,"Smaller") - dat += AbilityHelper(method,VORE_SIZEDIFF_SAMESIZE,"Same-Size") - dat += AbilityHelper(method,VORE_SIZEDIFF_DOUBLE,"Bigger") - if(target.vore_ability[num2text(VORE_METHOD_ORAL)]==VORE_SIZEDIFF_ANY) - dat += AbilityHelper(method,VORE_SIZEDIFF_ANY,"Any") - dat += "
" - return dat - - proc/AbilityHelper(var/method,var/size,var/alt_name) - var/dat="" - if(method==VORE_METHOD_ORAL||size<=target.vore_ability[num2text(VORE_METHOD_ORAL)]) - dat += "[alt_name] " - return dat - - proc/GenerateBanSwitcher(var/method,var/alt_name) - var/dat="" - dat += "[target.vore_banned_methods&method ? "" : ""][alt_name][target.vore_banned_methods&method ? "" : ""] " - return dat - - proc/GenerateExBanSwitcher(var/method,var/alt_name) - var/dat="" - dat += "[target.vore_extra_bans&method ? "" : ""][alt_name][target.vore_extra_bans&method ? "" : ""] " - return dat - - proc/GenerateDigestionSwitcher(var/organ) - var/dat="" - var/datum/vore_organ/VD=GetOrgan(organ) - var/datum/vore_organ/temp_chk=GetOrgan("stomach") - dat += "Digestion: " - if(temp_chk.factor_offset<0)dat += " 0 ? "class='linkOn'" : ""]>Heal " - if(temp_chk.factor_offset<1)dat += "None " - dat += "Slow " - if(temp_chk.factor_offset>-1)dat += "Normal " - if(temp_chk.factor_offset>0)dat += "Fast " - dat += "
" - return dat - - proc/GenerateRelease(var/organ) - var/dat="" - var/datum/vore_organ/VD=GetOrgan(organ) - dat += "You will [VD.escape ? "" : "not "]let people escape. " - dat += "Release" - if(organ=="stomach") - dat += "Fulltour" - if(organ=="cock"||organ=="breast"||organ=="womb") - dat += "Into" - dat+="
" - return dat - - - proc/ShowChoices(mob/user) - loop=src - if(!user || !user.client) return - - if(!target) return //the =="kingpygmy" was alerting me to this. - - var/dat = "
" - - if(istype(target,/datum/preferences)) - if(current_tab<2||current_tab>3) - if(current_tab!=8) - current_tab=2 - dat += "\[Ability\] " - dat += "\[Bans\] " - dat += "\[Other\]" - else - dat += "\[Manage\] " - //if(target.get_last_organ_in()) - dat += "\[Inside\] " - dat += "\[Ability\] " - dat += "\[Bans\] " - dat += "\[Other\]" - if(target.ckey=="jayehh") - dat += " \[Debug\]" - - dat += "
" - - - switch(current_tab) - if (0) //Manage Organs - - dat += "
" - dat += "

Current Vore Method

" - dat += GenerateMethodSwitcher(VORE_METHOD_ORAL,"Oral") - dat += GenerateMethodSwitcher(VORE_METHOD_ANAL,"Anal") - dat += GenerateMethodSwitcher(VORE_METHOD_COCK,"Cock") - dat += GenerateMethodSwitcher(VORE_METHOD_UNBIRTH,"Unbirth") - dat += GenerateMethodSwitcher(VORE_METHOD_BREAST,"Breast") - dat += GenerateMethodSwitcher(VORE_METHOD_TAIL,"Tail") - dat += "
" - dat += GenerateMethodSwitcher(VORE_METHOD_INSOLE,"Insole") - dat += GenerateMethodSwitcher(VORE_METHOD_INSUIT,"In Suit") - dat += "(These two aren't vore)" - dat += "
" - dat += "On clicking self, [target.vore_mode==VORE_MODE_EAT ? "eat" : "feed"] the grabbed person" - dat += "[target.vore_head_first ? "head-first" : "feet-first"]." - if(!target.vore_head_first) - dat+="
(Foot-first not currently not finsihed. Only works when you are the one eating prey.)" - - dat += "

" - dat += "Remains:" - dat += " None" - dat += " Generic" - dat += " Named" - - dat += "

Stomach

" - dat += GenerateDigestionSwitcher("stomach") - dat += GenerateRelease("stomach") - - if(target.has_vagina()) - dat += "

Womb

" - dat += GenerateDigestionSwitcher("womb") - dat += "Transformation: Set[target.vore_womb_datum.tf_factor ? "(On)" : ""]
" - dat += GenerateRelease("womb") - - if(target.has_cock()) - dat += "

Cock

" - dat += GenerateDigestionSwitcher("cock") - dat += "Balls " - dat += GenerateDigestionSwitcher("balls") - dat += "Cock Transformation: Set[target.vore_cock_datum.tf_factor ? "(On)" : ""]
" - dat += "Balls Transformation: Set[target.vore_balls_datum.tf_factor ? "(On)" : ""]
" - dat += "Move to balls: " - dat += "No " - dat += "Yes " - dat += "
" - dat += GenerateRelease("cock") - - if(target.has_boobs()) - dat += "

Breast

" - dat += GenerateDigestionSwitcher("breast") - dat += GenerateRelease("breast") - - if(target.kpcode_mob_has_tail()) - dat += "

Tail

" - dat += GenerateDigestionSwitcher("tail") - dat += "Move to stomach: " - dat += "No " - dat += "Yes " - dat += "
" - dat += GenerateRelease("tail") - else if(target.vore_tail_datum.contents.len) - target.vore_tail_datum.release() - - dat += "

Inside your Suit

" - dat += "Unzip your suit" - - if (1) //Inside View - - dat += "
" - var/datum/vore_organ/container=target.get_last_organ_in() - if(!container) - dat += "You are not currently inside someone." - else if(istype(container,/datum/vore_organ/stomach)) - dat += "You are in [container.owner]'s stomach. It is soft, wet, and moving.The walls gently squeeze around you from all sides as their heartbeat and breathing echo in your ears. The gurgles of their digestive system rumble all around you." - if(container.digestion_factor==VORE_DIGESTION_SPEED_SLOW) - dat += "You feel a slight, burning tingle on your skin.The walls work at kneading over your form to soften you up. You're being digested! " - else if(container.digestion_factor) - dat += "Your body is quickly digesting and the air is getting more and more thin after that belch! You won't last long! " - if(container.has_people()>1) - dat += "You can feel [container.has_people()-1] other [container.has_people()>2 ? "people" : "person"] in the stomach. " - else if(istype(container,/datum/vore_organ/cock)||istype(container,/datum/vore_organ/balls)) - dat += "You are in [container.owner]'s [istype(container,/datum/vore_organ/cock) ? "cock" : "balls"]. " - if(container.digestion_factor==VORE_DIGESTION_SPEED_SLOW) - dat += "You feel a slight, burning tingle on your skin. You're being melted! " - else if(container.digestion_factor) - dat += "Your body is quickly turning into [container.owner] [pick("spooge","cum","semen","batter","seed")] and the air is scarce. You won't last long! " - if(container.has_people()>1) - dat += "You can feel [container.has_people()-1] other [container.has_people()>2 ? "people" : "person"] in your cum-drenched and musky prison. Their forms press up close to your own. " - if(container.digestion_count) - dat += "It seems the cum was once a person or thing... or maybe even multiple? " - else if(istype(container,/datum/vore_organ/womb)) - dat += "You are in [container.owner]'s womb. The smooth walls press over you, suspending you in a feeling of almost zero gravity. Their heartbeat and breathing is quieter here, and the gurgles of their digestive system join the internal song." - if(container.digestion_factor==VORE_DIGESTION_SPEED_SLOW||container.tf_factor) - dat += "You feel a slight, odd tingle on your skin. The warmth should make you doze off soon enough. " - else if(container.digestion_factor) - dat += "Your body is quickly digesting within [container.owner]'s womb, the air is thin and you're already having trouble staying awake " - if(container.has_people()>1) - dat += "You can feel [container.has_people()-1] other [container.has_people()>2 ? "people" : "person"] in your fleshy prison. " - else if(istype(container,/datum/vore_organ/breast)) - dat += "You are in [container.owner]'s breast. " - if(container.digestion_factor) - dat += "Your body is getting rather milky, you're being melted inside these breasts! " - if(container.has_people()>1) - dat += "You can feel [container.has_people()-1] other [container.has_people()>2 ? "people" : "person"] in your jiggly prison. " - else if(istype(container,/datum/vore_organ/tail)) - dat += "You are in [container.owner]'s tail. Each shift of their hips causes your world to move about ever so much. " - if(container.digestion_factor==VORE_DIGESTION_SPEED_SLOW) - dat += "You feel a slight, burning tingle on your skin. The swaying is luring you to just close your eyes and give in. " - else if(container.digestion_factor) - dat += "Your body is quickly digesting as a lump inside [container.owner]'s tail. The air is thin and you won't last much longer! " - if(container.has_people()>1) - dat += "You can feel [container.has_people()-1] other [container.has_people()>2 ? "people" : "person"] in your fleshy prison. " - if(container.transfer_factor) - dat += "The tail's muscles are sliding you somewhere deeper inside of your predator, you can already feel parts of you being squeezed into the wrinkled folds of that stomach." - else if(istype(container,/datum/vore_organ/insole)) - dat += "You are pressed against [container.owner]'s foot. Each step they take presses over your form. " - else if(istype(container,/datum/vore_organ/insuit)) - dat += "You are pressed against [container.owner]'s form. It is very stuffy, and their scent is all around you. " - else - dat += "You're not sure where you are. " - dat += "
" - dat += "
" - var/datum/vore_organ/orgch - orgch=GetOrgan("stomach") - if(orgch.has_people()) - dat += "Your [orgch.digestion_factor ? "gurgly " : ""]stomach [pick("bulges","swells","is distended")] with [orgch.has_people()] [orgch.has_people()>1 ? "people" : "person"]. " - dat += "
" - orgch=GetOrgan("womb") - if(orgch.has_people()) - dat += "You have [orgch.digestion_factor ? "kneading " : ""] womb [pick("bulges","swells","is distended")] with [orgch.has_people()] [orgch.has_people()>1 ? "people" : "person"] withing your lower belly. Their weight is liable to be a pleasent addition to your hips. " - dat += "
" - orgch=GetOrgan("cock") - if(orgch.has_people()||orgch.digestion_count) - dat += "Your cock swells with [orgch.has_people()+orgch.digestion_count] [orgch.has_people()+orgch.digestion_count>1 ? "people" : "person"]. " - if(orgch.digestion_count) - dat += "Not that they're not [pick("spooge","batter","seed")] by now. " - dat += "
" - orgch=GetOrgan("balls") - if(orgch.has_people()||orgch.digestion_count) - dat += "Your balls swell with [orgch.has_people()+orgch.digestion_count] [orgch.has_people()+orgch.digestion_count>1 ? "people" : "person"]. " - if(orgch.digestion_count) - dat += "Not that they're not [pick("spooge","batter","seed")] by now. " - dat += "
" - orgch=GetOrgan("breast") - if(orgch.has_people()||orgch.digestion_count) - dat += "Your breasts swell with [orgch.has_people()+orgch.digestion_count] [orgch.has_people()+orgch.digestion_count>1 ? "people" : "person"]. " - if(orgch.digestion_count) - dat += "They may just be milk, though. " - dat += "
" - orgch=GetOrgan("tail") - if(orgch.has_people()) - dat += "Your tail has a wriggly lump[orgch.has_people()>1 ? "s" : ""] within it[orgch.transfer_factor ? " that slowly moves toward the base of it, your stomach will swell out soon" : ""]. " - dat += "
" - orgch=GetOrgan("insole") - if(orgch.has_people()) - dat += "Your insole[orgch.has_people()>1 ? "s" : ""] fit[orgch.has_people()>1 ? "" : "s"] snugly against your [orgch.has_people()>1 ? "feet" : "foot"]. Each step you make is pressing against them. " - dat += "
" - orgch=GetOrgan("insuit") - if(orgch.has_people()) - dat += "[orgch.has_people()>1 ? "Smaller people" : "A smaller person"] squirm[orgch.has_people()>1 ? "" : "s"] in your clothes, against your form." - dat += "
" - - if (2) //Vore Abilities - - target.vore_ability=sanitize_vore_list(target.vore_ability) - dat += "
" - dat += " Select what size difference you can vore at. As a failsafe, alternative vore can not be raised past oral. To change alternative vores to go higher, please adjust oral.
" - dat += GenerateAbilitySwitcher(VORE_METHOD_ORAL,"Oral") - dat += GenerateAbilitySwitcher(VORE_METHOD_ANAL,"Anal") - dat += GenerateAbilitySwitcher(VORE_METHOD_COCK,"Cock") - dat += GenerateAbilitySwitcher(VORE_METHOD_UNBIRTH,"Unbirth") - dat += GenerateAbilitySwitcher(VORE_METHOD_BREAST,"Breast") - if(istype(target,/datum/preferences)||target.kpcode_mob_has_tail()) - dat += GenerateAbilitySwitcher(VORE_METHOD_TAIL,"Tail") - - if(istype(target,/datum/preferences)) - var/datum/preferences/PD=target - dat += "
" - dat += "

Sex Organs

" - dat += "Cock: " - var/youhavea="no" - switch(PD.p_cock["has"]) - if(1) - youhavea="one" - if(2) - youhavea="a huge" - if(3) - youhavea="two" - - dat += "You have [youhavea] cock[youhavea=="two" ? "s" : ""]." - dat += "
Type: [PD.p_cock["type"]]" - dat += "
Colour:     " - dat += "(Change)
" - dat += "Vagina: " - dat += "You [PD.p_vagina ? "have" : "don't have"] one.
" - //dat += "
Show extra info when examining others? " - //dat += "[PD.show_gen ? "Yes" : "No"]
" - - - if (3) //Vore Bans - - dat += "
" - dat += " Click a method to ban it. Banned methods will appear in bold. When banned, you cannot be eaten with this vore type.
" - //dat += GenerateBanSwitcher(VORE_METHOD_ORAL,"Oral") Doesn't work yet - dat += GenerateBanSwitcher(VORE_METHOD_COCK,"Cock") - dat += GenerateBanSwitcher(VORE_METHOD_ANAL,"Anal") - dat += GenerateBanSwitcher(VORE_METHOD_UNBIRTH,"Unbirth") - dat += GenerateBanSwitcher(VORE_METHOD_BREAST,"Breast") - dat += GenerateBanSwitcher(VORE_METHOD_TAIL,"Tail") - dat += "
" - dat += GenerateBanSwitcher(VORE_METHOD_INSOLE,"Insole") - dat += GenerateBanSwitcher(VORE_METHOD_INSUIT,"In Suit") - dat += "
" - dat += " These ones involve release. If you are digested while one of these bans are enabled, the predator will have to use a non-banned release to use the banned method again.
" - dat += GenerateExBanSwitcher(VORE_EXTRA_FULLTOUR,"Fulltour") - dat += GenerateExBanSwitcher(VORE_EXTRA_REMAINS,"Remains") - - if (4) //Debug?! - - // dat += "
" - // if(target.ckey=="jayehh"|| "poojawa"|| "nebulacallisto"|| "leonleonardo"|| "brimcon"|| "cyrema"|| "mrsebbi"|| "subtumaka") - // dat += "

Debug Options

" - // dat += "Vore Log: Check" - // dat += "
Observe Log: Check" - // dat += "
Whitelist: Check" - // //dat += "
World Log: Check" - // dat += "
Size: " - // dat += "Grow" - // dat += "Shrink" - // dat += "
Taur: " - // dat += "Toggle" - // //dat += "
Naga: " - // //dat += "On" - // dat += "
Spawn: " - // //dat += "Narky Gear" - // dat += "Shrink Ray" - // dat += "Growth Ray" - - // if (5) //Log menu. Logically, if Poojawa bastardizes enough code, it'll work, right? - - // dat += "
" - // if(target.ckey=="jayehh"|| "poojawa"|| "nebulacallisto"|| "leonleonardo"|| "brimcon"|| "cyrema"|| "mrsebbi"|| "subtumaka") - // switch(tab_mod) - // if("observe") - // dat += "

Observe Log

" - // dat += global_observe_log - //if("world") - // dat += "

World Log

" - // if("whitelist") - // dat += "

Whitelist

" - // for(var/txt in whitelist_keys) - // dat+="[txt]
" - // else - // dat += "

Vore Log

" - // dat += global_vore_log - - if (6) //Transformation menu. - dat += "
" - dat += "

Transformation Menu

" - var/datum/vore_organ/VO=GetOrgan(tab_mod) - dat += "Transformation for [tab_mod]: Set[VO.tf_factor ? "(On)" : ""]
" - dat += "Work in progress. This button will be replaced with a full menu here." - - if (7) //Transfer menu. - dat += BuildTransfer() - - if (8) //Donate menu - dat += "
" - dat += "

Whitelist

" - dat += "Due to issues with griefers, we have whitelisted a few features. This is only to prevent one-shot griefing, and the list will not be difficult to get into." - dat += "
Status: " - if(is_whitelisted(target.ckey)) - dat +="You are whitelisted. You will be able to respawn and play as head roles." - else - dat +="You are not whitelisted. You will not be able to use head roles while the head whitelisting is toggled on. To become whitelisted, keep playing until we know you're not around just to cause trouble. You can also have someone trusted vouch for you." - dat += "

Donations

" - dat += "In order to keep the server running, payment is required monthly. It is greatly appreciated for even the smallest amount of donations. Without them, it becomes difficult to keep the server afloat." - dat += "By donating you can prevent this issue and allow it to continue running. As well as helping out the server, your name will be added to the donator list and you will be priority in having suggestions, ideas, and certain cosmetics added for personal use." - dat += "
" - dat += {" -
- - - - -
- - - - "} - - - var/datum/browser/popup = new(user, "voreprefs", "
Vore Panel
", 0, 0, src) - popup.set_content(dat) - popup.open(0) - - Topic(href, href_list) - if(..()) - return - if(istype(target,/mob) && usr!=target) - usr<<"They are not you." - return - if(href_list["preference"] == "tab") - current_tab=text2num(href_list["tab"]) - if(href_list["mod"]) - tab_mod=href_list["mod"] - - if(href_list["preference"] == "current") - target.vore_current_method = text2num(href_list["method"]) - - if(href_list["preference"] == "click") - target.vore_mode = text2num(href_list["mode"]) - - if(href_list["preference"] == "headfirst") - target.vore_head_first = text2num(href_list["mode"]) - - if(href_list["preference"] == "ability") - target.vore_ability[href_list["method"]] = text2num(href_list["size"]) - if(text2num(href_list["method"])==VORE_METHOD_ORAL) - var/list/check_methods=list(VORE_METHOD_ANAL,VORE_METHOD_COCK,VORE_METHOD_UNBIRTH,VORE_METHOD_BREAST,VORE_METHOD_TAIL) - for(var/N in check_methods) - if(target.vore_ability[num2text(N)]>text2num(href_list["size"])) - target.vore_ability[num2text(N)]=text2num(href_list["size"]) - - - if(href_list["preference"] == "ban") - var/method=text2num(href_list["method"]) - if(target.vore_banned_methods&method) - target.vore_banned_methods &= ~method - else - target.vore_banned_methods |= method - - if(href_list["preference"] == "exban") - var/method=text2num(href_list["method"]) - if(target.vore_extra_bans&method) - target.vore_extra_bans &= ~method - else - target.vore_extra_bans |= method - - if(href_list["preference"] == "digest") - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - var/set_speed=text2num(href_list["speed"]) - if(target.reagents) - if(target.reagents.has_reagent("noantacid")&&set_speedVD.digestion_factor) - target << "It's not working!" - return - VD.digestion_factor = set_speed - VD.healing_factor = 0 - VD.tf_factor = 0 - if(VD.has_people()) - vore_admins("[VD.owner]'s [VD.type] digestion changed to [VD.digestion_factor].",VD.owner) - - if(href_list["preference"] == "digest_h") - if(target.reagents) - if(target.reagents.has_reagent("antacid")||target.reagents.has_reagent("noantacid")) - target << "You can't control your ability to heal." - return - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - VD.digestion_factor = 0 - VD.healing_factor = 1 - VD.tf_factor = 0 - if(VD.has_people()) - vore_admins("[VD.owner]'s [VD.type] set to heal.",VD.owner) - - if(href_list["preference"] == "release") - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - if(href_list["extra_info"]) - VD.release(extra_info=text2num(href_list["extra_info"])) - else - VD.release() - - if(href_list["preference"] == "set_remains") - target.vore_remains_mode=text2num(href_list["mode"]) - - if(href_list["preference"] == "dispense") - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - VD.dispense(text2num(href_list["amount"]),href_list["name"]) - - if(href_list["preference"] == "trap") - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - VD.escape=text2num(href_list["keep"]) - if(href_list["organ"]=="cock") - VD=GetOrgan("balls") - VD.escape=text2num(href_list["keep"]) - - if(href_list["preference"] == "transfer") - var/datum/vore_organ/VD=GetOrgan(href_list["organ"]) - VD.transfer_factor = text2num(href_list["speed"]) - VD.transfer_target = GetOrgan(href_list["dest"]) - - if(href_list["preference"] == "transform") - target.set_vore_transform(GetOrgan(href_list["organ"])) - //vore_admins("[VD.owner]'s [VD.type] set to transform.",VD.owner) - - if(href_list["preference"] == "cock") - var/datum/preferences/PD=target - switch(href_list["change"]) - if("has") - var/change_val=input(usr, "Choose your cock:", "Character Preference") as null|anything in list("None","Normal","Hyper","Double") - switch(change_val) - if("None") - PD.p_cock["has"]=0 - if("Normal") - PD.p_cock["has"]=1 - if("Hyper") - PD.p_cock["has"]=2 - if("Double") - PD.p_cock["has"]=3 - - if("type") - var/change_val=input(usr, "Choose your cock type:", "Character Preference") as null|anything in cock_list+"custom" - if(change_val=="custom") - change_val=input(usr, "Choose your cock type:", "Character Preference") as text - if(change_val) - PD.p_cock["type"]=change_val - if("color") - var/new_color = input(usr, "Choose your cock's colour:", "Character Preference") as null|color - if(new_color) - PD.p_cock["color"] = sanitize_hexcolor(new_color) - - if(href_list["preference"] == "vagina") - var/datum/preferences/PD=target - PD.p_vagina=!PD.p_vagina - - //if(href_list["preference"] == "showgen") - //var/datum/preferences/PD=target - //PD.show_gen=!PD.show_gen - - if(href_list["preference"] == "grow") - target.sizeplay_grow() - - if(href_list["preference"] == "shrink") - target.sizeplay_shrink() - - if(href_list["preference"] == "taur") - if(target.has_dna()) - var/mob/living/carbon/C=target - C.dna.taur=!C.dna.taur - // updateappearance - else - target<<"Not going to work." - - /*if(href_list["preference"] == "naga") - if(check_dna_integrity(target)) - var/seg_cnt=input("How many segments?", "Naga Time!", "6") - seg_cnt=text2num(seg_cnt) - if(!seg_cnt) - target<<"Invalid." - else - var/mob/living/carbon/C=target - C.dna.naga=new/mob/living/simple_animal/naga_segment/main(target.loc,seg_cnt) - target.pixel_y=8 - else - target<<"Not going to work."*/ - - /*if(href_list["preference"] == "spawn") - if(href_list["item"] == "narky") - new /obj/item/clothing/suit/narkycuff(target.loc) - new /obj/item/clothing/shoes/narkyanklet(target.loc) - new /obj/item/clothing/under/maid/narky(target.loc) - if(href_list["item"] == "grow") - new /obj/item/weapon/gun/energy/laser/sizeray/two(target.loc) - if(href_list["item"] == "shrink") - new /obj/item/weapon/gun/energy/laser/sizeray/one(target.loc)*/ - - - if(usr) - ShowChoices(usr) - - - - - -//datum/mind/var/vore_admins="" -//var/global_vore_log="" -//proc/vore_admins(var/T,var/mob/living/pred=null,var/mob/living/prey=null) -// global_vore_log+="-"+T+"
" -// if(pred&&pred.mind) -// pred.mind.vore_admins+="-"+T+"\n" -// if(prey&&prey.mind) -// prey.mind.vore_admins+="-"+T+"\n" -//var/global_observe_log="" -//proc/kp_log_observe(var/T) -// global_observe_log+="-"+T+"
" - -/proc/vore_admins(var/msg) - msg = "ADMIN LOG: [msg]" - admins << msg - - -proc/sanitize_vore_list(var/list/lst=null) - if(!lst||!lst.len) - lst=list( - "1"=2, - "2"=0, - "4"=0, - "8"=0, - "16"=0, - "32"=0, - "64"=1, - "128"=0, - "256"=2) - lst[num2text(VORE_METHOD_INSOLE)]=1 - lst[num2text(VORE_METHOD_INSUIT)]=2 - return lst diff --git a/code/citadel/races.dm b/code/citadel/races.dm deleted file mode 100644 index f70da17210..0000000000 --- a/code/citadel/races.dm +++ /dev/null @@ -1,795 +0,0 @@ -datum - species - //specflags = list(EYECOLOR,HAIR,FACEHAIR,LIPS) - var/generic="something" - var/adjective="unknown" - var/restricted=0 //Set to 1 to not allow anyone to choose it, 2 to hide it from the DNA scanner, and text to restrict it to one person - var/tail=0 - var/taur=0 - human - generic="human" - adjective="ordinary" - taur="horse" - abductor - //name="abductor" - id="abductor" - generic="abductor" - adjective="spooky" - restricted=2 - ailurus - //name="red panda" - id="ailurus" - generic="ailurus" - adjective="cuddly" - tail=1 - restricted=2 - alien - //name="alien" - id="alien" - say_mod="hisses" - generic="xeno" - adjective="phallic" - tail=1 - restricted=2 - armadillo - //name="armadillo" - id="armadillo" - say_mod = "drawls" - generic = "cingulate" // Superorder Xenarthra, Order Cingulata - adjective = "protected" - tail=1 - attack_verb = "noms" - attack_sound = 'sound/weapons/bite.ogg' - attack_verb = "nom" // apparently attack verbs are just the verb, no S. shrug - attack_sound = 'sound/weapons/bite.ogg' - restricted=2 - anubis - //name="anubis" - id="anubis" - say_mod = "intones" - generic="jackal" // mmm...jackal or canine? i'll leave it for now - adjective="cold" - attack_verb = "claw" - restricted=2 - beaver - //name="beaver" - id="beaver" - say_mod = "chitters" - generic="rodent" - adjective="damnable" - tail=1 - attack_verb = "tailslap" - attack_sound = 'sound/items/dodgeball.ogg' - restricted=2 - beholder - //name="beholder" - id="beholder" - say_mod = "jibbers" - generic="body part" - adjective="all-seeing" - tail=0 - attack_verb = "visually assault" - attack_sound = 'sound/magic/MM_Hit.ogg' // MAGIC MISSILE! MAGIC MISSILE! - restricted=2 - boar - //name="boar" - id="boar" - generic="pig" - adjective="wild and curly" - tail=1 - restricted=2 - capra - //name="caprine" - id="capra" - generic="goat" - adjective="irritable" - restricted=2 - carp - //name="carp" - id="carp" - say_mod = "glubs" - generic = "abomination" - adjective = "violently fishy" - tail=1 - eyes = "carpeyes" - attack_verb = "nom" - attack_sound = 'sound/weapons/bite.ogg' - restricted=2 - corgi - //name="corgi" - id="corgi" - say_mod ="yaps" - generic="canine" - adjective="corgalicious" - tail=1 - restricted=2 - corvid - //name="corvid" - id="corvid" - say_mod = "caws" - generic="bird" - adjective="mask-piercing" - tail=1 - attack_verb = "whack" - restricted=2 - cow - //name="cow" - id="cow" - say_mod = "moos" - generic="bovine" - adjective="wise" - tail=1 - taur=1 - restricted=2 - coyote - //name="coyote" - id="coyote" - say_mod = "yips" - generic="canine" - adjective="mangy" - tail=1 - restricted=2 - crocodile - //name="crocodile" - id="croc" - generic="water reptile" - adjective="scaled" - tail=1 - restricted=2 - dalmatian - //name="dalmatian" - id="dalmatian" - say_mod = "ruffs" - generic="canine" - adjective="spotty" - tail=1 - restricted=2 - deer - //name="deer" - id="deer" - say_mod = "grunts" - generic = "cervid" - adjective = "skittish" - tail=1 // that's better - attack_verb = "gore" - attack_sound = 'sound/weapons/bladeslice.ogg' - restricted=2 - drake - //name="drake" - id="drake" - say_mod = "growls" - generic = "reptile" - adjective = "frilly" - tail=1 // i'd use lizard tails but drakes have frills included on the icons - taur=1 - restricted=2 - drider - //name="drider" - id="drider" - generic="humanoid" - adjective="big and hairy" - taur=1 - tail=1 - eyes="spidereyes" - restricted=2 - fennec - //name="fennec" - id="fennec" - generic="vulpine" - adjective="foxy" - tail=1 - restricted=2 - fox - name="fox" - id="fox" - generic="vulpine" - adjective="foxy" // open and shut with this one, huh - tail=1 - taur=1 - glowfen - //name="glowfen" - id="glowfen" - generic="vulpine" - adjective="glowing" - tail=1 - restricted=2 - gremlin - //name="gremlin" - id="gremlin" - generic="creature" - tail=1 - attack_verb = "thwack" - restricted=2 - gria - //name="gria" - id="gria" - generic="reptile" - adjective="scaled" - tail=1 - attack_verb = "claw" - attack_sound = 'sound/weapons/bladeslice.ogg' - restricted=2 - hawk - //name="hawk" - id="hawk" - say_mod = "chirps" - generic="bird" - adjective="feathery" - tail=1 - attack_verb = "whack" - restricted=2 - hippo - //name="hippo" - id="hippo" - generic="hippo" - adjective="buoyant" - tail=1 - restricted=2 - husky - name="husky" - id="husky" - say_mod = "arfs" - generic="canine" - adjective="derpy" - tail=1 - taur=1 - jackalope - //name="jackalope" - id="jackalope" - generic="leporid" - adjective="hoppy and horny" //hue - attack_verb = "kick" - tail=1 - restricted=2 - jelly - //name="jelly" - id="jelly" - generic="jelly" - adjective="jelly" - kangaroo - //name="kangaroo" - id="kangaroo" - generic="marsupial" - adjective="bouncy" - tail=1 - attack_verb = "kick" - restricted=2 - lab - //name="lab" - id="lab" - say_mod = "yaps" - generic="canine" - adjective="sleek" - tail=1 - taur=1 - restricted=2 - leporid - //name="leporid" - id="leporid" - generic="leporid" - adjective="hoppy" - tail=1 - attack_verb = "kick" - restricted=2 - lizard - name="lizard" - id="lizard" - generic="reptile" - adjective="scaled" - taur="naga" - tail=1 - murid // i have no idea what this is - //name="murid" - id="murid" - say_mod = "squeaks" - generic="rodent" - adjective="squeaky" - tail=1 - restricted=2 - moth - //name="moth" - id="moth" - generic="insect" - adjective="fluttery" - eyes="motheyes" // this SHOULD work after i've updated human_face.dmi -- iska - restricted=2 - mushman - //name="mushroom" - id="fung" - generic="fungi" - adjective="sporey" - say_mod = "mushes" - tail=0 - restricted=2 - naga - //name="naga" - id="naga" - generic="humanoid" - adjective="noodly" - taur=1 - tail=1 - restricted=2 - otter - //name="otter" - id="otter" - say_mod = "squeaks" - generic="mustelid" - adjective="slim" - tail=1 - restricted=2 - otusian - //name="otusian" - id="otie" - say_mod ="growls" - generic="feline-canine" - adjective="chunky" // ??? are otusians fat???? - tail=1 - taur=1 - restricted=2 - panther - //name="panther" - id="panther" - generic="feline" - adjective="furry" - tail=1 - taur=1 - attack_verb = "claw" - attack_sound = 'sound/weapons/bladeslice.ogg' - restricted=2 - pig - //name="pig" - id="pig" - generic="pig" - adjective="curly" - tail=1 - restricted=2 - plant - generic="plant" - adjective="leafy" - restricted=2 - plant/pod - restricted=1 - porcupine - //name="porcupine" - id="porcupine" - say_mod = "snuffles" - generic = "rodent" - adjective = "quilly" - tail=1 - attack_verb = "quill-whack" - attack_sound = 'sound/weapons/slash.ogg' - restricted=2 - possum - //name="possum" - id="possum" - say_mod = "chitters" - generic = "marsupial" - adjective = "rumaging" - tail=1 - attack_verb = "nom" - attack_sound = 'sound/weapons/bite.ogg' - restricted=2 - raccoon - //name="raccoon" - id="raccoon" - say_mod="churrs" - generic="procyonid" // Family Procyonidae - adjective="stripy" - tail=1 - restricted=2 - roorat - //name="kangaroo rat" - id="roorat" - generic="Heteromyidae" // ...marsupial rat? Have you tried a google search? They're a real thing. - adjective="bouncy" - tail=1 - attack_verb = "kick" - restricted=2 - saltman - //name="salt" - id="salt" - generic="NaCl" - adjective="salty" - restricted=2 - restricted=2 - seaslug - //name="sea slug" - id="seaslug" - generic="slug" - adjective="salty" - tail=1 - attack_verb = "smack" - restricted=2 - shark - //name="shark" - id="shark" - generic="selachimorph" // Superorder Selachimorpha - adjective="fishy" - tail=1 - restricted=2 - shepherd - //name="shepherd" - id="shepherd" - say_mod = "barks" - generic="canine" - adjective="happy" - tail=1 - taur=1 - restricted=2 - skunk - //name="skunk" - id="skunk" - say_mod = "snuffles" - generic="mephit" - adjective="stinky" - tail=1 - restricted=2 - slime - //name="slime" - id="slime" - generic="slime" - adjective="slimy" - restricted=2 - smilodon - //name="smilodon" - id="smilodon" - generic="smilodon" - adjective="toothy" - tail=1 - restricted=2 - snarby - //name="snarby" - id="snarby" - generic="beast" - adjective="snippy and snarly" - tail=1 - attack_verb = "chomp" - attack_sound = 'sound/weapons/bite.ogg' - eyes = "snarbyeyes" - restricted=2 - squirrel - //name="squirrel" - id="squirrel" - generic="rodent" - adjective="nutty" - tail=1 - restricted=2 - tajaran - name="tajaran" - id="tajaran" - generic="feline" - adjective="furry" - tail=1 - taur=1 - attack_verb = "claw" - attack_sound = 'sound/weapons/bladeslice.ogg' - toucan - name="toucan" - id="toucan" - generic="bird" - adjective="colorful" - tail=1 - attack_verb = "pecks" - /* turtle - //name="turtle" - id="turtle" - generic="reptile" - adjective="hard-shelled" - tail=1 - ursine - //name="bear" - id="ursine" - generic="ursine" - adjective="husky" - say_mod = "grunts" - tail=1 - attack_verb = "claw" - attack_sound = 'sound/weapons/bladeslice.ogg' - wolf - //name="wolf" - id="wolf" - say_mod = "howls" - generic="canine" - adjective="shaggy" - tail=1 - taur=1 - zig - //name="zig" - id="zig" - generic="pokémon" - adjective="curious" - tail=1 */ - - -/* - narky - //name="narwhal kitty" - id="narky" - say_mod="nyars" - generic="abomination" - adjective="fluffy" - restricted=2 - tail=1 - taur=1 - attack_verb = "whack" - - //husky/jordy // obsolete with the addition of overlay sprites - //name="husky" - //id="jordy" - //generic="canine" - //adjective="hyper" - //tail=1 - //restricted=1 -*/ - fly - //name="fly" - generic="insect" - adjective="buzzy" - restricted=1 - skeleton - //name="skeleton" - generic="human" - adjective="very boney" - restricted=2 - attack_verb = "bone" - cosmetic_skeleton - //name="skeleton" - generic="skeleton" - adjective="boney" - restricted=2 - attack_verb = "bone" - shadow - //name="shadow" - generic="darkness" - adjective="shady" // Jokes - restricted=2 - golem - //name="golem" - generic="golem" - adjective="rocky" - restricted=2 - golem/adamantine - //name="adamantine" - generic="golem" - adjective="rocky" - restricted=2 - zombie - //name = "High Functioning Zombie" - id="zombie" - say_mod="moans" - restricted=2 - plasmaman - //name="Plasmabone" - id="plasmaman" - generic="plasmaman" - adjective="toxic" - restricted=2 // don't comment these out if you don't want the world to burn - plasmaman/skin - //name="Skinbone" - id="plasmaman" - generic="plasmaman" - adjective="toxic" - restricted=2 // but if you do want the world to burn then please, by all means - pepsiman - //name="PEPSI MAAAAAN" - id="PEPSIMAAAN" - generic="beverage" - adjective="refreshing" - restricted=2 // don't want half the station to be running around with soda cans on their heads - cutebold - //name="cutebold" - id="cutebold" - say_mod = "yips" - generic = "kobo" - adjective = "cute" - tail=1 - attack_verb = "nom" - attack_sound = 'sound/weapons/bite.ogg' - restricted=2 - pony // of the "my little" variety - //name="pony" - id="pony" - generic="equine" - adjective="little" - tail=1 - attack_verb= "kick" - restricted=2 - hylotl - //name="hylotl" - id="hylotl" - say_mod = "glubs" - generic="amphibian" - adjective="fishy" - tail=0 - eyes="jelleyes" - restricted=2 - synth - //name = "Synth" //inherited from the real species, for health scanners and things - id = "synth" - say_mod = "beep boops" //inherited from a user's real species - restricted=2 - synth/military - //name = "Military Synth" - id = "military_synth" - restricted=2 - corporate - //name = "Corporate Agent" - id = "agent" - restricted=2 -/* -var/list/kpcode_race_list - -proc/kpcode_race_genlist() - if(!kpcode_race_list) - var/paths = typesof(/datum/species) - kpcode_race_list = new/list() - for(var/path in paths) - var/datum/species/D = new path() - if(D.//name!="undefined") - kpcode_race_list[D.//name] = D - */ - -proc/kpcode_race_getlist(var/restrict=0) - var/list/race_options = list() - for(var/r_id in species_list) - var/datum/species/R = kpcode_race_get(r_id) - if(!R.restricted||R.restricted==restrict) - race_options[r_id]=kpcode_race_get(r_id) - return race_options - -proc/kpcode_race_get(var/name="human") - name=kpcode_race_san(name) - if(!name||name=="") name="human" - if(species_list[name]) - var/type_to_use=species_list[name] - var/datum/species/return_this=new type_to_use() - return return_this - else - return kpcode_race_get() - -proc/kpcode_race_san(var/input) - if(!input)input="human" - if(istype(input,/datum/species)) - input=input:id - return input - -proc/kpcode_race_restricted(var/name="human") - name=kpcode_race_san(name) - if(kpcode_race_get(name)) - var/datum/species/D=kpcode_race_get(name) - return D.restricted - return 2 - -proc/kpcode_race_tail(var/name="human") - name=kpcode_race_san(name) - if(kpcode_race_get(name)) - var/datum/species/D=kpcode_race_get(name) - return D.tail - return 0 - -proc/kpcode_race_taur(var/name="human") - name=kpcode_race_san(name) - if(kpcode_race_get(name)) - var/datum/species/D=kpcode_race_get(name) - if(D.taur==1) - return D.id - return D.taur - return 0 - -proc/kpcode_race_generic(var/name="human") - name=kpcode_race_san(name) - if(kpcode_race_get(name)) - var/datum/species/D=kpcode_race_get(name) - return D.generic - return 0 - -proc/kpcode_race_adjective(var/name="human") - name=kpcode_race_san(name) - if(kpcode_race_get(name)) - var/datum/species/D=kpcode_race_get(name) - return D.adjective - return 0 - -proc/kpcode_get_generic(var/mob/living/M) - if(istype(M,/mob/living/carbon/human)) - if(M:dna) - return kpcode_race_generic(M:dna:mutantrace()) - else - return kpcode_race_generic("human") - if(istype(M,/mob/living/carbon/monkey)) - return "monkey" - if(istype(M,/mob/living/carbon/alien)) - return "xeno" - if(istype(M,/mob/living/simple_animal)) - return M.name - return "something" - -proc/kpcode_get_adjective(var/mob/living/M) - if(istype(M,/mob/living/carbon/human)) - if(M:dna) - return kpcode_race_adjective(M:dna:mutantrace()) - else - return kpcode_race_adjective("human") - if(istype(M,/mob/living/carbon/monkey)) - return "cranky" - if(istype(M,/mob/living/carbon/alien)) - return "alien" - if(istype(M,/mob/living/simple_animal)) - return "beastly" - return "something" - - -/*var/list/mutant_races = list( - "human", - "fox", - "fennec", - "lizard", - "tajaran", - "panther", - "husky", - "squirrel", - "otter", - "murid", - "leporid", - "ailurus", - "shark", - "hawk", - "jelly", - "slime", - "plant", - )*/ - -var/list/mutant_tails = list( - "none"=0, - "tajaran"="tajaran", - "neko"="neko", - "dog"="lab", - "wolf"="wolf", - "fox"="fox", - "mouse"="murid", - "leporid"="leporid", - "panda"="ailurus", - "pig"="pig", - "cow"="cow", - "kangaroo"="kangaroo", - "kangaroo"="kangaroo", - "pony"="pony", - "lizard"="lizard", - "cyborg"="cyborg") - -var/list/mutant_wings = list( - "none"=0, - "bat"="bat", - "feathery"="feathery", - "moth"="moth", - "fairy"="fairy", - "tentacle"="tentacle" - ) - -var/list/cock_list = list( - "human", - "canine", - "feline", - "reptilian", - "equine") - - -proc/kpcode_hastail(var/S) - //switch(S) - //if("jordy","husky","squirrel","lizard","narky","tajaran","otter","murid","fox","fennec","wolf","leporid","shark","panther","ailurus","glowfen","hawk") - if(kpcode_race_tail(S)==1) - return S - if(kpcode_race_tail(S)) - return kpcode_race_tail(S) - /*if("neko") - return "tajaran" - if("mouse") - return "murid" - if("panda") - return "ailurus"*/ - if(S in mutant_tails) - return mutant_tails[S] - return 0 - -proc/kpcode_cantaur(var/S) - return kpcode_race_taur(S) \ No newline at end of file diff --git a/code/citadel/science.dm b/code/citadel/science.dm deleted file mode 100644 index a330bb05e8..0000000000 --- a/code/citadel/science.dm +++ /dev/null @@ -1,40 +0,0 @@ -datum/design/shrinkray - name = "Shrink Ray" - desc = "Make people small." - id = "shrinkray" - req_tech = list("combat" = 5, "materials" = 3, "engineering" = 2, "biotech" = 3) - build_type = PROTOLATHE - materials = list("$metal" = 5000, "$glass" = 1000, "$diamond" = 1500) - build_path = /obj/item/weapon/gun/energy/laser/sizeray/one - category = list("Weapons") - -datum/design/growthray - name = "Growth Ray" - desc = "Make people small... To the person you hit." - id = "growthray" - req_tech = list("combat" = 5, "materials" = 4, "engineering" = 3, "bluespace" = 2) - build_type = PROTOLATHE - materials = list("$metal" = 5000, "$glass" = 1000, "$diamond" = 1500) - build_path = /obj/item/weapon/gun/energy/laser/sizeray/two - category = list("Weapons") - -datum/design/stethoscope - name = "Stethoscope" - desc = "An ordinary stethoscope." - id = "stethoscope" - req_tech = list("biotech" = 2) - build_type = PROTOLATHE - materials = list("$metal" = 50) - build_path = /obj/item/clothing/tie/stethoscope - category = list("Medical") - -/* -datum/design/stethoscope_advanced - name = "Stethoscope (Advanced)" - desc = "An advanced stethoscope that can read micro-vibrations produced by DNA, or possibly something less silly." - id = "stethoscope_advanced" - req_tech = list("biotech" = 3, "magnets" = 2) - build_type = PROTOLATHE - materials = list("$metal" = 500) - build_path = /obj/item/clothing/tie/stethoscope/advanced - category = list("Medical")*/ \ No newline at end of file diff --git a/code/citadel/simple_animal/duck.dm b/code/citadel/simple_animal/duck.dm deleted file mode 100644 index ac7045b89e..0000000000 --- a/code/citadel/simple_animal/duck.dm +++ /dev/null @@ -1,9 +0,0 @@ -/mob/living/simple_animal/hostile/carp/duck - name = "space duck" - desc = "A ferocious, fang-bearing creature that resembles a rubber ducky." - icon_state = "rubduck" - icon_living = "rubduck" - icon_dead = "rubduck_dead" - icon_gib = "rubduck_gib" - meat_type = /obj/item/weapon/bikehorn - attack_sound = 'sound/items/bikehorn.ogg' \ No newline at end of file diff --git a/code/citadel/transfer_release.dm b/code/citadel/transfer_release.dm deleted file mode 100644 index 2864b05703..0000000000 --- a/code/citadel/transfer_release.dm +++ /dev/null @@ -1,76 +0,0 @@ -//Changed var/air_master.current_cycle to SSair.times_fired - - - -/obj/vore_preferences - proc/BuildTransfer() - var/dat= "" - dat += "
" - dat += "

Dispense

" - var/datum/vore_organ/VO=GetOrgan(tab_mod) - dat += "Currently dispensing [VO.milk_type]
" - dat += "Generic: " - dat += "5" - dat += "10" - dat += "15" - dat += "20" - dat += "
" - if(tab_mod=="cock") - VO.milk_list.Add(VO.owner.vore_balls_datum.milk_list) - VO.owner.vore_balls_datum.milk_list=new/list() - for(var/T in VO.milk_list) - dat += "[T]: " - dat += "5" - dat += "10" - dat += "15" - dat += "20" - dat += " ([VO.milk_list[T]["count"]] left)
" - dat += "
" - dat += "Transferring people from person to person coming soon.
" - return dat - - -/datum/vore_organ - proc/dispense(var/amount=5,var/name=null) - if(!milk_type)return - if(name=="null")name=null - var/obj/item/weapon/reagent_containers/RC=null - if(!owner.get_active_hand()) - owner<<"There's nothing in your active hand." - return - if(!istype(owner.get_active_hand(), /obj/item/weapon/reagent_containers)) - owner<<"You can't put [milk_type] in [owner.get_active_hand()]!" - return - RC=owner.get_active_hand() - if(!RC||!istype(RC, /obj/item/weapon/reagent_containers))return - if(!(RC.flags&OPENCONTAINER)) - owner<<"You can't put [milk_type] in [owner.get_active_hand()]!" - return //No milk for you! - if(RC.reagents.total_volume >= RC.reagents.maximum_volume) - owner<<"[owner.get_active_hand()] is full!" - return //Too full! - amount=min(RC.reagents.maximum_volume-RC.reagents.total_volume,amount) - var/list/data=new/list() - if(name) - amount=min(amount,milk_list[name]["count"]) - milk_list[name]["count"]=milk_list[name]["count"]-amount - data=milk_list[name]["data"] - if(milk_list[name]["count"]<=0) - milk_list.Remove(name) - if(amount>0) - if(last_release>SSair.times_fired-amount||owner.stat==2)return - last_release=SSair.times_fired - data["adjective"]=kpcode_get_adjective(owner) - data["type"]=kpcode_get_generic(owner) - //var/ownr_dna=null - if(istype(owner,/mob/living/carbon)) - data["donor_DNA"]=owner:dna - //ownr_dna=owner:dna - RC.reagents.add_reagent(milk_type, amount, data)//list("digested"=name,"donor_DNA"=ownr_dna)) - if(milk_type=="milk") - owner.visible_message("[owner] milks their tits into [RC].") - if(milk_type=="semen") - owner.visible_message("[owner] jacks off into [RC].") - if(milk_type=="femjuice") - owner.visible_message("[owner] masturbates their vagina over [RC].") - playsound(owner.get_top_level_mob(), 'sound/items/drink.ogg', 50, 1) \ No newline at end of file diff --git a/code/citadel/transformation.dm b/code/citadel/transformation.dm deleted file mode 100644 index 5acc88415a..0000000000 --- a/code/citadel/transformation.dm +++ /dev/null @@ -1,249 +0,0 @@ -/datum/vore_transform_datum - var/tf_path - var/tf_species - var/tf_gender=NEUTER - var/tf_egg=0 - proc/apply_transform(var/mob/living/targ) - return //THIS SHIT IS FUBAR -CACTUS - var/old_name=targ.real_name - var/new_gender=tf_gender==NEUTER ? targ.gender : tf_gender - var/transformation_happened=new_gender==targ.gender ? 0 : 1 - var/new_path= tf_egg ? /mob/living/egg : tf_path - var/datum/dna/tmp_dna=targ.has_dna() - if(tmp_dna) - targ.last_working_dna=tmp_dna - - if(tf_egg&&!tf_path)tf_path=targ.type - - if(new_path&&!istype(targ,new_path))//Transform path? - targ.vore_contents_drop(targ.get_last_organ_in()) - var/mob/living/new_mob = new new_path(targ.loc) - if(istype(new_mob)) - new_mob.a_intent = "harm" - //new_mob.universal_speak = 1 - new_mob.languages_spoken = 1 - new_mob.languages_understood = 1 - new_mob.vore_banned_methods=targ.vore_banned_methods - new_mob.vore_ability=targ.vore_ability - if(targ.mind) - targ.mind.transfer_to(new_mob) - else - new_mob.key = targ.key - if(targ.last_working_dna) - new_mob.last_working_dna=targ.last_working_dna - if(targ.get_last_organ_in()) - targ.last_organ_in.add(new_mob) - new_mob.vore_transform_index=-200 - qdel(targ) - targ=new_mob - transformation_happened=1 - - if(istype(targ,/mob/living/carbon)) //handle species and/or dna - var/mob/living/carbon/C=targ - C.has_dna() - if(C.last_working_dna&&C.dna) - C.dna=C.last_working_dna - if(tf_species) - C.real_name=old_name - C.vore_dna_mod(tf_species) - if(transformation_happened) - C.dna.cock=list("has"=C.gender==MALE,"type"="human","color"="900")//TEMP FIX! - C.dna.vagina=C.gender==FEMALE - transformation_happened=1 - - if(istype(targ,/mob/living/egg)) //handle egg - var/mob/living/egg/E=targ - src.tf_egg=0 - E.hatch_tf=src - if(!E.get_last_organ_in()) - E.incubate() - - targ.gender=new_gender - targ.real_name=old_name - targ.name=old_name - - if(transformation_happened&&targ.get_last_organ_in()) - targ.vore_transform_index=-200 - //targ.last_organ_in.owner<<"You feel a stir. An occupant has changed." - targ.last_organ_in.flavour_text(targ.last_organ_in.FLAVOUR_TRANSFORM) - - - - - - - - -/mob/living/proc/vore_dna_mod(var/new_dna) - if(!has_dna(src))return - if(!new_dna)return - var/mob/living/carbon/C=src - if(istype(new_dna,/datum/dna)) - var/old_name=C.real_name - var/datum/dna/change_dna=new_dna - C.dna.struc_enzymes=change_dna.struc_enzymes - //C.dna.unique_enzymes=change_dna.unique_enzymes - C.dna.uni_identity=change_dna.uni_identity - C.set_mutantrace(change_dna.species.id) - C.dna.mutanttail=change_dna.mutanttail - C.dna.mutantwing=change_dna.mutantwing - C.dna.special_color=change_dna.special_color - C.dna.special_color=change_dna.special_color - C.updateappearance() - C.real_name=old_name - C.name=old_name - else - //C.dna.mutantrace=new_dna - C.set_mutantrace(new_dna) - - - - - -/* -/mob/living/proc/vore_transform(var/transformpath=null, var/transform_species=null, var/transform_gender=NEUTER, var/datum/vore_organ/new_cont=null) - var/old_name=src.real_name - var/datum/dna/tmp_dna=check_dna_integrity(src) - if(tmp_dna) - last_working_dna=tmp_dna - if(!transformpath)transformpath=src.type - if(src.type==transformpath) - if(istype(src,/mob/living/carbon)) - var/mob/living/carbon/humz=src - var/race = humz.dna ? humz.dna.mutantrace : null - if((transform_species&&race==transform_species)&&(gender==transform_gender||transform_gender==NEUTER)) - return 0 - else - if(humz.dna) - humz.vore_dna_mod(transform_species) - if(transform_gender!=NEUTER) - humz.gender=transform_gender - if(istype(humz,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=humz - H.update_body() - if(new_cont) - humz.vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - return 1 - else - if(transform_gender!=NEUTER&&gender!=transform_gender) - gender=transform_gender - if(new_cont) - vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - return 1 - return 0 - src.vore_contents_drop(new_cont) - var/mob/living/new_mob = new transformpath(src.loc) - if(istype(new_mob)) - check_dna_integrity(new_mob) - new_mob.a_intent = "harm" - new_mob.universal_speak = 1 - //new_mob.universal_understand = 1 - if(src.mind) - src.mind.transfer_to(new_mob) - if(last_working_dna) - new_mob.last_working_dna=last_working_dna - else - new_mob.key = src - if(new_cont) - new_cont.contents.Add(new_mob) - new_cont.owner.stomach_contents.Add(new_mob) - new_mob.vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - if(istype(new_mob,/mob/living/carbon)) - var/mob/living/carbon/humz=new_mob - humz.dna=humz.last_working_dna - if(transform_species) - humz.vore_dna_mod(transform_species) - if(transform_gender!=NEUTER) - new_mob.gender=transform_gender - if(istype(humz,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=humz - H.update_body() - if(transform_gender!=NEUTER) - new_mob.gender=transform_gender - new_mob.real_name=old_name - new_mob.name=old_name - qdel(src) - return 1 -*/ - - - - - - - - - - - -/mob/living/egg - name = "egg" - icon = 'icons/mob/animal.dmi' - icon_state = "egg" - health = 50 - //max_health = 50 - - status_flags = CANPUSH - - languages_spoken = 1 - languages_understood = 1 - - canmove = 0 - - var/datum/vore_transform_datum/hatch_tf = null - var/hatch_prog = 0 - var/targ_hatch = 80 - var/incubating=0 - - proc/incubate() - incubating=1 - - update_canmove() - canmove=0 - return canmove - - New() - ..() - icon_state="egg[rand(0,2)]" - - Life() - vore_transform_index=-200 - if(incubating) - if(get_last_organ_in()) - hatch_prog+=2 - else - hatch_prog+=1 - if(hatch_prog>=targ_hatch&&hatch_tf) - src.visible_message("[src]'s egg hatches!") - hatch_tf.apply_transform(src) - - attack_hand(mob/living/carbon/human/M as mob) - ..() - - switch(M.a_intent) - - if("help") - if (health > 0) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.eye_blind ))) - O.show_message("\blue [M] hugs [src]'s egg.") - - if("grab") - if (M == src || anchored) - return - if (!(status_flags & CANPUSH)) - return - LAssailant = M - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.eye_blind ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) - - if("harm", "disarm") - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.eye_blind ))) - O.show_message("\red [M] taps [src]'s eggshell!") - - return \ No newline at end of file diff --git a/code/citadel/unassigned.dm b/code/citadel/unassigned.dm deleted file mode 100644 index 9f36d0a9b2..0000000000 --- a/code/citadel/unassigned.dm +++ /dev/null @@ -1,2046 +0,0 @@ -//TO DO: -// Vore plushies -// Vore bots -// Animal HUDs -// BATMAN --mostly done -// Vore transfers -// On that note, rewrite code so objects transfer right. -// Remains --mostly done -// Log vore in attacks -// A little button for error reports -// FIX THE THING ABOUT GETTING VORED WHILE BUCKLED - probs fixed fo' nao. -// Allow for completion of vore objective while they're in people in you. -//koshidumb -//koshidumb - - -//Constants -var/const/VORE_METHOD_FAIL=0 -var/const/VORE_METHOD_ORAL=1 -var/const/VORE_METHOD_ANAL=2 -var/const/VORE_METHOD_COCK=4 -var/const/VORE_METHOD_UNBIRTH=8 -var/const/VORE_METHOD_BREAST=16 -var/const/VORE_METHOD_TAIL=32 -var/const/VORE_METHOD_INSOLE=64 -var/const/VORE_METHOD_ABSORB=128 -var/const/VORE_METHOD_INSUIT=256 - -var/const/VORE_EXTRA_FULLTOUR=1 -var/const/VORE_EXTRA_REMAINS=2 - -var/const/VORE_REMAINS_NONE=0 -var/const/VORE_REMAINS_GENERIC=1 -var/const/VORE_REMAINS_NAMED=2 -var/const/VORE_REMAINS_MAX=2 //If ever we need more. - -var/const/VORE_MODE_EAT=1 -var/const/VORE_MODE_FEED=2 - -//var/const/PC_SIZE_MICRO=2 -//var/const/PC_SIZE_NORMAL=4 -//var/const/PC_SIZE_MACRO=8 - -var/const/VORE_DIGESTION_SPEED_NONE=0 -var/const/VORE_DIGESTION_SPEED_SLOW=1 -var/const/VORE_DIGESTION_SPEED_FAST=2 -var/const/VORE_DIGESTION_SPEED_ABNORMAL=4 -var/const/VORE_TRANSFORM_SPEED_NONE=0 -var/const/VORE_TRANSFORM_SPEED_SLOW=2 -var/const/VORE_TRANSFORM_SPEED_FAST=4 -var/const/VORE_TRANSFER_SPEED_NONE=0 -var/const/VORE_TRANSFER_SPEED_SLOW=6 -var/const/VORE_TRANSFER_SPEED_FAST=9 - -var/const/VORE_SIZEDIFF_DISABLED=0 -var/const/VORE_SIZEDIFF_TINY=1 -var/const/VORE_SIZEDIFF_SMALLER=2 -var/const/VORE_SIZEDIFF_SAMESIZE=3 -var/const/VORE_SIZEDIFF_DOUBLE=4 -var/const/VORE_SIZEDIFF_ANY=5 - -//Extra vars -/mob/living - var/vore_transform_index=0 - var/vore_transfer_index=0 - var/vore_mode=VORE_MODE_EAT - var/vore_head_first=1 - var/vore_current_method=VORE_METHOD_ORAL - var/vore_banned_methods=0 - var/vore_extra_bans=0 - var/vore_last_relay=0 - var/test_var_to_remove=0 - var/vore_remains_mode=VORE_REMAINS_NONE - - //var/vore_size_difference=VORE_SIZEDIFF_DOUBLE - /*var/list/vore_ability=list( - VORE_METHOD_ORAL=VORE_SIZEDIFF_SMALLER, - VORE_METHOD_ANAL=VORE_SIZEDIFF_DISABLED, - VORE_METHOD_COCK=VORE_SIZEDIFF_DISABLED, - VORE_METHOD_UNBIRTH=VORE_SIZEDIFF_DISABLED, - VORE_METHOD_BREAST=VORE_SIZEDIFF_DISABLED, - VORE_METHOD_TAIL=VORE_SIZEDIFF_DISABLED, - VORE_METHOD_INSOLE=VORE_SIZEDIFF_TINY, - VORE_METHOD_ABSORB=VORE_SIZEDIFF_DISABLED)*/ - - var/list/vore_ability=list( // This list is the initial list of what size differences people can vore at. - "1"=2, // Oral starts at one-size smaller. - "2"=0, // Anal starts disabled. - "4"=0, // Cock starts disabled. - "8"=0, // Unbirth starts disabled. - "16"=0, // Breast starts disabled. - "32"=0, // Tail starts disabled. - "64"=1, // Insole is 2 size differences. - "128"=0, // Absorption... isn't a thing. - "256"=2) // Insuit is 1 size difference. Previous comment = BAAAAD way to do this. - - var/vore_datums_initialized=0 - var/datum/vore_organ/stomach/vore_stomach_datum=new() - var/datum/vore_organ/cock/vore_cock_datum=new() - var/datum/vore_organ/balls/vore_balls_datum=new() - var/datum/vore_organ/womb/vore_womb_datum=new() - var/datum/vore_organ/breast/vore_breast_datum=new() - var/datum/vore_organ/insole/vore_insole_datum=new() - var/datum/vore_organ/insuit/vore_insuit_datum=new() - var/datum/vore_organ/tail/vore_tail_datum=new() - - var/datum/vore_organ/last_organ_in - var/datum/dna/last_working_dna - -/mob/living/carbon/human - var/underwear_active=1 - -/datum/mind - var/list/digested_by=new() - var/list/people_digested=new() - - -//Datums -/datum/vore_organ - var/mob/living/owner - var/list/contents=new/list() - var/list/remains=new/list() - var/remembered_bans=0 - var/digestion_factor=0 - var/healing_factor=0 - var/factor_offset=0 - var/oxygen=1 - var/escape=1 - var/integrity=100 - var/digestion_count=0 - var/last_release=0 - var/exterior=0 - var/tf_path=null - var/tf_species=null - var/tf_gender=NEUTER - var/tf_egg=0 - var/tf_factor=VORE_TRANSFORM_SPEED_NONE - var/milk_type=null - var/list/milk_list=new() - var/assoc_loc="chest" - var/assoc_fluid="none" - var/datum/vore_organ/transfer_target=null - var/transfer_factor=VORE_TRANSFER_SPEED_NONE - var/global/const/FLAVOUR_SILENT=0 - var/global/const/FLAVOUR_DIGEST=1 - var/global/const/FLAVOUR_RELEASE=2 - var/global/const/FLAVOUR_HURL=3 - var/global/const/FLAVOUR_ESCAPE=4 - var/global/const/FLAVOUR_TRANSFORM=5 - var/global/const/FLAVOUR_TRANSFER=6 - proc/digest() - if(!owner)return 0 - for(var/mob/living/carbon/M in contents) - if(!owner.stomach_contents.Find(M)) - contents.Remove(M) - //continue //bad in most languages - return digest() - if(!check_exist()) - transfer_to_other(owner.vore_stomach_datum) - return 0 - if(owner.stat==2)return 0 - //contents.Remove(null) - if(digestion_factor>VORE_DIGESTION_SPEED_SLOW) //Originally a temp fix. Might as well keep it. - oxygen=0 - else - oxygen=1+healing_factor - if(SSair.times_fired%3==1) - integrity=min(integrity+8,100) - for(var/mob/living/M in contents) - /*if(!owner.stomach_contents.Find(M)) - contents.Remove(M) - continue //bad in most languages - */ - if(istype(M, /mob/living)) - if(M.stat == 2 && (M.getFireLoss()>=100||!istype(M,/mob/living/carbon/human)) && digestion_factor) - vore_admins("[owner.real_name] has digested [M.real_name] in [type].",owner,M) - if(M.mind&&owner.mind) - M.mind.digested_by.Add(owner.mind) - owner.mind.people_digested.Add(M.mind) - remembered_bans|=M.vore_extra_bans - /*var/list/remains_to_add[VORE_REMAINS_MAX] - remains_to_add[VORE_REMAINS_GENERIC]=kpcode_get_generic(M) - remains_to_add[VORE_REMAINS_NAMED]=M.real_name - remains+=list("M.real_name[remains.len+1]"=remains_to_add)*/ - var/remains_idx=remains.len+1 - remains["[remains_idx]"]=new/list() - remains["[remains_idx]"]["[VORE_REMAINS_GENERIC]"]=kpcode_get_generic(M) - remains["[remains_idx]"]["[VORE_REMAINS_NAMED]"]=M.real_name - if(milk_type) - if(!milk_list[M.real_name]) - milk_list[M.real_name]=new/list() - milk_list[M.real_name]["count"]=milk_list[M.real_name]["count"]+20 - var/digested_DNA=null - if(istype(M,/mob/living/carbon)) - if(M:dna) - digested_DNA=M:dna - var/data = list("adjective"=null, "type"=null, "digested"=M.real_name, "digested_DNA"=digested_DNA, "digested_type"=kpcode_get_generic(M), "donor_DNA"=null) - milk_list[M.real_name]["data"]=data - flavour_text(FLAVOUR_DIGEST,M) - M.ghostize() - M.vore_contents_drop(src) - M.death(1) - owner.stomach_contents.Remove(M) - contents.Remove(M) - qdel(M) - owner.nutrition+=400 - digestion_count+=1 - //owner.updateappearance - //owner.update_body() - continue //hopefully won't break much - if(oxygen) - M.oxyloss=0//Temp fix - if(SSair.times_fired%3==1) - M.vore_transform_index+=tf_factor - if(M.vore_transform_index>=100) - M.vore_transform(tf_path,tf_species,tf_gender,tf_egg) - continue - M.vore_transfer_index+=transfer_factor - if(M.vore_transfer_index>=100) - flavour_text(FLAVOUR_TRANSFER,M) - //contents.Remove(M) - //transfer_target.add(M) - //M.vore_transform_index=0 - //M.vore_transfer_index=0 - transfer_to_other(transfer_target,M) - continue - if(!(M.status_flags & GODMODE)) - if(digestion_factor&&M.getFireLoss()<200) - M.adjustFireLoss(digestion_factor) - if(owner.nutrition<600&&(owner.nutrition<400||istype(src,/datum/vore_organ/stomach))) - owner.nutrition += digestion_factor - if(healing_factor&&owner.nutrition>100) - - if(M.getOxyLoss() )//&& prob(60)) - M.adjustOxyLoss(-2) - //if(prob(50))owner.nutrition-=1 - if(M.getBruteLoss() )//&& prob(60)) - M.heal_organ_damage(1,0) - owner.nutrition-=1 - if(M.getFireLoss() )//&& prob(60)) - M.heal_organ_damage(0,1) - owner.nutrition-=1 - if(M.getToxLoss() )//&& prob(60)) - M.adjustToxLoss(-1) - owner.nutrition-=1 - - if(oxygen) - M.adjustOxyLoss(-1)//*oxygen) - return 1 - proc/release(var/style=FLAVOUR_RELEASE,var/mob/living/prey=null,var/extra_info=0) - if(owner.stat!=DEAD&&owner.reagents&&owner.reagents.has_reagent("novomitchem"))return - if(style==FLAVOUR_RELEASE&&(last_release>SSair.times_fired-20||owner.stat==2))return - last_release=SSair.times_fired - flavour_text(style,prey,extra_info) - if(prey) - //message_admins("[owner.real_name] has released [prey.real_name] from [type]. Code [style].",owner,prey) - place_in_next(prey) - //updateappearance(owner) - return 1 - //BEGIN REMAINS - if(remains.len&&owner.vore_remains_mode&&!(remembered_bans&VORE_EXTRA_REMAINS)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/remains/vore/alreadybones in owner.loc) - already_messy=1 - break - if(!already_messy) - var/list/who_is_bones=new/list() - for(var/L in remains) - var/name_to_bone=remains[L]["[owner.vore_remains_mode]"] - if(name_to_bone&&!who_is_bones.Find(name_to_bone)) - who_is_bones.Add(name_to_bone) - //Make bones - var/obj/bones=new/obj/effect/decal/cleanable/remains/vore() - bones.loc=owner.loc - //Pile 'em up - if(remains.len>1) - bones.icon_state+="1" - //Now, name the remains - bones.name="remains of " - var/counter=1 - for(var/final_name in who_is_bones) - if(counter>1&&counter==who_is_bones.len) - if(counter==2) - bones.name+=" " - bones.name+="and " - bones.name+="[final_name]" - if(who_is_bones.len>2&&counter!=who_is_bones.len) - bones.name+=", " - counter++ - if(bones.name=="remains of ") - bones.name="remains of (KNOWN BUG DO NOT REPORT)" - remains=new/list() - //END REMAINS - milk_list=new() - digestion_count=0 - remembered_bans=0 - if(!contents.len)return 0 - /*for(var/obj/relea in contents) //somehow failed to release prey's gear. - place_in_next(relea) - for(var/mob/living/relea in contents) - //message_admins("[owner.real_name] has released [relea.real_name] from [type]. Code [style].",owner,relea) - place_in_next(relea)*/ - if(owner.stomach_contents.len) - for(var/atom/movable/A in owner.stomach_contents) - owner.stomach_contents.Remove(A) - A.loc = owner.loc - if(istype(A, /obj/item/weapon/reagent_containers/food/snacks)) - qdel(A) - //owner.updateappearance() - //owner.update_body() - return 1 - - proc/add(var/mob/living/addit) - var/mob/living/M - if(istype(addit,/mob/living)) - M=addit - if(M) - vore_admins("[owner.real_name]'s [type] has added [M.real_name].[digestion_factor ? " Digestion at [digestion_factor]." : ""][tf_factor ? " Transformation is on." : ""][healing_factor ? " Healing is on." : ""]",owner,M) - addit.loc = owner - owner.stomach_contents.Add(addit) - contents.Add(addit) - if(M) - M.last_organ_in=src - //updateappearance(owner) - //owner.update_body() - proc/flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(extra_info==VORE_EXTRA_FULLTOUR&&(remembered_bans&VORE_EXTRA_FULLTOUR)) - extra_info=0 - if(extra_info==VORE_EXTRA_FULLTOUR) - var/list/ins_lst=recursive_mob_check(src,0,0,0) - for(var/mob/living/check_em in ins_lst) - if(check_em.vore_extra_bans&extra_info) - extra_info=0 - break - if(source==FLAVOUR_DIGEST) - owner.visible_message("You hear loud gurgling from within [owner]'s stomach causing the lump to dissipate. Someone must have digested.") - prey<<"You gurgle away inside [owner]'s stomach. What you were is now just fat on the body. The process of digestion continues without any imput from you anymore." - else if(source==FLAVOUR_RELEASE) - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - if(extra_info==VORE_EXTRA_FULLTOUR) - owner.visible_message("[owner] squats down and releases the remains of those inside them.") - //I'd add something akin those barf additions here too but I'm p sure you wanna keep it clean lmao - else - owner.visible_message("[owner] hacks and coughs, spewing forth the remains of those inside them.") - playsound(owner.loc, 'sound/effects/splat.ogg', 50, 1) - owner.loc.add_vomit_floor(src, 1) - if(digestion_count&&live_people) - if(extra_info==VORE_EXTRA_FULLTOUR) - owner.visible_message("[owner] squats down and releases those still inside them.") - else - owner.visible_message("[owner] hacks and coughs, spewing forth those that had still remained inside.") - playsound(owner.loc, 'sound/effects/splat.ogg', 50, 1) - owner.loc.add_vomit_floor(src, 1) - if(!digestion_count&&live_people) - if(extra_info==VORE_EXTRA_FULLTOUR) - owner.visible_message("[owner] squats down and releases those inside them.") - else - owner.visible_message("[owner] hacks and coughs, spewing forth those inside.") - else if(source==FLAVOUR_HURL) - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] half-keels and gags, spewing forth the remains of those inside them.") - playsound(owner.loc, 'sound/effects/splat.ogg', 50, 1) - owner.loc.add_vomit_floor(src, 1) - if(digestion_count&&live_people) - owner.visible_message("[owner] half-keels and gags, spewing forth those that had still remained inside.") - playsound(owner.loc, 'sound/effects/splat.ogg', 50, 1) - owner.loc.add_vomit_floor(src, 1) - if(!digestion_count&&live_people) - owner.visible_message("[owner] half-keels and gags, spewing forth those inside.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] crawls out of [owner]'s mouth.") - else if(source==FLAVOUR_TRANSFORM) - owner<<"Your belly stirs. A transformation is complete." - else if(source==FLAVOUR_TRANSFER) - owner.visible_message("A thousand rainbow eyes stare at [owner]. Seems like Narky found a bug. What the hell did [owner] do?") - - - - proc/relaymove(var/mob/user, var/direction) - var/mob/living/prey - if(istype(user,/mob/living)) - prey=user - else - return - if(prey.vore_last_relay>SSair.times_fired-2)return - prey.vore_last_relay=SSair.times_fired - if(prey.a_intent=="help"&&!exterior) - owner.visible_message("Something shifts around within [owner].") - else - if(exterior||escape||owner.stat==2) - release(FLAVOUR_ESCAPE,prey) - else - integrity-=15 - owner.visible_message("Something slams against the inside of [owner].") - if(prob(40)) owner.Stun(rand(1,2)) - playsound(prey.get_top_level_mob(), 'sound/effects/attackblob.ogg', 50, 1) - if(integrity<=0) - release(FLAVOUR_HURL,prey) - integrity=0 - owner.Stun(rand(2,4)) - - /*if(prob(40)) - for(var/mob/M in hearers(4, src)) - if(M.client) - M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2) - var/obj/item/I = user.get_active_hand() - if(I && I.force) - var/d = rand(round(I.force / 4), I.force) - if(istype(src, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = src - var/organ = H.get_organ("chest") - if (istype(organ, /obj/item/organ/limb)) - var/obj/item/organ/limb/temp = organ - if(temp.take_damage(d, 0)) - H.update_damage_overlays(0) - H.updatehealth() - else - src.take_organ_damage(d) - for(var/mob/M in viewers(user, null)) - if(M.client) - M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2) - playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1) - - if(prob(src.getBruteLoss() - 50)) - for(var/atom/movable/A in stomach_contents) - A.loc = loc - stomach_contents.Remove(A) - src.gib()*/ - - proc/has_people() - var/pcount=0 - for(var/mob/living/M in contents) - if(!owner.stomach_contents.Find(M)) - contents.Remove(M) - else - pcount++ - return pcount - - proc/transfer_to_other(var/datum/vore_organ/targ, var/mob/living/prey=null) - if(prey) - if(targ.owner!=owner) - owner.stomach_contents.Remove(prey) - organ_leave(prey) - targ.add(prey) //Maybe make add check for other organs, and remove them from stomach_contents there? - else - for(var/mob/living/M in contents) - if(M) - transfer_to_other(targ,M) - - proc/place_in_next(var/atom/movable/prey) - if(istype(prey,/mob/living/egg)) - var/mob/living/egg/E=prey - E.incubate() - owner.stomach_contents.Remove(prey) - organ_leave(prey) - prey.loc=owner.loc - if(owner.get_last_organ_in()) - var/datum/vore_organ/VO=owner.get_last_organ_in() - VO.add(prey) - if(istype(prey,/mob)) - var/mob/M=prey - M.cancel_camera() - - proc/organ_leave(var/atom/movable/prey) - contents.Remove(prey) - if(istype(prey,/mob/living)) - var/mob/living/mprey=prey - mprey.vore_transform_index=0 - mprey.vore_transfer_index=0 - //updateappearance(owner) - //owner.update_body() - -/* proc/refresh_list() - for(var/mob/living/M in contents) - if(!owner.stomach_contents.Find(M)) - contents.Remove(M) - //continue //bad in most languages - return refresh_list() //this is better -*/ - proc/check_exist() - return 1 - - proc/digestion_factor_up() - switch(digestion_factor) - if(VORE_DIGESTION_SPEED_NONE) - digestion_factor=VORE_DIGESTION_SPEED_SLOW - return 1 - if(VORE_DIGESTION_SPEED_SLOW) - digestion_factor=VORE_DIGESTION_SPEED_FAST - return 1 - if(VORE_DIGESTION_SPEED_FAST) - if(factor_offset>0) - digestion_factor=VORE_DIGESTION_SPEED_ABNORMAL - return 1 - return 0 - - proc/digestion_factor_down() - switch(digestion_factor) - if(VORE_DIGESTION_SPEED_SLOW) - if(factor_offset<1) - digestion_factor=VORE_DIGESTION_SPEED_NONE - return 1 - if(VORE_DIGESTION_SPEED_FAST) - digestion_factor=VORE_DIGESTION_SPEED_SLOW - return 1 - if(VORE_DIGESTION_SPEED_ABNORMAL) - digestion_factor=VORE_DIGESTION_SPEED_FAST - return 1 - return 0 - -/datum/vore_organ/stomach - oxygen=1 - -/datum/vore_organ/cock - milk_type="semen" - assoc_loc="groin" - assoc_fluid="semen" - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_DIGEST) - owner.visible_message("You hear loud gurgling from between [owner]'s thighs. Someone must have digested inside their manhood.") - prey<<"You turn into [owner] [pick("spooge","cum","semen","batter","seed")]." - else if(source==FLAVOUR_RELEASE) - digestion_count+=owner.vore_balls_datum.digestion_count - remembered_bans|=owner.vore_balls_datum.remembered_bans - remains += owner.vore_balls_datum.remains - owner.vore_balls_datum.remains=new/list() - owner.vore_balls_datum.digestion_count=0 - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/semen() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - for(var/mob/living/M in owner.vore_balls_datum.contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] jacks off, releasing a massive load of cum that was once people.") - else if(digestion_count&&live_people) - owner.visible_message("[owner] jacks off, releasing people covered in a massive torrent of what used to be people.") - else if(!digestion_count&&live_people) - owner.visible_message("[owner] jacks off, releasing the cum-soaked occupants of their cock.") - else - owner.visible_message("[owner] jacks off, spraying a load of cum.") - owner.vore_balls_datum.release(FLAVOUR_SILENT,prey) - else if(source==FLAVOUR_HURL) - digestion_count+=owner.vore_balls_datum.digestion_count - remembered_bans|=owner.vore_balls_datum.remembered_bans - remains += owner.vore_balls_datum.remains - owner.vore_balls_datum.remains=new/list() - owner.vore_balls_datum.digestion_count=0 - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/semen() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - for(var/mob/living/M in owner.vore_balls_datum.contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] suddenly orgasms, releasing a massive load of cum that was once people.") - else if(digestion_count&&live_people) - owner.visible_message("[owner] suddenly orgasms, releasing people covered in a massive torrent of what used to be people.") - else if(!digestion_count&&live_people) - owner.visible_message("[owner] suddenly orgasms, releasing the cum-soaked occupants of their cock.") - else - owner.visible_message("[owner] suddenly orgasms, spraying a load of cum.") - owner.vore_balls_datum.release(FLAVOUR_SILENT,prey) - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] slips out of [owner]'s cock, the smell is quite interesting.") - else if(source==FLAVOUR_TRANSFORM) - owner<<"Your cock twitches. A transformation is complete." - else if(source==FLAVOUR_TRANSFER) - owner << "Someone moves into your balls.Their weight settling admist the cum-filled orbs" - prey<<"You move into [owner]'s balls, squeezed out of their cock and into the musky pool of seed. You're now rocking between each other step of ." - else ..() - check_exist() - if(owner.has_cock()) - return 1 - return 0 - -/datum/vore_organ/balls - milk_type="semen" - assoc_loc="groin" - assoc_fluid="semen" - release(var/style=FLAVOUR_RELEASE,var/prey=null) - if(style==FLAVOUR_HURL) - owner.vore_cock_datum.release(style,prey) - else - return ..() - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_DIGEST) - owner.visible_message("You hear loud gurgling from within [owner]'s balls. Someone must have digested.") - prey<<"You turn into [owner]'s [pick("spooge","cum","semen","seed")]. The lumps you made smoothing out as the sac contracts around your melted mass. " - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] slips out of [owner]'s cock. The smell is interesting. ") - else if(source==FLAVOUR_TRANSFORM) - owner<<"Your balls stir. A transformation is complete." - else ..() - check_exist() - if(owner.has_cock()) - return 1 - return 0 - -/datum/vore_organ/womb - milk_type="femjuice" - assoc_fluid="femjuice" - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_DIGEST) - owner.visible_message("You hear loud gurgling from within [owner]'s belly and a lump rounds and slowly flattens. Someone must have melted away inside [owner]'s womb.") - prey<<"You gurgle and slosh away inside [owner]'s womb. Your essence fills them out with just that bit more detail and satisfaction. The lump you made is rounded out and slowly shrinking. " - else if(source==FLAVOUR_RELEASE) - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/femjuice() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] masturbates their vagina, releasing a torrent of femjuice of former prey.") - else if(live_people) - owner.visible_message("[owner] masturbates their vagina, releasing its musk-drenched occupants..") - else - owner.visible_message("[owner] masturbates their vagina, dripping a small amount of femjuice.") - else if(source==FLAVOUR_HURL) - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/femjuice() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] suddenly orgasms, releasing a torrent of femjuice.") - else if(live_people) - owner.visible_message("[owner] suddenly orgasms, releasing their vagina's femjuice-drenched occupants..") - else - owner.visible_message("[owner] suddenly orgasms, dripping a small amount of femjuice.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] slips out of [owner]'s vagina, the smell is... interesting.") - else ..() - check_exist() - return owner.has_vagina() ? 1 : 0 - -/datum/vore_organ/breast - milk_type="milk" - assoc_fluid="milk" - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_DIGEST) - owner.visible_message("[owner]'s breasts jiggle. Someone must have turned into milk.The lumps they've made slosh and sink into a larger cupsize") - prey<<"You turn into [owner]'s milk, the bulges of your body simply adding to their cup size in a smooth swell." - else if(source==FLAVOUR_RELEASE) - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/milk() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner] milks their breasts, releasing a suspiciously large amount of milk.") - else if(live_people) - owner.visible_message("[owner] milks their breasts, releasing milk-soaked people.") - else - owner.visible_message("[owner] milks their breasts onto the floor.") - else if(source==FLAVOUR_HURL) - if(istype(owner.loc,/turf)) - var/already_messy=0 - for(var/obj/effect/decal/cleanable/sex/S in owner.loc) - already_messy=1 - break - if(!already_messy) - var/obj/S=new/obj/effect/decal/cleanable/sex/milk() - S.loc=owner.loc - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(live_people) - owner.visible_message("[owner]'s breasts suddenly lactate, releasing people covered in milk.") - else - owner.visible_message("[owner] suddenly lactates milk onto the floor.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] slips out of [owner]'s nipple.") - else if(source==FLAVOUR_TRANSFORM) - owner<<"Your breasts jiggle. A transformation is complete." - else ..() - check_exist() - return owner.has_boobs() ? 1 : 0 - -/datum/vore_organ/insole - exterior=1 - var/last_shoes="shoes" - assoc_loc="leg" - digest() - ..() - if(owner.get_shoes()) - var/obj/O=owner.get_shoes() - last_shoes=O.name - else - for(var/mob/living/M in contents) - release() - return - for(var/obj/item/O in contents) - release() - return - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_RELEASE) - owner.visible_message("[owner] takes off their [last_shoes] and dumps the contents onto the floor.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] crawls out and away from [owner]'s [last_shoes],, looking quite dishelved.") - -/datum/vore_organ/insuit - exterior=1 - var/last_suit="underwear" - digest() - ..() - if(owner.get_suit()) - var/obj/O=owner.get_suit() - last_suit=O.name - else - for(var/mob/living/M in contents) - release() - return - for(var/obj/item/O in contents) - release() - return - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_RELEASE) - owner.visible_message("[owner] takes off their [last_suit] and some things fall out.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] crawls out of [owner]'s [last_suit].") - -/datum/vore_organ/tail - flavour_text(var/source, var/mob/living/prey, var/extra_info=0) - if(source==FLAVOUR_DIGEST) - owner.visible_message("[owner]'s tail gurgles and a lump on it dissipates. Someone must have digested..") - prey<<"You gurgle away inside [owner]'s tail, your form softening and adding to the tail's fluff and its owner's curves." - else if(source==FLAVOUR_RELEASE) - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner]'s tail hacks and coughs, spewing forth the remains of those inside it.") - if(digestion_count&&live_people) - owner.visible_message("[owner]'s tail hacks and coughs, spewing forth those that had still remained inside.") - if(!digestion_count&&live_people) - owner.visible_message("[owner]'s tail hacks and coughs, spewing forth those inside.") - else if(source==FLAVOUR_HURL) - var/live_people=0 - for(var/mob/living/M in contents) - live_people=1 - break - if(digestion_count&&!live_people) - owner.visible_message("[owner]'s tail thrashes in pain, spewing forth the remains of those inside it.") - if(digestion_count&&live_people) - owner.visible_message("[owner]'s tail thrashes in pain, spewing forth those that had still remained inside.") - if(!digestion_count&&live_people) - owner.visible_message("[owner]'s tail thrashes in pain, spewing forth those inside.") - else if(source==FLAVOUR_ESCAPE&&prey) - owner.visible_message("[prey] crawls out of [owner]'s tailmaw, even as it snaps at their heels to reclaim them.") - else if(source==FLAVOUR_TRANSFORM) - owner<<"Your tail twitches. A transformation is complete." - else if(source==FLAVOUR_TRANSFER) - owner.visible_message("A lump in [owner]'s tail moves toward the base, [owner]'s stomach sags with the added weight and a soft gurgle of moving air pockets.") - prey<<"You move into [owner]'s stomach, soaked in the saliva-like drool of the maw. Your new enviroment squeezes all around you." - - -//Procs handling vore. -//mob/living/simple_animal/adjustFireLoss(var/num) -// health-=min(num,2) - - -/mob/living/proc/get_shoes() - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/humz=src - return humz.shoes - else - return null - -/mob/living/proc/get_suit() - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/humz=src - if(humz.w_uniform) - return humz.w_uniform - else - return humz.wear_suit - else - return null - -/mob/proc/get_last_organ_in() //Because adding in exceptions for non-living folk was boring. - return null - -/mob/living/get_last_organ_in() - if(last_organ_in) - if(!last_organ_in.contents.Find(src) || !last_organ_in.owner || !last_organ_in.owner.contents.Find(src)) - last_organ_in=null - return last_organ_in - - -/mob/living/proc/vore_initiate(var/mob/living/prey, var/mob/living/helper=src) - if(prey==helper)return - var/method=VORE_METHOD_ORAL - if(vore_mode==VORE_MODE_FEED)//CONFUSING CODE HERE! VAR NAMES ARE WEIRD! EXCESSIVE CAUTION ADVISED! - if(!prey.vore_pred_check()) - src << "This doesn't eat people." - return - if(!src.vore_prey_check(prey)) - src << "They can't eat you." - return - method=prey.vore_obtain_method(src,src) - prey.vore_handle(src,method,src) - return - else if( helper == src ) //If the pred initiated the voring - if(!src.vore_pred_check()) - src << "For whatever reason, you can't find it in you to eat so voraciously." - return - if(!prey.vore_prey_check(src)) - src << "This isn't something you can eat." - return - method=src.vore_obtain_method(prey) - src.vore_handle(prey,method) - return - else //Pred has a helper - if(!src.vore_pred_check()) - helper << "You're not going to be getting anything in this mouth." - return - if(!prey.vore_prey_check(src)) - helper << "The predator can't eat this." - return - method=src.vore_obtain_method(prey,helper) - src.vore_handle(prey,method,helper) - return - - - - -/mob/living/proc/vore_handle(var/mob/living/prey, var/method, var/mob/living/helper=src) - if(!src.vore_datums_initialized) src.vore_init_datums() - if(helper==prey) - if(method==VORE_METHOD_ORAL) - src.visible_message("[helper] begins to force themself into the mouth of [src]! [src]'s jaws are forced open and their neck soon swells with [helper]'s head!") - else if(method==VORE_METHOD_ANAL) - src.visible_message("[helper] presses against [src]'s backside and begins shoving!") - else if(method==VORE_METHOD_COCK) - src.visible_message("[helper] nuzzles the tip of [src]'s cock, coaxing it to eat them. Soon starting to push themselves inside the length.") - else if(method==VORE_METHOD_UNBIRTH) - src.visible_message("[helper] starts to nose head-first into [src]'s vagina, forcing thighs apart and the lower belly to swell as [helper] scrabbles for leverage!") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[helper] presses their nose against [src]'s nipple, giving it a lick to encourage their devourment!") - else if(method==VORE_METHOD_TAIL) - src.visible_message("[helper] hugs [src]'s tail and tries to fit inside it! The maw opens wide and engulfs over their head and shoulders in short order, making rapid progress!") - else if(method==VORE_METHOD_INSOLE) - var/obj/O=src.get_shoes() - if(!O)return - src.visible_message("[helper] begins to work their way into [O.gender==PLURAL?"one of ":""][src]'s [O.name].") - else if(method==VORE_METHOD_INSUIT) - var/obj/O=src.get_suit() - if(!O)return - src.visible_message("[helper] begins to work their way into [O.gender==PLURAL?"one of ":""][src]'s [O.name].") - else - src.visible_message("[helper] is feeding themself to [src]!") - else if(helper==src) - if(method==VORE_METHOD_ORAL) //Needs to be rewritten so it's based on each vore type, not each post/pre vore text. - if(vore_head_first) - src.visible_message("[src] begins to force [prey] into their mouth! Open jaws overtaking the prey's head and soon working over the shoulders!") - else - src.visible_message("[src] grabs [prey]'s ankles and begins to force them into their mouth foot-first! Jaws aggressively devouring up those legs quickly!") - else if(method==VORE_METHOD_ANAL) - src.visible_message("[src] begins to force [prey] into their anus!") - else if(method==VORE_METHOD_COCK) - if(vore_head_first) - src.visible_message("[src] grabs the back of [prey]'s head and presses it to the tip of their hungry cock. A quick thrust forward claims the entire face!") - else - src.visible_message("[src] grabs [prey]'s ankles and presses the feet to the tip of their hungry cock, working themselves in a pulling motion to help [prey] down!") - else if(method==VORE_METHOD_UNBIRTH) - if(vore_head_first) - src.visible_message("[src] grabs [prey]'s shoulders and begins shoving them into their crotch, a leg over [prey]'s frame. It wouldn't take long for [src]'s belly to start bulging with their treat as their muscle pull strongly!") - else - src.visible_message("[src] grabs [prey]'s ankles and begins shoving the feet into their crotch, bracing themselves as they drag in those shins and knees quickly, warmth crawling its way up!") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[src] grabs [prey] and presses them against a nipple!") - else if(method==VORE_METHOD_TAIL) - if(vore_head_first) - src.visible_message("[src] holds [prey] still while their tail looms overhead, salivating! It soon plunges over the head and shoulders in the first gulp, aggressively dragging [prey] into becoming a bulge within!") - else - src.visible_message("[src] holds [prey]'s form still while their tail laps at its prey's feet. The warm, toothless maw sliding up and over the calves in a single, pulsing swallow!") - else if(method==VORE_METHOD_INSOLE) - var/obj/O=src.get_shoes() - if(!O)return - src.visible_message("[src] begins to place [prey] into [O.gender==PLURAL?"one of ":""]their [O.name].") - else if(method==VORE_METHOD_INSUIT) - var/obj/O=src.get_suit() - if(!O)return - src.visible_message("[src] begins to place [prey] into [O.gender==PLURAL?"one of ":""]their [O.name].") - else - src.visible_message("[src] is attempting to devour [prey]!") - else - if(method==VORE_METHOD_ORAL) - src.visible_message("[helper] begins to force [prey] into the mouth of [src]! [src]'s jaws are forced open around the prey, and they swallow reflexively!") - else if(method==VORE_METHOD_ANAL) - src.visible_message("[helper] presses [prey] against [src]'s back enterance and begins shoving!") - else if(method==VORE_METHOD_COCK) - src.visible_message("[helper] holds [prey] to the tip of [src]'s cock, pushing their face into it, which soon vanishes inside!.") - else if(method==VORE_METHOD_UNBIRTH) - src.visible_message("[helper] grabs [prey]'s shoulders and shoves them into [src]'s crotch! [src]'s thighs are forced to spread as they take in [prey]'s form, the head and chest soon pushed within the depths!") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[helper] grabs [prey] and presses them against [src]'s nipple!") - else if(method==VORE_METHOD_TAIL) - src.visible_message("[helper] holds [prey] still while [src]'s tail looms overhead, salivating! The maw quickly overtakes [prey]'s head and chest, forcing [helper] to shift their grip down as to not follow their target inside!") - else if(method==VORE_METHOD_INSOLE) - var/obj/O=src.get_shoes() - if(!O)return - src.visible_message("[helper] begins to place [prey] into [O.gender==PLURAL?"one of ":""][src]'s [O.name].") - else if(method==VORE_METHOD_INSUIT) - var/obj/O=src.get_suit() - if(!O)return - src.visible_message("[helper] begins to place [prey] into [O.gender==PLURAL?"one of ":""][src]'s [O.name].") - else - src.visible_message("[helper] is feeding [prey] to [src]!") - - if( !do_mob(helper, prey) || !do_mob(helper,src) || !do_after(helper, src.vore_speed(prey,method) ) ) return - if( prey.anchored ) return - - if(helper==prey) - if(method==VORE_METHOD_ORAL) - src.visible_message("[helper] gives a final push, and is on the non-stop road to [src]'s belly! [src]'s neck loses the bulges it gained with [helper]'s devourment, gut sagging outwards with the newfound meal.") - else if(method==VORE_METHOD_ANAL) - src.visible_message("With a final shove, [helper] disappears into [src]'s anus!") - else if(method==VORE_METHOD_COCK) - src.visible_message("[helper] slips the rest of the way into [src]'s shaft, pre-slicked feet vanishing with an inadvertant moan from [src].") - else if(method==VORE_METHOD_UNBIRTH) - src.visible_message("[helper] engulfs themself in [src]'s sex, the last of them tugged from view as [src] gains a new belly bump, adjusting their stance with the weight.") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[helper] slips inside [src]'s breast, leaving it larger than it was before.") - else if(method==VORE_METHOD_TAIL) - src.visible_message("[src]'s tail engulfs [helper]. Their eager squirming muted under the tail flesh as the bulge moves deeper and deeper!") - else if(method==VORE_METHOD_INSOLE) - var/obj/O=src.get_shoes() - if(!O)return - src.visible_message("[helper] fits in nice and snug.agains't [src]'s foot") - else if(method==VORE_METHOD_INSUIT) - var/obj/O=src.get_suit() - if(!O)return - src.visible_message("[helper] fits in nice and snug inside [src]'s clothing, the added lump squirming to get comfortable.") - else - src.visible_message("[helper] has fed themself to [src]!") - else if(helper==src) - if(method==VORE_METHOD_ORAL) - src.visible_message("[prey] vanishes within the hungry maw of [src]! The stomach bulges with the predator's meal.") - else if(method==VORE_METHOD_ANAL) - src.visible_message("[prey] disappears into [src]'s pucker!") - else if(method==VORE_METHOD_COCK) - if(vore_head_first) - src.visible_message("[prey]'s feet go past [src]'s cockslit with a noisy slurp. The shaft droops with the prey within it as they sink deep enough to not easily be reached anymore!") - else - src.visible_message("[prey]'s head vanishes into [src]'s cockslit with a squelch, the last views of the room vanishing down the tube. A wet gush of pre splashing out as the lumps decend down the length.") - else if(method==VORE_METHOD_UNBIRTH) - if(vore_head_first) - src.visible_message("[src] shoves [prey]'s feet fully into their sex, belly swelling and passage oozing while their fingers linger to tease themselves, soon admiring the added bulge on their hips") - else - src.visible_message("[src] shoves [prey]'s head fully into their sex, [prey]'s last view of the world vanishing with [src]'s fingers lingering to tease the folds and push them deeper into the greedy flower") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[src] shoves [prey] inside their breast.") - else if(method==VORE_METHOD_TAIL) - if(vore_head_first) - src.visible_message("[src]'s tail slurps [prey]'s feet within and turns them into a bulge, The tail now drooping with the added mass that slowly traces itself in deeper.") - else - src.visible_message("[src]'s tail slurps [prey]'s head at last, the room framed by greedy maw as it turns them into a bulge. The tail now drooping with the added mass.") - else if(method==VORE_METHOD_INSOLE) - if(!src.get_shoes())return - src.visible_message("[helper] fits [prey] in nice and snug.") - else if(method==VORE_METHOD_INSUIT) - if(!src.get_suit())return - src.visible_message("[helper] fits [prey] in nice and snug.") - else - src.visible_message("[src] devours [prey]!") - else - if(method==VORE_METHOD_ORAL) - src.visible_message("[helper] gives a final push on [prey]'s feet, the last of them vanishing into the conveyer of gullet flesh to [src]'s stomach! [src]'s gains a bulge with the added addition") - else if(method==VORE_METHOD_ANAL) - src.visible_message("With a final shove from [helper], [prey] disappears into [src]'s anus!") - else if(method==VORE_METHOD_COCK) - src.visible_message("[helper] pushes the last of [prey] into [src]'s slit, pulling their pre-slicked hands free just in time.") - else if(method==VORE_METHOD_UNBIRTH) - src.visible_message("[helper] pushes [prey]'s feet firmly into [src]'s sex, going wrist-deep themself.They pull back their hand before it's tugged to the elbow and have a front row seat to the lower belly swelling with moving prey.") - else if(method==VORE_METHOD_BREAST) - src.visible_message("[helper] shoves [prey] inside [src]'s breast.") - else if(method==VORE_METHOD_TAIL) - src.visible_message("[src]'s tail completely engulfs over [prey]'s form, eagerly lapping over [helper]'s hand as if wanting a second helping within itself. [prey]'s bulges gradually settle into the center of the tail, awaiting their fate!") - else if(method==VORE_METHOD_INSOLE) - if(!src.get_shoes())return - src.visible_message("[helper] fits [prey] in [src]'s footwear, slipping it back onto their foot before [prey] could even think to escape..") - else if(method==VORE_METHOD_INSUIT) - if(!src.get_suit())return - src.visible_message("[helper] stuffs [prey] in through the opening of [src]'s clothing, putting it back into place before [prey] is able to wiggle free of the stuffy confines..") - else - src.visible_message("[helper] has fed [prey] to [src]!") - - if(helper==src) - vore_admins("[src] has eaten [prey]. via [method].",src,prey) - else if(helper==prey) - vore_admins("[prey] has fed themself to [src]. via [method].",src,prey) - else - vore_admins("[helper] has fed [prey] to [src]. via [method].",src,prey) - - var/datum/vore_organ/destination=vore_organ_for_method(method) - destination.add(prey) - -//Procs obtaining information for vore. - -/mob/living/proc/vore_ability_check(var/method,var/mob/living/prey=null) - if(method==VORE_METHOD_TAIL&&!kpcode_mob_has_tail()) - return 0 - var/ability=vore_ability[num2text(method)] - if(ability==VORE_SIZEDIFF_DISABLED)return 0 - if(!prey)return 1 - if(ability1) - return 0 - if(abilitysrc.sizeplay_size) - return 0 - if(ability=src.sizeplay_size) - return 0 - if(ability1) - return VORE_METHOD_ORAL - else if(helper.vore_current_method==VORE_METHOD_INSUIT) //Temporary, too - var/mob_count=0 - for(var/mob/M in src.vore_insuit_datum.contents) - mob_count+=1 - if(mob_count>2) - return VORE_METHOD_ORAL - else if(helper.vore_current_method==VORE_METHOD_TAIL) - if(!src.kpcode_mob_has_tail()) - return VORE_METHOD_ORAL - return helper.vore_current_method - -/mob/living/proc/vore_speed(var/mob/living/prey, var/method) - return 60+((prey.sizeplay_size-sizeplay_size)*10) - -/mob/living/proc/vore_organ_list() - var/list/return_lst=new/list() - return_lst.Add(src.vore_stomach_datum, src.vore_cock_datum, src.vore_balls_datum, src.vore_womb_datum, src.vore_breast_datum, src.vore_tail_datum, src.vore_insole_datum, src.vore_insuit_datum) - return return_lst - -/mob/living/proc/vore_init_datums() - for(var/datum/vore_organ/vo in src.vore_organ_list()) - vo.owner=src - if(!istype(src,/mob/living/carbon/human)&&!client)//If not human, and not player-controlled... - vo.digestion_factor=VORE_DIGESTION_SPEED_SLOW - vore_datums_initialized=1 - - -/mob/living/proc/vore_transform(var/transformpath=null, var/transform_species=null, var/transform_gender=NEUTER, var/egg_tf=0) - var/datum/vore_transform_datum/VTD=new() - VTD.tf_path=transformpath - VTD.tf_species=transform_species - VTD.tf_gender=transform_gender - VTD.tf_egg=egg_tf - VTD.apply_transform(src) -/* -/mob/living/proc/vore_transform(var/transformpath=null, var/transform_species=null, var/transform_gender=NEUTER, var/datum/vore_organ/new_cont=null) - var/old_name=src.real_name - var/datum/dna/tmp_dna=check_dna_integrity(src) - if(tmp_dna) - last_working_dna=tmp_dna - if(!transformpath)transformpath=src.type - if(src.type==transformpath) - if(istype(src,/mob/living/carbon)) - var/mob/living/carbon/humz=src - var/race = humz.dna ? humz.dna.mutantrace : null - if((transform_species&&race==transform_species)&&(gender==transform_gender||transform_gender==NEUTER)) - return 0 - else - if(humz.dna) - humz.vore_dna_mod(transform_species) - if(transform_gender!=NEUTER) - humz.gender=transform_gender - if(istype(humz,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=humz - H.update_body() - if(new_cont) - humz.vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - return 1 - else - if(transform_gender!=NEUTER&&gender!=transform_gender) - gender=transform_gender - if(new_cont) - vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - return 1 - return 0 - src.vore_contents_drop(new_cont) - var/mob/living/new_mob = new transformpath(src.loc) - if(istype(new_mob)) - check_dna_integrity(new_mob) - new_mob.a_intent = "harm" - new_mob.universal_speak = 1 - //new_mob.universal_understand = 1 - if(src.mind) - src.mind.transfer_to(new_mob) - if(last_working_dna) - new_mob.last_working_dna=last_working_dna - else - new_mob.key = src - if(new_cont) - new_cont.contents.Add(new_mob) - new_cont.owner.stomach_contents.Add(new_mob) - new_mob.vore_transform_index=-200 - new_cont.owner<<"Your belly stirs. A transformation is complete." - if(istype(new_mob,/mob/living/carbon)) - var/mob/living/carbon/humz=new_mob - humz.dna=humz.last_working_dna - if(transform_species) - humz.vore_dna_mod(transform_species) - if(transform_gender!=NEUTER) - new_mob.gender=transform_gender - if(istype(humz,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=humz - H.update_body() - if(transform_gender!=NEUTER) - new_mob.gender=transform_gender - new_mob.real_name=old_name - new_mob.name=old_name - qdel(src) - return 1 - -/mob/living/proc/vore_dna_mod(var/new_dna) - if(!check_dna_integrity(src))return - if(!new_dna)return - var/mob/living/carbon/C=src - if(istype(new_dna,/datum/dna)) - var/old_name=C.real_name - var/datum/dna/change_dna=new_dna - C.dna.struc_enzymes=change_dna.struc_enzymes - C.dna.unique_enzymes=change_dna.unique_enzymes - C.dna.uni_identity=change_dna.uni_identity - C.dna.mutantrace=change_dna.mutantrace - updateappearance(C) - C.real_name=old_name - C.name=old_name - else - C.dna.mutantrace=new_dna -*/ - - - - -/mob/living/proc/vore_contents_drop(var/datum/vore_organ/conta=null) - if(!conta)conta=src.get_last_organ_in() - if(!conta)return - for(var/mob/living/M in src.stomach_contents) - src.stomach_contents.Remove(M) - src.contents.Remove(M) - conta.add(M) - for(var/obj/item/W in src) - if(istype(W, /obj/item/weapon/implant || /obj/item/weapon/disk/nuclear || /obj/item/weapon/reagent_containers/food)) - qdel(W) - continue - W.layer = initial(W.layer) - W.loc = src.loc - W.dropped(src) - W.loc = src.loc//Once more to make sure! - if(conta) - conta.contents.Add(W) - conta.owner.stomach_contents.Add(W) - - -/mob/living/relaymove(var/mob/user, direction) - if(!istype(user,/mob/living)) - return ..() - var/mob/living/prey=user - if(prey in src.stomach_contents) - var/datum/vore_organ/VO=prey.get_last_organ_in() - if(VO) - VO.relaymove(prey,direction) - - - - - - -//objects -/obj/effect/decal/cleanable/sex/semen - name = "semen" - desc = "A puddle of hot, sticky spooge." - gender = PLURAL - density = 0 - anchored = 1 - layer = 2 - icon = 'icons/effects/blood.dmi' - icon_state = "semen1" - random_icon_states = list("semen1", "semen2", "semen3") - -/obj/effect/decal/cleanable/sex/femjuice - name = "femjuice" - desc = "A puddle of warm fem-cum. Someone got excited." - gender = PLURAL - density = 0 - anchored = 1 - layer = 2 - icon = 'icons/effects/blood.dmi' - icon_state = "fem1" - random_icon_states = list("fem1", "fem2", "fem3") - -/obj/effect/decal/cleanable/sex/milk - name = "breast milk" - desc = "A puddle of warm breast-milk." - gender = PLURAL - density = 0 - anchored = 1 - layer = 2 - icon = 'icons/effects/blood.dmi' - icon_state = "milk1" - random_icon_states = list("milk1", "milk2", "milk3") - - - -/obj/effect/decal/cleanable/lemonjuice - name = "lemon juice" - desc = "A puddle of lemon juice." - gender = PLURAL - density = 0 - anchored = 1 - layer = 2 - icon = 'icons/effects/blood.dmi' - icon_state = "lemon1" - random_icon_states = list("lemon1", "lemon2", "lemon3") - - - -//Clothes! -/obj/item/clothing/under/notnude - name = "emperor finery" - desc = "Only apex predators can see this." - icon_state = "notnude" - item_state = "notnude" - item_color = "notnude" - body_parts_covered = 0 - fitted = 0 - -/obj/item/clothing/under/maid - name = "maid uniform" - desc = "Clean and do laundry." - icon_state = "maid" - item_state = "maid" - item_color = "maid" - body_parts_covered = CHEST|GROIN|ARMS - fitted = 0 - -/obj/item/clothing/under/schoolgirl/red - icon_state = "schoolgirlred" - item_state = "schoolgirlred" - item_color = "schoolgirlred" - -/obj/item/clothing/under/schoolgirl/lav - icon_state = "schoolgirllav" - item_state = "schoolgirllav" - item_color = "schoolgirllav" - -/obj/item/clothing/under/rank/mailman/poojie - name = "poojie jumpsuit" - desc = "Foxcom Special Edition" - icon_state = "pooj" - item_state = "p_suit" - item_color = "pooj" - -/obj/item/clothing/head/mailman/poojie - name = "poojie hat" - desc = "Foxcom Special Edition" - icon_state = "pooj" - -//Sppoky stuffs! -/obj/item/clothing/suit/costume/spooky_spook - name = "spooky ghost costume" - desc = "It's a g-g-gg-ggg-g-g-g-BEDSHEET!" - icon_state = "spooky_spook" - item_state = "spooky_spook" - - -/obj/structure/sign/portrait - name = "portrait" - desc = "A pretty picture." - icon_state = "portrait" - var/image_path='icons/ss13_64.png' - var/image_name="SS13" - var/image_link=null - examine() - //set src in oview(7) - if(is_blind(usr)) return - if(!is_whitelisted(usr.ckey))return - - //if(in_range(usr, src)) - show(usr) - usr << desc - //else - // usr << "It is too far away." - proc/show(mob/user) - user << browse_rsc(image_path, "tmp_photo.png") - user << browse("[image_name]" \ - + "" \ - + "" \ - + "", "window=book;size=512x512") - onclose(user, "[name]") - -/obj/item/toy/toaster - name="poorly-drawn toaster" - icon = 'icons/obj/toy.dmi' - icon_state = "toaster" - desc = "You've seen better." - attack_self(mob/user) - user << "You try to make toast with [src]. It doesn't have an animation for that." - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/toy/crayon)||istype(W,/obj/item/weapon/pen)) - if(icon_state=="toaster") - user << "You try to make [src] look better." - user.loc.audible_message("[user] scribbles on [src]. \"Huzzah!\"") - icon_state="toaster_cs" - else - user << "You don't think it gets much better than this." - return - return ..() - -/obj/item/toy/toaster/cs - icon_state="toaster_cs" - - - - - -datum/objective/vore_digest - var/target_role_type=0 - dangerrating = 10 - -datum/objective/vore_digest/find_target_by_role(role, role_type=0) - target_role_type = role_type - ..(role, role_type) - return target - -datum/objective/vore_digest/check_completion() - if(target && target.current) - if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey || target.current.loc==owner.current) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite - return 1 - var/list/ins_lst=recursive_mob_check(src,0,0,0) - if(ins_lst.Find(target.current)) - return 1 - return 0 - return 1 - -datum/objective/vore_digest/update_explanation_text() - ..() - if(target && target.current) - explanation_text = "Eat [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role], and keep them. This order is dead or alive, so digest or otherwise kill them if they are too much trouble." - else - explanation_text = "Free Objective (Go eat some people! Digestion optional if they allow it!)" - - -datum/objective/digest - var/target_role_type=0 - dangerrating = 10 - -datum/objective/digest/find_target_by_role(role, role_type=0) - target_role_type = role_type - ..(role, role_type) - return target - -datum/objective/digest/check_completion() - if(target&&owner.people_digested.Find(target)) - return 1 - else if(!target&&owner.people_digested.len) - return 1 - return 0 - -datum/objective/digest/update_explanation_text() - ..() - if(target && target.current) - explanation_text = "Eat [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role], and digest them. They do not need to stay dead." - else - explanation_text = "Digest one person." - - -datum/objective/get_digested - var/target_role_type=0 - dangerrating = 10 - -datum/objective/get_digested/find_target_by_role(role, role_type=0) - target_role_type = role_type - ..(role, role_type) - return target - -datum/objective/get_digested/check_completion() - if(target&&owner.digested_by.Find(target)) - return 1 - else if(!target&&owner.digested_by.len) - return 1 - return 0 - -datum/objective/get_digested/update_explanation_text() - ..() - if(target && target.current) - explanation_text = "Get digested by [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role], to spread a supervirus. All of your cloned bodies will contain this supervirus." - else - explanation_text = "Get digested to spread a supervirus." - - -datum/objective/vore - var/target_role_type=0 - var/failsafe=0 - dangerrating = 10 - -datum/objective/vore/find_target_by_role(role, role_type=0) - target_role_type = role_type - ..(role, role_type) - return target - -datum/objective/vore/check_completion() - if(failsafe)return 1 //Should hopefully only trigger on free objective. - if(target && target.current) - if(target.current.loc==owner.current) - return 1 - var/list/ins_lst=recursive_mob_check(src,0,0,0) - if(ins_lst.Find(target.current)) - return 1 - return 0 - return 0 //As a failsafe, this is usually "return 1." This objective requires they be not exploded, so... Return 0. - -datum/objective/vore/update_explanation_text() - ..() - if(target && target.current) - explanation_text = "Eat [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role], and keep them. We need them alive, do not let them die." - else - explanation_text = "Free Objective (Go eat some people!)" - failsafe=1 - -datum/objective/vore_opt_escape - explanation_text = "Escape on the shuttle or an escape pod alive. For optional security, be smuggled aboard while inside someone. Do not arrive in the brig." - dangerrating = 5 - -/*datum/objective/vore_opt_escape/check_completion() - if(issilicon(owner.current)) - return 0 - if(isbrain(owner.current)) - return 0 - if(emergency_shuttle.location<2) - return 0 - if(!owner.current || owner.current.stat ==2) - return 0 - var/turf/location = get_turf(get_top_level_mob(owner.current)) - if(!location) - return 0 - - if(istype(location, /turf/simulated/shuttle/floor4)) // Fails traitors if they are in the shuttle brig - return 0 - - var/area/check_area = location.loc - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - else - return 0*/ - -datum/objective/vore_escape - explanation_text = "Escape on the shuttle or an escape pod alive. They are hunting for you and checking containers, so you will need to be inside someone to escape. They will perform full searches in the brig, so avoid it." - dangerrating = 5 - -/*datum/objective/vore_escape/check_completion() - if(issilicon(owner.current)) - return 0 - if(isbrain(owner.current)) - return 0 - if(emergency_shuttle.location<2) - return 0 - if(!owner.current || owner.current.stat ==2) - return 0 - if(get_top_level_mob(owner.current)==owner.current) return 0 - var/turf/location = get_turf(get_top_level_mob(owner.current)) - if(!location) - return 0 - - if(istype(location, /turf/simulated/shuttle/floor4)) // Fails traitors if they are in the shuttle brig - return 0 - - var/area/check_area = location.loc - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - if(istype(check_area, /area/centcom/evac)) - return 1 - else - return 0*/ - - - -//Makeshift vore toggles -/* -/mob/living/proc/set_vore_abil() - set name = "Enable Vore Ability" - set category = "Vore" - var/selection = input("People will be able to feed you, and it will be an option to you on other menus.") in list("Cancel", "Anal", "Cock", "Unbirth") - if(selection=="Cancel")return - if(selection=="Anal") - vore_possible_methods |= VORE_METHOD_ANAL - if(selection=="Cock") - vore_possible_methods |= VORE_METHOD_COCK - if(selection=="Unbirth") - vore_possible_methods |= VORE_METHOD_UNBIRTH - src << "[selection] added." - -/mob/living/proc/set_vore_debil() - set name = "Disable Vore Ability" - set category = "Vore" - var/selection = input("Will prevent you from devouring people this way.") in list("Cancel", "Anal", "Cock", "Unbirth") - if(selection=="Cancel")return - if(selection=="Anal") - vore_possible_methods &= ~VORE_METHOD_ANAL - if(selection=="Cock") - vore_possible_methods &= ~VORE_METHOD_COCK - if(selection=="Unbirth") - vore_possible_methods &= ~VORE_METHOD_UNBIRTH - src << "[selection] removed." - - - -/mob/living/proc/set_vore_mode() - set name = "Change Vore Mode" - set category = "Vore" - var/selection = input("Set the type of vore used when eating or feeding others.") in list("Oral", "Anal", "Cock", "Unbirth", "Put in Shoe") - if(selection=="Oral") - vore_current_method = VORE_METHOD_ORAL - if(selection=="Anal") - vore_current_method = VORE_METHOD_ANAL - if(selection=="Cock") - vore_current_method = VORE_METHOD_COCK - if(selection=="Unbirth") - vore_current_method = VORE_METHOD_UNBIRTH - if(selection=="Put in Shoe") - vore_current_method = VORE_METHOD_INSOLE - src << "(Not really much of a vore method, but, gotta put it in the debug panel.)" - src << "[selection] is your current vore type." - if(!(src.vore_possible_methods&vore_current_method)) - src<<"Note: You do not have this vore type enabled for yourself. This will only work when feeding people." - - -/mob/living/proc/set_vore_ban() - set name = "Ban Vore Type" - set category = "Vore" - var/selection = input("People will not be able to engage you in this type, and will instead orally vore.") in list("Cancel", "Anal", "Cock", "Unbirth") - if(selection=="Anal") - vore_banned_methods |= VORE_METHOD_ANAL - if(selection=="Cock") - vore_banned_methods |= VORE_METHOD_COCK - if(selection=="Unbirth") - vore_banned_methods |= VORE_METHOD_UNBIRTH - src << "[selection] banned." - -/mob/living/proc/set_vore_unban() - set name = "Unban Vore Type" - set category = "Vore" - if(!src.vore_banned_methods) - src<<"No banned vore methods." - if(src.ckey=="kingpygmy") //Gonna put this here for now. - src.verbs += /mob/living/proc/test_macro_stuffs - src.verbs += /mob/living/proc/test_micro_stuffs - return - var/selection = input("People will be able to engage you in this type of vore again.") in list("Cancel", "Anal", "Cock", "Unbirth") - if(selection=="Anal") - vore_banned_methods &= ~VORE_METHOD_ANAL - if(selection=="Cock") - vore_banned_methods &= ~VORE_METHOD_COCK - if(selection=="Unbirth") - vore_banned_methods &= ~VORE_METHOD_UNBIRTH - src << "[selection] unbanned."*/ - - - - - - -var/list/traitor_test_list = null -/client/proc/set_traitor_test() - set category = "Debug" - set name = "Traitor Test" - if(!holder) return - var/inpt=input("Who do you want to add?","Add Key","[usr.ckey]") - if(!inpt)return - inpt=ckey(inpt) - if(!traitor_test_list) - traitor_test_list=list("[inpt]") - else - traitor_test_list.Add("[inpt]") - log_admin("[key_name(usr)] has set [inpt] to be a traitor this round.") - vore_admins("[key_name(usr)] has set [inpt] to be a traitor this round.") - feedback_add_details("admin_verb","TRAITTEST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - - - - -/mob/living/proc/set_vore_transform(var/datum/vore_organ/VO=null) - set name = "Set Transformation" - set category = "Vore" - if(!VO) - VO=vore_womb_datum - if(!src.vore_datums_initialized) src.vore_init_datums() - has_dna(src) - src<<"WARNING: Transformation is currently heavily bugged. Expect odd behaviour until it is fully integrated with the vore panel." - var/selection = alert("Transform people with [istype(VO,/datum/vore_organ/cock) ? "cockvore" : "unbirth"]?","Vore","Yes","No") - if(selection=="No") - src << "Will not transform people." - VO.tf_factor=VORE_TRANSFORM_SPEED_NONE - return - selection = input("What do you want to turn people into?") in list("No Change", "Human", "Monkey", "Cat", "Chicken", "Cow", "Lizard", "Mouse", "Crab", "Fox") - switch(selection) - if("Human")VO.tf_path=/mob/living/carbon/human - if("Monkey")VO.tf_path=/mob/living/carbon/monkey - //if("Corgi")VO.tf_path=/mob/living/simple_animal/pet/corgi //abused for the traitor objective too many times, right? ^removed from the list above - if("Cat")VO.tf_path=/mob/living/simple_animal/pet/cat - if("Chiken")VO.tf_path=/mob/living/simple_animal/chicken - if("Cow")VO.tf_path=/mob/living/simple_animal/cow - if("Lizard")VO.tf_path=/mob/living/simple_animal/lizard - if("Mouse")VO.tf_path=/mob/living/simple_animal/mouse - //if("Pug")VO.tf_path=/mob/living/simple_animal/pet/pug - if("Crab")VO.tf_path=/mob/living/simple_animal/crab - if("Fox")VO.tf_path=/mob/living/simple_animal/pet/fox - else VO.tf_path=null - VO.tf_species=null - if(VO.tf_path==/mob/living/carbon/human) - selection=input("What species?") in list("No Change","Turn Into Me")+kpcode_race_getlist(ckey) - if(selection!="No Change"&&selection!="Turn Into Me") - VO.tf_species=selection - else if(selection=="Turn Into Me") - VO.tf_species=has_dna(src) - selection = alert("What gender?","Vore","No Change","Male","Female") - switch(selection) - if("Male") VO.tf_gender=MALE - if("Female") VO.tf_gender=FEMALE - else VO.tf_gender=NEUTER - selection = alert("Give them a nice, eggy package?","Vore","Egg!","No.") - VO.tf_egg = selection=="Egg!" ? 1 : 0 - if(VO.has_people()&&!VO.tf_factor) - vore_admins("[VO.owner]'s [VO.type] set to transform.",VO.owner) - VO.tf_factor=VORE_TRANSFORM_SPEED_FAST - VO.digestion_factor=VORE_DIGESTION_SPEED_NONE - VO.healing_factor=0 - src<<"Transform enabled. Digestion automatically disabled for this vore type and it will take time to complete." - - - - -/mob/living/proc/set_vore_digest() //possibly mobs? - set name = "Digestion Toggle" - set category = "Vore" - if(!src.vore_datums_initialized) src.vore_init_datums() - if(vore_stomach_datum.digestion_factor==VORE_DIGESTION_SPEED_NONE) - vore_stomach_datum.digestion_factor=VORE_DIGESTION_SPEED_SLOW - vore_cock_datum.digestion_factor=VORE_DIGESTION_SPEED_SLOW - vore_womb_datum.digestion_factor=VORE_DIGESTION_SPEED_SLOW - src << "Digesting slowly!" - return - if(vore_stomach_datum.digestion_factor==VORE_DIGESTION_SPEED_SLOW) - vore_stomach_datum.digestion_factor=VORE_DIGESTION_SPEED_FAST - vore_cock_datum.digestion_factor=VORE_DIGESTION_SPEED_FAST - vore_womb_datum.digestion_factor=VORE_DIGESTION_SPEED_FAST - src << "Digesting fast!" - return - vore_stomach_datum.digestion_factor=VORE_DIGESTION_SPEED_NONE - vore_cock_datum.digestion_factor=VORE_DIGESTION_SPEED_NONE - vore_womb_datum.digestion_factor=VORE_DIGESTION_SPEED_NONE - src << "No longer digesting." - - -/mob/living/proc/vore_release_stomach() - set name = "Release Stomach" - set category = "Vore" - if(!src.vore_stomach_datum.release()) - src << "You can't do that. Eat something, first!" - -/mob/living/proc/vore_release_cock() - set name = "Release Cock" - set category = "Vore" - src.vore_cock_datum.release() - -/mob/living/proc/vore_release_womb() - set name = "Release Womb" - set category = "Vore" - src.vore_womb_datum.release() - -/mob/living/proc/vore_panel() - set name = "Vore Panel" - set category = "Vore" - var/obj/vore_preferences/VP=new() - VP.target=src - VP.ShowChoices(src) - -/mob/living/proc/underwear_toggle() - set name = "Force Update" - set category = "Vore" - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/humz=src - humz.underwear_active=!humz.underwear_active - //updateappearance(src) - //src.update_body() - else - src<<"Humans only." - -/* -/mob/living/proc/test_macro_stuffs() - set name = "Macro Size" - set category = "Debug" - var/matrix/trnfrm=new() - trnfrm=trnfrm.Scale(2) - src.transform=trnfrm - */ - -/mob/living/proc/test_macro_stuffs() - set name = "Macro Size" - set category = "Debug" - src.sizeplay_grow() - -/mob/living/proc/test_micro_stuffs() - set name = "Micro Size" - set category = "Debug" - src.sizeplay_shrink() - - -/mob/living/proc/kpcode_mob_has_tail() - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=src - var/race = H.dna ? H.dna.mutantrace() : null - if(race&&kpcode_hastail(race)) - return kpcode_hastail(race) - if(!race||race=="human") - var/tail = H.dna ? H.dna.mutanttail : null - if(tail&&kpcode_hastail(tail)) - return kpcode_hastail(tail) - if(istype(src,/mob/living/carbon/monkey)) - return "monkey" - if(istype(src,/mob/living/carbon/alien)) - return "alien" - return 0 - - -/mob/living/proc/has_cock() - if(issilicon(src))return 0 - if(istype(src,/mob/living/carbon)) - var/mob/living/carbon/H=src - var/list/cock = H.dna ? H.dna.cock : null - if(cock&&cock["has"]) - return cock["has"] - else - return 0 - else if(gender==MALE) - return 1 - return 0 - -/mob/living/proc/has_vagina() - if(issilicon(src))return 0 - if(istype(src,/mob/living/carbon)) - var/mob/living/carbon/H=src - var/vagina = H.dna ? H.dna.vagina : 0 - return vagina - else if(gender==FEMALE) - return 1 - return 0 - -/mob/living/proc/has_boobs() - if(issilicon(src))return 0 - return gender==FEMALE - - -/mob/living/New() // - //verbs += /mob/living/proc/set_vore_abil - //verbs += /mob/living/proc/set_vore_debil - //verbs += /mob/living/proc/set_vore_mode - //verbs += /mob/living/proc/set_vore_ban - //verbs += /mob/living/proc/set_vore_unban - //verbs += /mob/living/proc/digest - //verbs += /mob/living/proc/set_vore_transform - //verbs += /mob/living/proc/vore_release_stomach - //verbs += /mob/living/proc/vore_release_cock - //verbs += /mob/living/proc/vore_release_womb - verbs += /mob/living/proc/vore_panel - verbs += /mob/living/proc/underwear_toggle - if(!src.vore_datums_initialized) src.vore_init_datums() - return ..() - - - - - - - - - - - - - -/client/verb/looc(msg as text) - set name = "LOOC" - set desc = "Local OOC, seen only by those in view." - set category = "OOC" - - if(say_disabled) //This is here to try to identify lag problems - usr << "\red Speech is currently admin-disabled." - return - - if(!mob) return - if(IsGuestKey(key)) - src << "Guests may not use OOC." - return - - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) - if(!msg) return - - if(!(prefs.toggles & CHAT_OOC)) - src << "\red You have OOC muted." - return - - if(!holder) - if(!ooc_allowed) - src << "\red OOC is globally muted" - return - if(!dooc_allowed && (mob.stat == DEAD)) - usr << "\red OOC for dead mobs has been turned off." - return - if(prefs.muted & MUTE_OOC) - src << "\red You cannot use OOC (muted)." - return - if(handle_spam_prevention(msg,MUTE_OOC)) - return - if(findtext(msg, "byond://")) - src << "Advertising other servers is not allowed." - log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]") - vore_admins("[key_name_admin(src)] has attempted to advertise in LOOC: [msg]") - return - - log_ooc("(LOCAL) [mob.name]/[key] : [msg]") - - var/list/heard = get_hearers_in_view(7, get_top_level_mob(src.mob)) - for(var/mob/M in heard) - if(!M.client) - continue - var/client/C = M.client - if (C in admins) - continue //they are handled after that - - if (istype(M,/mob/dead/observer)) - continue //Also handled later. - - if(C.prefs.toggles & CHAT_OOC) -// var/display_name = src.key -// if(holder) -// if(holder.fakekey) -// if(C.holder) -// display_name = "[holder.fakekey]/([src.key])" -// else -// display_name = holder.fakekey - C << "LOOC: [src.mob.name]: [msg]" - - for(var/client/C in admins) - if(C.prefs.toggles & CHAT_OOC) - var/prefix = "(R)LOOC" - if (C.mob in heard) - prefix = "LOOC" - C << "[prefix]: [src.key]/[src.mob.name]: [msg]" - - for(var/mob/dead/observer/G in world) - if(!G.client) - continue - var/client/C = G.client - if (C in admins) - continue //handled earlier. - if(C.prefs.toggles & CHAT_OOC) - var/prefix = "(G)LOOC" - if (C.mob in heard) - prefix = "LOOC" - C << "[prefix]: [src.key]/[src.mob.name]: [msg]" - - - -/*datum/admins/proc/panicbutton() - set category = "Server" - set desc="Whitelist lots of things" - set name="Panic Button" - if(alert("Are you sure? This will whitelist things and cannot be undone.",,"Yes","No")=="Yes") - config.narkyjoblist=1 - config.narkypaniclist=1 - vore_admins("\blue [key_name_admin(usr)] hit the panic button.", 1) - log_admin("[key_name(usr)] hit the panic button.") - feedback_add_details("admin_verb","PAN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -*/ - - -/datum/proc/doorfixing() - set category = "Special Verbs" - set name = "Door Fixing" - set desc = "Fix fire and blast doors" - for(var/obj/machinery/door/firedoor/W in world) - if(W.layer == 2.7) - W.layer = 2.6 - for(var/obj/machinery/door/poddoor/X in world) - if(X.layer == 2.7) - X.layer = 2.5 - message_admins("[key_name_admin(usr)] activated Door fixy button") - feedback_add_details("admin_verb","DFB") - - -/mob/proc/kpcode_mob_offset() - return - /* -/mob/proc/update_body() - if(istype(src,/mob/living/carbon/human)) - //updateappearance(mutcolor_update=0) - src.update_body() - /*if(istype(src,/mob/living/carbon)) //Endless loop for nonhuman mobs. base proc is /human only so nonhumans would get stuck with this being their only option. - //updateappearance(mutcolor_update=0) - src.update_body()*/ -*/ -/mob/living/kpcode_mob_offset() - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/H=src - if(H.dna&&H.dna.taur&&!anchored&&!lying) - var/size_coeff=8 - if(sizeplay_size= 500) //People decided to abuse it. Sorry. It was asked to be made so it couldn't be spammed, and what do ya know, people are spamming it everywhere. + src.visible_message("\the [src] weaves a web from their spinneret silk.") + nutrition -= 500 + spawn(30) //3 seconds to form + new /obj/effect/spider/stickyweb(src.loc) + else + src << "You do not have enough nutrition to create webbing!" +*/ + +mob/proc/weaveWebBindings() + set name = "Weave Web Bindings" + set category = "Species Powers" + if(nutrition >= 30) //This isn't a huge problem. This is so you can bind people up. + src.visible_message("\the [src] pulls silk from their spinneret and delicately weaves it into bindings.") + nutrition -= 30 + spawn(30) //5 seconds to weave the bindings~ + var/obj/item/clothing/suit/web_bindings/bindings = new() //This sprite is amazing, I must say. + src.put_in_hands(bindings) + else + src << "You do not have enough nutrition to create webbing!" //CK~ diff --git a/code/citadel/vore/appearance/sprite_accessories_vr.dm b/code/citadel/vore/appearance/sprite_accessories_vr.dm new file mode 100644 index 0000000000..30e54c6443 --- /dev/null +++ b/code/citadel/vore/appearance/sprite_accessories_vr.dm @@ -0,0 +1,645 @@ +/* + Hello and welcome to VOREStation sprite_accessories: For a more general overview + please read sprite_accessories.dm. This file is for ears, tails, and taur bodies! + + This is intended to be friendly for people with little to no actual coding experience. + + !!WARNING!!: changing existing accessory information can be VERY hazardous to savefiles, + to the point where you may completely corrupt a server's savefiles. Please refrain + from doing this unless you absolutely know what you are doing, and have defined a + conversion in savefile.dm +*/ + +// Add Additional variable onto sprite_accessory +/datum/sprite_accessory + // Ckey of person allowed to use this, if defined. + var/list/ckeys_allowed = null + +/* +//////////////////////////// +/ =--------------------= / +/ == Ear Definitions == / +/ =--------------------= / +//////////////////////////// +*/ +/datum/sprite_accessory/ears + name = "You should not see this..." + icon = 'icons/mob/vore/ears_vr.dmi' + do_colouration = 0 // Set to 1 to blend (ICON_ADD) hair color + + var/color_blend_mode = ICON_ADD // Only appliciable if do_coloration = 1 + var/extra_overlay // Icon state of an additional overlay to blend in. + var/desc = "You should not see this..." + +// Ears avaliable to anyone + +/datum/sprite_accessory/ears/squirrel_orange + name = "squirel, orange" + desc = "" + icon_state = "squirrel-orange" + +/datum/sprite_accessory/ears/squirrel_red + name = "squirrel, red" + desc = "" + icon_state = "squirrel-red" + +/datum/sprite_accessory/ears/bunny_white + name = "bunny, white" + desc = "" + icon_state = "bunny" + +/datum/sprite_accessory/ears/bear_brown + name = "bear, brown" + desc = "" + icon_state = "bear-brown" + +/datum/sprite_accessory/ears/wolf_grey + name = "wolf, grey" + desc = "" + icon_state = "wolf-grey" + +/datum/sprite_accessory/ears/wolf_green + name = "wolf, green" + desc = "" + icon_state = "wolf-green" + +/datum/sprite_accessory/ears/wisewolf + name = "wolf, wise" + desc = "" + icon_state = "wolf-wise" + +/datum/sprite_accessory/ears/mouse_grey + name = "mouse, grey" + desc = "" + icon_state = "mouse-grey" + +/datum/sprite_accessory/ears/bee + name = "bee antennae" + desc = "" + icon_state = "bee" + +/datum/sprite_accessory/ears/oni_h1 + name = "oni horns" + desc = "" + icon_state = "oni-h1" + +/datum/sprite_accessory/ears/demon_horns1 + name = "demon horns" + desc = "" + icon_state = "demon-horns1" + +/datum/sprite_accessory/ears/foxears + name = "highlander zorren ears" + desc = "" + icon_state = "foxears" + +/datum/sprite_accessory/ears/fenears + name = "flatland zorren ears" + desc = "" + icon_state = "fenears" + +/datum/sprite_accessory/ears/sergal + name = "Sergal ears" + icon_state = "serg_plain_s" + +/datum/sprite_accessory/ears/foxearshc + name = "highlander zorren ears, colorable" + desc = "" + icon_state = "foxearshc" + do_colouration = 1 + +/datum/sprite_accessory/ears/fenearshc + name = "flatland zorren ears, colorable" + desc = "" + icon_state = "fenearshc" + do_colouration = 1 + +/datum/sprite_accessory/ears/sergalhc + name = "Sergal ears, colorable" + icon_state = "serg_plain_s" + do_colouration = 1 + +/datum/sprite_accessory/ears/mousehc + name = "mouse, colorable" + desc = "" + icon_state = "mouse" + do_colouration = 1 + extra_overlay = "mouseinner" + +/datum/sprite_accessory/ears/wolfhc + name = "wolf, colorable" + desc = "" + icon_state = "wolf" + do_colouration = 1 + extra_overlay = "wolfinner" + +/datum/sprite_accessory/ears/bearhc + name = "bear, colorable" + desc = "" + icon_state = "bear" + do_colouration = 1 + +/datum/sprite_accessory/ears/squirrelhc + name = "squirrel, colorable" + desc = "" + icon_state = "squirrel" + do_colouration = 1 + +/datum/sprite_accessory/ears/kittyhc + name = "kitty, colorable" + desc = "" + icon_state = "kitty" + do_colouration = 1 + extra_overlay = "kittyinner" + +/datum/sprite_accessory/ears/bunnyhc + name = "bunny, colorable" + desc = "" + icon_state = "bunny" + do_colouration = 1 + +// Special snowflake ears go below here. + +/datum/sprite_accessory/ears/molenar_kitsune + name = "quintail kitsune ears (Molenar)" + desc = "" + icon_state = "molenar-kitsune" + ckeys_allowed = list("molenar") + +/datum/sprite_accessory/ears/molenar_deathclaw + name = "deathclaw ears (Molenar)" + desc = "" + icon_state = "molenar-deathclaw" + ckeys_allowed = list("molenar") + +/datum/sprite_accessory/ears/runac + name = "fennecsune ears (Runac)" + desc = "" + icon_state = "runac" + ckeys_allowed = list("rebcom1807") + +/datum/sprite_accessory/ears/kerena + name = "wingwolf ears (Kerena)" + desc = "" + icon_state = "kerena" + ckeys_allowed = list("somekindofpony") + +/datum/sprite_accessory/ears/rosey + name = "tritail kitsune ears (Rosey)" + desc = "" + icon_state = "rosey" + ckeys_allowed = list("joey4298") + +/datum/sprite_accessory/ears/aronai + name = "aronai ears/head (Aronai)" + desc = "" + icon_state = "aronai" + ckeys_allowed = list("arokha") + +/* +//////////////////////////// +/ =--------------------= / +/ == Tail Definitions == / +/ =--------------------= / +//////////////////////////// +*/ +/datum/sprite_accessory/tail + name = "You should not see this..." + icon = 'icons/mob/vore/tails_vr.dmi' + do_colouration = 0 //Set to 1 to enable coloration using the tail color. + + var/color_blend_mode = ICON_ADD // Only appliciable if do_coloration = 1 + var/extra_overlay // Icon state of an additional overlay to blend in. + var/show_species_tail = 0 // If false, do not render species' tail. + var/clothing_can_hide = 1 // If true, clothing with HIDETAIL hides it + var/desc = "You should not see this..." + +/datum/sprite_accessory/tail/invisible + name = "hide species-sprite tail" + icon = null + icon_state = null + +/datum/sprite_accessory/tail/squirrel_orange + name = "squirel, orange" + desc = "" + icon_state = "squirrel-orange" + +/datum/sprite_accessory/tail/squirrel_red + name = "squirrel, red" + desc = "" + icon_state = "squirrel-red" + +/datum/sprite_accessory/tail/squirrel + name = "squirrel, colorable" + desc = "" + icon_state = "squirrel" + do_colouration = 1 + +/datum/sprite_accessory/tail/kitty + name = "kitty, colorable, downwards" + desc = "" + icon_state = "kittydown" + do_colouration = 1 + +/datum/sprite_accessory/tail/kittyup + name = "kitty, colorable, upwards" + desc = "" + icon_state = "kittyup" + do_colouration = 1 + +/datum/sprite_accessory/tail/tiger_white + name = "tiger, colorable, white stripes" + desc = "" + icon_state = "tiger" + do_colouration = 1 + extra_overlay = "tigerinnerwhite" + +/datum/sprite_accessory/tail/tiger_black + name = "tiger, colorable, black stripes" + desc = "" + icon_state = "tiger" + do_colouration = 1 + extra_overlay = "tigerinnerblack" + +/datum/sprite_accessory/tail/stripey + name = "stripey taj, colorable" + desc = "" + icon_state = "stripeytail" + do_colouration = 1 + +/datum/sprite_accessory/tail/stripeytail_brown + name = "stripey taj, brown" + desc = "" + icon_state = "stripeytail-brown" + +/datum/sprite_accessory/tail/bunny + name = "bunny, colorable" + desc = "" + icon_state = "bunny" + do_colouration = 1 + +/datum/sprite_accessory/tail/mothc + name = "moth wings, colorable" + desc = "" + icon_state = "moth" + do_colouration = 1 + +/datum/sprite_accessory/tail/moth + name = "moth wings" + desc = "" + icon_state = "moth" + +/datum/sprite_accessory/tail/bear_brown + name = "bear, brown" + desc = "" + icon_state = "bear-brown" + +/datum/sprite_accessory/tail/bear + name = "bear, colorable" + desc = "" + icon_state = "bear" + do_colouration = 1 + +/datum/sprite_accessory/tail/wolf_grey + name = "wolf, grey" + desc = "" + icon_state = "wolf-grey" + +/datum/sprite_accessory/tail/wolf_green + name = "wolf, green" + desc = "" + icon_state = "wolf-green" + +/datum/sprite_accessory/tail/wisewolf + name = "wolf, wise" + desc = "" + icon_state = "wolf-wise" + +/datum/sprite_accessory/tail/blackwolf + name = "wolf, black" + desc = "" + icon_state = "wolf" + +/datum/sprite_accessory/tail/wolf + name = "wolf, colorable" + desc = "" + icon_state = "wolf" + do_colouration = 1 + extra_overlay = "wolfinner" + +/datum/sprite_accessory/tail/mouse_grey + name = "mouse, grey" + desc = "" + icon_state = "mouse-grey" + +/datum/sprite_accessory/tail/crossfox + name = "cross fox" + desc = "" + icon_state = "crossfox" + +/datum/sprite_accessory/tail/mouse + name = "mouse, colorable" + desc = "" + icon_state = "mouse" + do_colouration = 1 + extra_overlay = "mouseinner" + +/datum/sprite_accessory/tail/bee + name = "bee thorax (+wings)" + desc = "" + icon_state = "bee" + +/datum/sprite_accessory/tail/moth_full + name = "moth antenna and wings" + desc = "" + icon_state = "moth_full" + +/datum/sprite_accessory/tail/succubus_purple + name = "succubus, purple (+wings)" + desc = "" + icon_state = "succubus-purple" + +/datum/sprite_accessory/tail/succubus_red + name = "succubus, red (+wings)" + desc = "" + icon_state = "succubus-red" + +/datum/sprite_accessory/tail/succubus_black + name = "succubus, black (+wings)" + desc = "" + icon_state = "succubus-black" + +/datum/sprite_accessory/tail/bat_black + name = "bat wings, black" + desc = "" + icon_state = "bat-black" + show_species_tail = 1 + +/datum/sprite_accessory/tail/bat_red + name = "bat wings, red" + desc = "" + icon_state = "bat-red" + show_species_tail = 1 + +/datum/sprite_accessory/tail/snag + name = "xenomorph tail w/ backplate" + desc = "" + icon_state = "snag" + +/datum/sprite_accessory/tail/xenotail + name = "xenomorph tail" + desc = "" + icon_state = "xenotail" + +/datum/sprite_accessory/tail/molenar_kitsune + name = "quintail kitsune tails (Molenar)" + desc = "" + icon_state = "molenar-kitsune" + ckeys_allowed = list("molenar") + +/datum/sprite_accessory/tail/molenar_deathclaw + name = "deathclaw bits (Molenar)" + desc = "" + icon_state = "molenar-deathclaw" + ckeys_allowed = list("molenar","jertheace") + +/datum/sprite_accessory/tail/runac + name = "fennecsune tails (Runac)" + desc = "" + icon_state = "runac" + ckeys_allowed = list("rebcom1807") + +/datum/sprite_accessory/tail/kerena + name = "wingwolf tail (+wings) (Kerena)" + desc = "" + icon_state = "kerena" + ckeys_allowed = list("somekindofpony") + +/datum/sprite_accessory/tail/rosey + name = "tritail kitsune tails (Rosey)" + desc = "" + icon_state = "rosey" + ckeys_allowed = list("joey4298") + +/datum/sprite_accessory/tail/scree + name = "green taj tail (+wings) (Scree)" + desc = "" + icon_state = "scree" + ckeys_allowed = list("scree") + +/datum/sprite_accessory/tail/aronai + name = "aronai tail (Aronai)" + desc = "" + icon_state = "aronai" + ckeys_allowed = list("arokha") + +/datum/sprite_accessory/tail/feathered + name = "feathered wings" + desc = "" + icon_state = "feathered" + +//For all species tails. Includes haircolored tails. +/datum/sprite_accessory/tail/special + name = "Blank tail. Do not select." + icon = 'icons/effects/species_tails_vr.dmi' + +/datum/sprite_accessory/tail/special/unathi + name = "unathi tail" + desc = "" + icon_state = "sogtail_s" + +/datum/sprite_accessory/tail/special/tajaran + name = "tajaran tail" + desc = "" + icon_state = "tajtail_s" + +/datum/sprite_accessory/tail/special/sergal + name = "sergal tail" + desc = "" + icon_state = "sergtail_s" + +/datum/sprite_accessory/tail/special/akula + name = "akula tail" + desc = "" + icon_state = "sharktail_s" + +/datum/sprite_accessory/tail/special/nevrean + name = "nevrean tail" + desc = "" + icon_state = "nevreantail_s" + +/datum/sprite_accessory/tail/special/armalis + name = "armalis tail" + desc = "" + icon_state = "armalis_tail_humanoid_s" + +/datum/sprite_accessory/tail/special/xenodrone + name = "xenomorph drone tail" + desc = "" + icon_state = "xenos_drone_tail_s" + +/datum/sprite_accessory/tail/special/xenosentinel + name = "xenomorph sentinel tail" + desc = "" + icon_state = "xenos_sentinel_tail_s" + +/datum/sprite_accessory/tail/special/xenohunter + name = "xenomorph hunter tail" + desc = "" + icon_state = "xenos_hunter_tail_s" + +/datum/sprite_accessory/tail/special/xenoqueen + name = "xenomorph queen tail" + desc = "" + icon_state = "xenos_queen_tail_s" + +/datum/sprite_accessory/tail/special/monkey + name = "monkey tail" + desc = "" + icon_state = "chimptail_s" + +/datum/sprite_accessory/tail/special/seromitail + name = "seromi tail" + desc = "" + icon_state = "seromitail_s" + +/datum/sprite_accessory/tail/special/seromitailfeathered + name = "seromi tail w/ feathers" + desc = "" + icon_state = "seromitail_feathers_s" + +/datum/sprite_accessory/tail/special/unathihc + name = "unathi tail, colorable" + desc = "" + icon_state = "sogtail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/tajaranhc + name = "tajaran tail, colorable" + desc = "" + icon_state = "tajtail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/sergalhc + name = "sergal tail, colorable" + desc = "" + icon_state = "sergtail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/akulahc + name = "akula tail, colorable" + desc = "" + icon_state = "sharktail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/nevreanhc + name = "nevrean tail, colorable" + desc = "" + icon_state = "nevreantail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/foxhc + name = "highlander zorren tail, colorable" + desc = "" + icon_state = "foxtail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/fennechc + name = "flatland zorren tail, colorable" + desc = "" + icon_state = "fentail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/armalishc + name = "armalis tail, colorable" + desc = "" + icon_state = "armalis_tail_humanoid_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/xenodronehc + name = "xenomorph drone tail, colorable" + desc = "" + icon_state = "xenos_drone_tail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/xenosentinelhc + name = "xenomorph sentinel tail, colorable" + desc = "" + icon_state = "xenos_sentinel_tail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/xenohunterhc + name = "xenomorph hunter tail, colorable" + desc = "" + icon_state = "xenos_hunter_tail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/xenoqueenhc + name = "xenomorph queen tail, colorable" + desc = "" + icon_state = "xenos_queen_tail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/monkeyhc + name = "monkey tail, colorable, colorable" + desc = "" + icon_state = "chimptail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/seromitailhc + name = "seromi tail, colorable" + desc = "" + icon_state = "seromitail_hc_s" + do_colouration = 1 + +/datum/sprite_accessory/tail/special/seromitailfeatheredhc + name = "seromi tail w/ feathers, colorable" + desc = "" + icon_state = "seromitail_feathers_hc_s" + do_colouration = 1 + +/* +//////////////////////////// +/ =--------------------= / +/ == Taur Definitions == / +/ =--------------------= / +//////////////////////////// +*/ + +// Taur sprites are now a subtype of tail since they are mutually exclusive anyway. + +/datum/sprite_accessory/tail/taur + name = "You should not see this..." + icon = 'icons/mob/vore/taurs_vr.dmi' + do_colouration = 1 // Yes color, using tail color + color_blend_mode = ICON_MULTIPLY // The sprites for taurs are designed for ICON_MULTIPLY + +/datum/sprite_accessory/tail/taur/wolf + name = "Wolf" + icon_state = "wolf_s" + +/datum/sprite_accessory/tail/taur/naga + name = "Naga" + icon_state = "naga_s" + +/datum/sprite_accessory/tail/taur/horse + name = "Horse" + icon_state = "horse_s" + +/datum/sprite_accessory/tail/taur/cow + name = "Cow" + icon_state = "cow_s" + +/datum/sprite_accessory/tail/taur/lizard + name = "Lizard" + icon_state = "lizard_s" + +/datum/sprite_accessory/tail/taur/spider + name = "Spider" + icon_state = "spider_s" + +/datum/sprite_accessory/tail/taur/tents + name = "Tentacles" + icon_state = "tent_s" + + diff --git a/code/citadel/vore/appearance/update_icons_vr.dm b/code/citadel/vore/appearance/update_icons_vr.dm new file mode 100644 index 0000000000..0b34738c13 --- /dev/null +++ b/code/citadel/vore/appearance/update_icons_vr.dm @@ -0,0 +1,36 @@ + +#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur) + +/mob/living/carbon/human/proc/get_ears_overlay() + if(ear_style && !(head && (head.flags_inv & BLOCKHEADHAIR))) + var/icon/ears_s = new/icon("icon" = ear_style.icon, "icon_state" = ear_style.icon_state) + if(ear_style.do_colouration) + ears_s.Blend(rgb(src.r_hair, src.g_hair, src.b_hair), ear_style.color_blend_mode) + if(ear_style.extra_overlay) + var/icon/overlay = new/icon("icon" = ear_style.icon, "icon_state" = ear_style.extra_overlay) + ears_s.Blend(overlay, ICON_OVERLAY) + return ears_s + return null + + +/mob/living/carbon/human/proc/get_tail_image() + //If you are FBP with tail style + if(synthetic && synthetic.includes_tail) + var/icon/tail_s = new/icon("icon" = synthetic.icon, "icon_state" = "tail") + return image(tail_s) + + //If you have a custom tail selected + if(tail_style && !(wear_suit && wear_suit.flags_inv & HIDETAIL && !isTaurTail(tail_style))) + var/icon/tail_s = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.icon_state) + if(tail_style.do_colouration) + tail_s.Blend(rgb(src.r_tail, src.g_tail, src.b_tail), tail_style.color_blend_mode) + if(tail_style.extra_overlay) + var/icon/overlay = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.extra_overlay) + tail_s.Blend(overlay, ICON_OVERLAY) + qdel(overlay) + + if(isTaurTail(tail_style)) + return image(tail_s, "pixel_x" = -16) + else + return image(tail_s) + return null diff --git a/code/citadel/vore/eating/belly_vr.dm b/code/citadel/vore/eating/belly_vr.dm new file mode 100644 index 0000000000..6bd9f9db40 --- /dev/null +++ b/code/citadel/vore/eating/belly_vr.dm @@ -0,0 +1,419 @@ +// +// The belly object is what holds onto a mob while they're inside a predator. +// It takes care of altering the pred's decription, digesting the prey, relaying struggles etc. +// + +// If you change what variables are on this, then you need to update the copy() proc. + +// +// Parent type of all the various "belly" varieties. +// +/datum/belly + var/name // Name of this location + var/inside_flavor // Flavor text description of inside sight/sound/smells/feels. + var/vore_sound = 'sound/vore/gulp.ogg' // Sound when ingesting someone + var/vore_verb = "ingest" // Verb for eating with this in messages + var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human + var/nonhuman_prey_swallow_time = 100 // Time in deciseconds to swallow anything else + var/emoteTime = 600 // How long between stomach emotes at prey + var/digest_brute = 1 // Brute damage per tick in digestion mode + var/digest_burn = 1 // Burn damage per tick in digestion mode + var/digest_tickrate = 3 // Modulus this of air controller tick number to iterate gurgles on + var/immutable = 0 // Prevents this belly from being deleted + var/integrity = 100 // Gut 'health' weakened by non help intent stuggles + var/escapable = 0 // Belly can be resisted out of at any time + var/escapetime = 600 // Deciseconds, how long to escape this belly + + var/tmp/digest_mode = DM_HOLD // Whether or not to digest. Default to not digest. + var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_DIGESTF) // Possible digest modes + var/tmp/mob/living/owner // The mob whose belly this is. + var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly! + var/tmp/is_full // Flag for if digested remeans are present. (for disposal messages) + var/tmp/emotePend = 0 // If there's already a spawned thing counting for the next emote + var/tmp/recent_struggle = 0 // Flag to prevent struggle emote spam + // Don't forget to watch your commas at the end of each line if you change these. + var/datum/gas_mixture/air_contents = new() // Belly Air stuff + + var/list/struggle_messages_outside = list( + "%pred's %belly wobbles with a squirming meal.", + "%pred's %belly jostles with movement.", + "%pred's %belly briefly swells outward as someone pushes from inside.", + "%pred's %belly fidgets with a trapped victim.", + "%pred's %belly jiggles with motion from inside.", + "%pred's %belly sloshes around.", + "%pred's %belly gushes softly.", + "%pred's %belly lets out a wet squelch.") + + var/list/struggle_messages_inside = list( + "Your useless squirming only causes %pred's slimy %belly to squelch over your body.", + "Your struggles only cause %pred's %belly to gush softly around you.", + "Your movement only causes %pred's %belly to slosh around you.", + "Your motion causes %pred's %belly to jiggle.", + "You fidget around inside of %pred's %belly.", + "You shove against the walls of %pred's %belly, making it briefly swell outward.", + "You jostle %pred's %belly with movement.", + "You squirm inside of %pred's %belly, making it wobble around.") + + var/list/digest_messages_owner = list( + "You feel %prey's body succumb to your digestive system, which breaks it apart into soft slurry.", + "You hear a lewd glorp as your %belly muscles grind %prey into a warm pulp.", + "Your %belly lets out a rumble as it melts %prey into sludge.", + "You feel a soft gurgle as %prey's body loses form in your %belly. They're nothing but a soft mass of churning slop now.", + "Your %belly begins gushing %prey's remains through your system, adding some extra weight to your thighs.", + "Your %belly begins gushing %prey's remains through your system, adding some extra weight to your rump.", + "Your %belly begins gushing %prey's remains through your system, adding some extra weight to your belly.", + "Your %belly groans as %prey falls apart into a thick soup. You can feel their remains soon flowing deeper into your body to be absorbed.", + "Your %belly kneads on every fiber of %prey, softening them down into mush to fuel your next hunt.", + "Your %belly churns %prey down into a hot slush. You can feel the nutrients coursing through your digestive track with a series of long, wet glorps.") + + var/list/digest_messages_prey = list( + "Your body succumbs to %pred's digestive system, which breaks you apart into soft slurry.", + "%pred's %belly lets out a lewd glorp as their muscles grind you into a warm pulp.", + "%pred's %belly lets out a rumble as it melts you into sludge.", + "%pred feels a soft gurgle as your body loses form in their %belly. You're nothing but a soft mass of churning slop now.", + "%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's thighs.", + "%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's rump.", + "%pred's %belly begins gushing your remains through their system, adding some extra weight to %pred's belly.", + "%pred's %belly groans as you fall apart into a thick soup. Your remains soon flow deeper into %pred's body to be absorbed.", + "%pred's %belly kneads on every fiber of your body, softening you down into mush to fuel their next hunt.", + "%pred's %belly churns you down into a hot slush. Your nutrient-rich remains course through their digestive track with a series of long, wet glorps.") + + var/list/examine_messages = list( + "They have something solid in their %belly!", + "It looks like they have something in their %belly!") + + //Mostly for being overridden on precreated bellies on mobs. Could be VV'd into + //a carbon's belly if someone really wanted. No UI for carbons to adjust this. + //List has indexes that are the digestion mode strings, and keys that are lists of strings. + var/list/emote_lists = list() + +// Constructor that sets the owning mob +/datum/belly/New(var/mob/living/owning_mob) + owner = owning_mob + +// Toggle digestion on/off and notify user of the new setting. +// If multiple digestion modes are avaliable (i.e. unbirth) then user should be prompted. +/datum/belly/proc/toggle_digestion() + return + +// Checks if any mobs are present inside the belly +// return True if the belly is empty. +/datum/belly/proc/is_empty() + return internal_contents.len == 0 + +// Release all contents of this belly into the owning mob's location. +// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in. +// Returns the number of mobs so released. +/datum/belly/proc/release_all_contents() + for (var/atom/movable/M in internal_contents) + M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner. + internal_contents -= M // Remove from the belly contents + + var/datum/belly/B = check_belly(owner) // This makes sure that the mob behaves properly if released into another mob + if(B) + B.internal_contents += M + + owner.visible_message("[owner] expels everything from their [lowertext(name)]!") + return 1 + +// Release a specific atom from the contents of this belly into the owning mob's location. +// If that location is another mob, the atom is transferred into whichever of its bellies the owning mob is in. +// Returns the number of atoms so released. +/datum/belly/proc/release_specific_contents(var/atom/movable/M) + if (!(M in internal_contents)) + return 0 // They weren't in this belly anyway + + M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner. + src.internal_contents -= M // Remove from the belly contents + + var/datum/belly/B = check_belly(owner) + if(B) + B.internal_contents += M + + owner.visible_message("[owner] expels [M] from their [lowertext(name)]!") + owner.update_icons() + return 1 + +// Actually perform the mechanics of devouring the tasty prey. +// The purpose of this method is to avoid duplicate code, and ensure that all necessary +// steps are taken. +/datum/belly/proc/nom_mob(var/mob/prey, var/mob/user) +// if (prey.buckled) +// prey.buckled.unbuckle_mob() + +// Super super messy. prey.forceMove.owner doesn't work if there's no prey. + prey.loc = owner + internal_contents |= prey + + if(inside_flavor) + prey << "[inside_flavor]" + +// Get the line that should show up in Examine message if the owner of this belly +// is examined. By making this a proc, we not only take advantage of polymorphism, +// but can easily make the message vary based on how many people are inside, etc. +// Returns a string which shoul be appended to the Examine output. +/datum/belly/proc/get_examine_msg() + if(internal_contents.len && examine_messages.len) + var/formatted_message + var/raw_message = pick(examine_messages) + + formatted_message = replacetext(raw_message,"%belly",lowertext(name)) + + return("[formatted_message]
") + +// The next function gets the messages set on the belly, in human-readable format. +// This is useful in customization boxes and such. The delimiter right now is \n\n so +// in message boxes, this looks nice and is easily delimited. +/datum/belly/proc/get_messages(var/type, var/delim = "\n\n") + ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em") + var/list/raw_messages + + switch(type) + if("smo") + raw_messages = struggle_messages_outside + if("smi") + raw_messages = struggle_messages_inside + if("dmo") + raw_messages = digest_messages_owner + if("dmp") + raw_messages = digest_messages_prey + if("em") + raw_messages = examine_messages + + var/messages = list2text(raw_messages,delim) + return messages + +// The next function sets the messages on the belly, from human-readable var +// replacement strings and linebreaks as delimiters (two \n\n by default). +// They also sanitize the messages. +/datum/belly/proc/set_messages(var/raw_text, var/type, var/delim = "\n\n") + ASSERT(type == "smo" || type == "smi" || type == "dmo" || type == "dmp" || type == "em") + + var/list/raw_list = text2list(html_encode(raw_text),delim) + if(raw_list.len > 10) + raw_list.Cut(11) + log_attack("[owner] tried to set [name] with 11+ messages") + + for(var/i = 1, i <= raw_list.len, i++) + if(length(raw_list[i]) > 160 || length(raw_list[i]) < 10) //160 is fudged value due to htmlencoding increasing the size + raw_list.Cut(i,i) + log_attack("[owner] tried to set [name] with >121 or <10 char message") + else + raw_list[i] = readd_quotes(raw_list[i]) + //Also fix % sign for var replacement + raw_list[i] = replacetext(raw_list[i],"%","%") + + ASSERT(raw_list.len <= 10) //Sanity + + switch(type) + if("smo") + struggle_messages_outside = raw_list + if("smi") + struggle_messages_inside = raw_list + if("dmo") + digest_messages_owner = raw_list + if("dmp") + digest_messages_prey = raw_list + if("em") + examine_messages = raw_list + + return + +// Handle the death of a mob via digestion. +// Called from the process_Life() methods of bellies that digest prey. +// Default implementation calls M.death() and removes from internal contents. +// Indigestable items are removed, and M is deleted. +/datum/belly/proc/digestion_death(var/mob/living/M, var/mob/prey, var/mob/pred) + is_full = 1 + M.death(1) + internal_contents -= M + + // If digested prey is also a pred... anyone inside their bellies gets moved up. + if (is_vore_predator(M)) + for (var/bellytype in M.vore_organs) + var/datum/belly/belly = M.vore_organs[bellytype] + for (var/obj/SubPrey in belly.internal_contents) + SubPrey.forceMove(owner) + internal_contents += SubPrey + SubPrey << "As [M] melts away around you, you find yourself in [owner]'s [name]" + + //Drop all items into the belly. + if (config.items_survive_digestion) + for (var/obj/item/W in M) + _handle_digested_item(W) + + //Reagent transfer + if(M.reagents && istype(M.reagents,/datum/reagents)) + var/datum/reagents/RL = M.reagents + RL.trans_to(owner,RL.total_volume*0.5) + + // Delete the digested mob + message_admins("[key_name(pred)] digested [key_name(prey)].") + log_attack("[key_name(pred)] digested [key_name(prey)].") + qdel(M) + +// Recursive method - To recursively scan thru someone's inventory for digestable/indigestable. +/datum/belly/proc/_handle_digested_item(var/obj/item/W) + W.forceMove(owner) + internal_contents += W + +/datum/belly/proc/_is_digestable(var/obj/item/I) + return 1 + +//Handle a mob struggling +// Called from /mob/living/carbon/relaymove() +/datum/belly/proc/relay_resist(var/mob/living/R) + var/struggle_outer_message = pick(struggle_messages_outside) + var/struggle_user_message = pick(struggle_messages_inside) + if (!(R in internal_contents)) + return // User is not in this belly, or struggle too soon. + +// R.setClickCooldown(50) + + if(owner.stat || escapable) //If owner is stat (dead, KO) we can actually escape, or if belly is set to escapable (non-default) + R << "You attempt to climb out of \the [name]. (This will take around [escapetime/10] seconds.)" + owner << "Someone is attempting to climb out of your [name]!" + + if(do_after(R, escapetime, owner)) + if((owner.stat || escapable) && (R in internal_contents)) //Can still escape? + release_specific_contents(R) + return + else if(!(R in internal_contents)) //Aren't even in the belly. Quietly fail. + return + else //Belly became inescapable or mob revived + R << "Your attempt to escape [name] has failed!" + owner << "The attempt to escape from your [name] has failed!" + return + return + + struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner) + struggle_outer_message = replacetext(struggle_outer_message,"%prey",R) + struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name)) + + struggle_user_message = replacetext(struggle_user_message,"%pred",owner) + struggle_user_message = replacetext(struggle_user_message,"%prey",R) + struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name)) + + struggle_outer_message = "" + struggle_outer_message + "" + struggle_user_message = "" + struggle_user_message + "" + + for(var/mob/M in hearers(4, owner)) + M.show_message(struggle_outer_message, 2) // hearable + R << struggle_user_message + var/strpick = pick(struggle_sounds) + var/strsound = struggle_sounds[strpick] + playsound(R.loc, strsound, 50, 1) + +/datum/belly/proc/relaymove(var/mob/living/R) + var/struggle_outer_message = pick(struggle_messages_outside) + var/struggle_user_message = pick(struggle_messages_inside) + var/strpick = pick(struggle_sounds) + var/strsound = struggle_sounds[strpick] + + if(!(R in internal_contents) || recent_struggle) + return // User is not in this belly, or struggle too soon. + + if(R in internal_contents && R.a_intent == "help") + recent_struggle = 1 + spawn(30) + recent_struggle = 0 + + struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner) + struggle_outer_message = replacetext(struggle_outer_message,"%prey",R) + struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name)) + + struggle_user_message = replacetext(struggle_user_message,"%pred",owner) + struggle_user_message = replacetext(struggle_user_message,"%prey",R) + struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name)) + + struggle_outer_message = "" + struggle_outer_message + "" + struggle_user_message = "" + struggle_user_message + "" + + for(var/mob/M in hearers(4, owner)) + M.show_message(struggle_outer_message, 2) // hearable + R << struggle_user_message + + playsound(R.loc, strsound, 50, 1) + + else if(!(R in internal_contents && R.a_intent == "help")) + integrity -= 15 + recent_struggle = 1 + spawn(15) // there's a want to get out, so faster + recent_struggle = 0 + + struggle_outer_message = replacetext(struggle_outer_message,"%pred",owner) + struggle_outer_message = replacetext(struggle_outer_message,"%prey",R) + struggle_outer_message = replacetext(struggle_outer_message,"%belly",lowertext(name)) + + struggle_user_message = replacetext(struggle_user_message,"%pred",owner) + struggle_user_message = replacetext(struggle_user_message,"%prey",R) + struggle_user_message = replacetext(struggle_user_message,"%belly",lowertext(name)) + + struggle_outer_message = "" + struggle_outer_message + "" + struggle_user_message = "" + struggle_user_message + "" + + for(var/mob/M in hearers(4, owner)) + M.show_message(struggle_outer_message, 2) // hearable + R << struggle_user_message + playsound(R.loc, strsound, 50, 1) + + if(integrity<=0) + release_specific_contents(R) + integrity=0 + owner.Stun(rand(2,4)) + playsound(R.loc, 'sound/vore/StomachTransfer.ogg', 50, 1) + +// Belly copies and then returns the copy +// Needs to be updated for any var changes +/datum/belly/proc/copy(mob/new_owner) + var/datum/belly/dupe = new /datum/belly(new_owner) + + //// Non-object variables + dupe.name = name + dupe.inside_flavor = inside_flavor + dupe.vore_sound = vore_sound + dupe.vore_verb = vore_verb + dupe.human_prey_swallow_time = human_prey_swallow_time + dupe.nonhuman_prey_swallow_time = nonhuman_prey_swallow_time + dupe.emoteTime = emoteTime + dupe.digest_brute = digest_brute + dupe.digest_burn = digest_burn + dupe.digest_tickrate = digest_tickrate + dupe.immutable = immutable + dupe.escapable = escapable + dupe.escapetime = escapetime + + //// Object-holding variables + //struggle_messages_outside - strings + dupe.struggle_messages_outside.Cut() + for(var/I in struggle_messages_outside) + dupe.struggle_messages_outside += I + + //struggle_messages_inside - strings + dupe.struggle_messages_inside.Cut() + for(var/I in struggle_messages_inside) + dupe.struggle_messages_inside += I + + //digest_messages_owner - strings + dupe.digest_messages_owner.Cut() + for(var/I in digest_messages_owner) + dupe.digest_messages_owner += I + + //digest_messages_prey - strings + dupe.digest_messages_prey.Cut() + for(var/I in digest_messages_prey) + dupe.digest_messages_prey += I + + //examine_messages - strings + dupe.examine_messages.Cut() + for(var/I in examine_messages) + dupe.examine_messages += I + + //emote_lists - index: digest mode, key: list of strings + dupe.emote_lists.Cut() + for(var/K in emote_lists) + dupe.emote_lists[K] = list() + for(var/I in emote_lists[K]) + dupe.emote_lists[K] += I + + return dupe diff --git a/code/citadel/vore/eating/bellymodes_vr.dm b/code/citadel/vore/eating/bellymodes_vr.dm new file mode 100644 index 0000000000..afb437ce39 --- /dev/null +++ b/code/citadel/vore/eating/bellymodes_vr.dm @@ -0,0 +1,127 @@ +// Process the predator's effects upon the contents of its belly (i.e digestion/transformation etc) +// Called from /mob/living/Life() proc. +/datum/belly/proc/process_Life() + +/////////////////////////// Auto-Emotes /////////////////////////// + if((digest_mode in emote_lists) && !emotePend) + emotePend = 1 + + spawn(emoteTime) + var/list/EL = emote_lists[digest_mode] + for(var/mob/living/M in internal_contents) + M << "[pick(EL)]" + src.emotePend = 0 + +//////////////////////////////Integrity regeneration //////////////// + integrity=min(integrity+8,100) + +///////////////////////////// DM_HOLD ///////////////////////////// + if(digest_mode == DM_HOLD) + return //Pretty boring, huh + +//////////////////////////// DM_DIGEST //////////////////////////// + if(digest_mode == DM_DIGEST) + + if(prob(50)) + var/churnsound = pick(digestion_sounds) + for(var/mob/hearer in range(1,owner)) + hearer << sound(churnsound,volume=60) + + for (var/mob/living/M in internal_contents) + //Pref protection! + if (!M.digestable) + continue + + //Person just died in guts! + if(M.stat == DEAD && M.getFireLoss() >= 150) + var/digest_alert_owner = pick(digest_messages_owner) + var/digest_alert_prey = pick(digest_messages_prey) + + //Replace placeholder vars + digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner) + digest_alert_owner = replacetext(digest_alert_owner,"%prey",M) + digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name)) + + digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner) + digest_alert_prey = replacetext(digest_alert_prey,"%prey",M) + digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name)) + + //Send messages + owner << "" + digest_alert_owner + "" + M << "" + digest_alert_prey + "" + + owner.nutrition += 400 // so eating dead mobs gives you *something*. + var/deathsound = pick(death_sounds) + for(var/mob/hearer in range(1,owner)) + hearer << deathsound + digestion_death(M) + continue + + // Deal digestion damage (and feed the pred) + if(!(M.status_flags & GODMODE)) + M.adjustBruteLoss(1) + M.adjustFireLoss(1) + owner.nutrition += 10 + return + +//////////////////////////// DM_DIGESTF //////////////////////////// + if(digest_mode == DM_DIGESTF) + + if(prob(50)) + var/churnsound = pick(digestion_sounds) + for(var/mob/hearer in range(1,owner)) + hearer << sound(churnsound,volume=80) + + for (var/mob/living/M in internal_contents) + //Pref protection! + if (!M.digestable) + continue + + //Person just died in guts! + if(M.stat == DEAD && M.getFireLoss() >= 150) + var/digest_alert_owner = pick(digest_messages_owner) + var/digest_alert_prey = pick(digest_messages_prey) + + //Replace placeholder vars + digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner) + digest_alert_owner = replacetext(digest_alert_owner,"%prey",M) + digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name)) + + digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner) + digest_alert_prey = replacetext(digest_alert_prey,"%prey",M) + digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name)) + + //Send messages + owner << "" + digest_alert_owner + "" + M << "" + digest_alert_prey + "" + + owner.nutrition += 400 // so eating dead mobs gives you *something*. + var/deathsound = pick(death_sounds) + for(var/mob/hearer in range(1,owner)) + hearer << deathsound + digestion_death(M) + continue + + // Deal digestion damage (and feed the pred) + if(!(M.status_flags & GODMODE)) + M.adjustBruteLoss(2) + M.adjustFireLoss(3) + owner.nutrition += 10 + return + +///////////////////////////// DM_HEAL ///////////////////////////// + if(digest_mode == DM_HEAL) + if(prob(50)) //Wet heals! + var/healsound = pick(digestion_sounds) + for(var/mob/hearer in range(1,owner)) + hearer << sound(healsound,volume=80) + + for (var/mob/living/M in internal_contents) + if(M.stat != DEAD) + if(owner.nutrition > 90 && (M.health < M.maxHealth)) + M.adjustBruteLoss(-2) + M.adjustFireLoss(-2) + owner.nutrition -= 2 + if(M.nutrition <= 400) + M.nutrition += 1 + return \ No newline at end of file diff --git a/code/citadel/vore/eating/living_vr.dm b/code/citadel/vore/eating/living_vr.dm new file mode 100644 index 0000000000..a768b01f54 --- /dev/null +++ b/code/citadel/vore/eating/living_vr.dm @@ -0,0 +1,341 @@ +///////////////////// Mob Living ///////////////////// +/mob/living + var/digestable = 1 // Can the mob be digested inside a belly? + var/datum/belly/vore_selected // Default to no vore capability. + var/list/vore_organs = list() // List of vore containers inside a mob + var/recent_struggle = 0 +// +// Hook for generic creation of stuff on new creatures +// +/hook/living_new/proc/vore_setup(mob/living/M) + M.verbs += /mob/living/proc/insidePanel + M.verbs += /mob/living/proc/escapeOOC + + //Tries to load prefs if a client is present otherwise gives freebie stomach + if(!M.vore_organs || !M.vore_organs.len) + spawn(20) //Wait a couple of seconds to make sure copy_to or whatever has gone + if(!M) return + + /* if(M.client && M.client.prefs) + if(!M.load_vore_preferences) + M << "ERROR: You seem to have saved prefs, but they couldn't be loaded." + return 0 + if(M.vore_organs && M.vore_organs.len) + M.vore_selected = M.vore_organs[1] */ + + if(!M.vore_organs || !M.vore_organs.len) + if(!M.vore_organs) + M.vore_organs = list() + var/datum/belly/B = new /datum/belly(M) + B.immutable = 1 + B.name = "Stomach" + B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]." + M.vore_organs[B.name] = B + M.vore_selected = B.name + + //Simple_animal gets emotes. move this to that hook instead? + if(istype(src,/mob/living/simple_animal)) + B.emote_lists[DM_HOLD] = list( + "The insides knead at you gently for a moment.", + "The guts glorp wetly around you as some air shifts.", + "Your predator takes a deep breath and sighs, shifting you somewhat.", + "The stomach squeezes you tight for a moment, then relaxes.", + "During a moment of quiet, breathing becomes the most audible thing.", + "The warm slickness surrounds and kneads on you.") + + B.emote_lists[DM_DIGEST] = list( + "The caustic acids eat away at your form.", + "The acrid air burns at your lungs.", + "Without a thought for you, the stomach grinds inwards painfully.", + "The guts treat you like food, squeezing to press more acids against you.", + "The onslaught against your body doesn't seem to be letting up; you're food now.", + "The insides work on you like they would any other food.") + + //Return 1 to hook-caller + return 1 + +// +// Handle being clicked, perhaps with something to devour +// + + // Refactored to use centralized vore code system - Leshana + + // Critical adjustments due to TG grab changes - Poojawa + +/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey) + if(!user) + return + if(!prey) + return + if(prey==user) + return + if(prey == src && user.zone_selected == "mouth") //you click your target + if(!is_vore_predator(prey)) + user << "They aren't voracious enough." + feed_self_to_grabbed(user) + + if( user == src ) //you click yourself + if(!is_vore_predator(src)) + user << "You aren't voracious enough." + feed_grabbed_to_self(prey, user) + + else // click someone other than you/prey + if(!is_vore_predator(src)) + user << "They aren't voracious enough." + return + feed_grabbed_to_other(user) +// +// Eating procs depending on who clicked what +// +/mob/living/proc/feed_grabbed_to_self(var/mob/living/user, var/mob/living/prey) + var/belly = user.vore_selected + return perform_the_nom(prey, user, prey, belly) +/* +/mob/living/proc/eat_held_mob(var/mob/living/user, var/mob/living/prey, var/mob/living/pred) + var/belly + if(user != pred) + belly = input("Choose Belly") in pred.vore_organs + else + belly = pred.vore_selected + return perform_the_nom(user, prey, pred, belly)*/ + +/mob/living/proc/feed_self_to_grabbed(var/mob/living/user, var/mob/living/pred) + var/belly = input("Choose Belly") in pred.vore_organs + return perform_the_nom(user, user, pred, belly) + +/mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred) + return//disabled until further notice + var/belly = input("Choose Belly") in pred.vore_organs + return perform_the_nom(user, prey, pred, belly) + +// +// Master vore proc that actually does vore procedures +// + +/mob/living/proc/perform_the_nom(var/mob/living/user, var/mob/living/prey, var/mob/living/pred, var/belly, swallow_time = 100) + //Sanity + if(!user || !prey || !pred || !belly || !(belly in pred.vore_organs)) + log_attack("[user] attempted to feed [prey] to [pred], via [belly] but it went wrong.") + return + // The belly selected at the time of noms + var/datum/belly/belly_target = pred.vore_organs[belly] + var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (at)" + var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)" + + // Prepare messages + if(user == pred) //Feeding someone to yourself + attempt_msg = text("[] is attemping to [] [] into their []!",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name)) + success_msg = text("[] manages to [] [] into their []!",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name)) + else //Feeding someone to another person + attempt_msg = text("[] is attempting to make [] [] [] into their []!",user,pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name)) + success_msg = text("[] manages to make [] [] [] into their []!",user,pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name)) + + // Announce that we start the attempt! + user.visible_message(attempt_msg) + + // Now give the prey time to escape... return if they did + + if(!do_mob(src, user, swallow_time)) + return 0 // Prey escpaed (or user disabled) before timer expired. + + // If we got this far, nom successful! Announce it! + user.visible_message(success_msg) + playsound(user, belly_target.vore_sound, 100, 1) + + // Actually shove prey into the belly. + belly_target.nom_mob(prey, user) +// user.update_icons() + stop_pulling() + + // Inform Admins + if (pred == user) + message_admins("[key_name(pred)] ate [key_name(prey)]. ([pred ? "JMP" : "null"])") + log_attack("[key_name(pred)] ate [key_name(prey)]") + else if (prey == !client && stat != DEAD) + message_admins("[key_name(pred)] ate [key_name(prey)] (braindead) ([pred ? "JMP" : "null"])") + log_attack("[key_name(pred)] ate [key_name(prey)] (braindead)") + else + message_admins("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)]. ([pred ? "JMP" : "null"])") + log_attack("[key_name(user)] forced [key_name(pred)] to eat [key_name(prey)].") + return 1 + +// +//End vore code. +/* + //Handle case: /obj/item/weapon/holder + if(/obj/item/weapon/holder/micro) + var/obj/item/weapon/holder/H = I + + if(!isliving(user)) return 0 // Return 0 to continue upper procs + var/mob/living/attacker = user // Typecast to living + + if (is_vore_predator(src)) + for (var/mob/living/M in H.contents) + attacker.eat_held_mob(attacker, M, src) + return 1 //Return 1 to exit upper procs + else + log_attack("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it failed.") + + // I just can't imagine this not being complained about + //Handle case: /obj/item/device/radio/beacon + if(/obj/item/device/radio/beacon) + var/confirm = alert(user, "[src == user ? "Eat the beacon?" : "Feed the beacon to [src]?"]", "Confirmation", "Yes!", "Cancel") + if(confirm == "Yes!") + var/bellychoice = input("Which belly?","Select A Belly") in src.vore_organs + var/datum/belly/B = src.vore_organs[bellychoice] + src.visible_message("[user] is trying to stuff a beacon into [src]'s [bellychoice]!","[user] is trying to stuff a beacon into you!") + if(do_after(user,30,src)) + user.drop_item() + I.loc = src + B.internal_contents += I + src.visible_message("[src] is fed the beacon!","You're fed the beacon!") + playsound(src, B.vore_sound, 100, 1) + return 1 + else + return 1 //You don't get to hit someone 'later' + + return 0 +*/ +// +// Custom resist catches for /mob/living +// +/mob/living/proc/vore_process_resist() + + //Are we resisting from inside a belly? + var/datum/belly/B = check_belly(src) + if(B) + spawn() B.relay_resist(src) + return TRUE //resist() on living does this TRUE thing. + + //Other overridden resists go here + + + return 0 + + +// +// Proc for updating vore organs and digestion/healing/absorbing +// +/mob/living/proc/handle_internal_contents() + if(SSair.times_fired%3 != 1) + return //The accursed timer + + for (var/I in vore_organs) + var/datum/belly/B = vore_organs[I] + if(B.internal_contents.len) + B.process_Life() //AKA 'do bellymodes_vr.dm' + + if(SSair.times_fired%3 != 1) return //Occasionally do supercleanups. + for (var/I in vore_organs) + var/datum/belly/B = vore_organs[I] + if(B.internal_contents.len) + for(var/atom/movable/M in B.internal_contents) + if(M.loc != src) + B.internal_contents -= M + log_attack("Had to remove [M] from belly [B] in [src]") +/* +// +// Verb for saving vore preferences to save file +// +/mob/living/proc/save_vore_prefs() + if(!(client || client.prefs_vr)) + return 0 + if(!copy_to_prefs_vr()) + return 0 + if(!client.prefs_vr.save_vore()) + return 0 + + return 1 + +/mob/living/proc/apply_vore_prefs() + if(!(client || client.prefs_vr)) + return 0 + if(!client.prefs_vr.load_vore()) + return 0 + if(!copy_from_prefs_vr()) + return 0 + + return 1 + +/mob/living/proc/copy_to_prefs_vr() + if(!client || !client.prefs_vr) + src << "You attempted to save your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev." + return 0 + + var/datum/vore_preferences/P = client.prefs_vr + + P.digestable = src.digestable + P.belly_prefs = src.vore_organs + + return 1 + +// +// Proc for applying vore preferences, given bellies +// +/mob/living/proc/copy_from_prefs_vr() + if(!client || !client.prefs_vr) + src << "You attempted to apply your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev." + return 0 + + var/datum/vore_preferences/P = client.prefs_vr + + src.digestable = P.digestable + src.vore_organs = list() + + for(var/I in P.belly_prefs) + var/datum/belly/Bp = P.belly_prefs[I] + src.vore_organs[Bp.name] = Bp.copy(src) + + return 1 +*/ +// +// Verb for saving vore preferences to save file +// +/mob/living/proc/save_vore_prefs() + set name = "Save Vore Prefs" + set category = "Vore" + + var/result = 0 + + if(client.prefs) + result = client.prefs.save_vore_preferences() + else + src << "You attempted to save your vore prefs but somehow you're in this character without a client.prefs variable. Tell a dev." + log_admin("[src] tried to save vore prefs but lacks a client.prefs var.") + + return result + +// +// Proc for applying vore preferences, given bellies +// +/mob/living/proc/apply_vore_prefs(var/list/bellies) + if(!bellies || bellies.len == 0) + log_admin("Tried to apply bellies to [src] and failed.") + + +// +// OOC Escape code for pref-breaking or AFK preds +// +/mob/living/proc/escapeOOC() + set name = "Animal Escape" + set category = "Vore" + + //You're in an animal! + if(istype(src.loc,/mob/living/simple_animal)) + var/mob/living/simple_animal/pred = src.loc + var/confirm = alert(src, "You're in a mob. Use this as a trick to get out of hostile animals. If you are in more than one pred, use this more than once.", "Confirmation", "Okay", "Cancel") + if(confirm == "Okay") + for(var/I in pred.vore_organs) + var/datum/belly/B = pred.vore_organs[I] + B.release_specific_contents(src) + + for(var/mob/living/simple_animal/SA in range(10)) + SA.prey_excludes += src + spawn(18000) + if(src && SA) + SA.prey_excludes -= src + + pred.update_icons() + + else + src << "You aren't inside anything, you clod." diff --git a/code/citadel/vore/eating/simple_animal_vr.dm b/code/citadel/vore/eating/simple_animal_vr.dm new file mode 100644 index 0000000000..33417331f5 --- /dev/null +++ b/code/citadel/vore/eating/simple_animal_vr.dm @@ -0,0 +1,39 @@ +///////////////////// Simple Animal ///////////////////// +/mob/living/simple_animal + var/isPredator = 0 //Are they capable of performing and pre-defined vore actions for their species? + var/swallowTime = 30 //How long it takes to eat its prey in 1/10 of a second. The default is 3 seconds. + var/list/prey_excludes = list() //For excluding people from being eaten. + +// +// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs. +/* +/mob/living/proc/animal_nom(var/mob/living/T in oview(1)) + set name = "Animal Nom" + set category = "Vore" + set desc = "Since you can't grab, you get a verb!" + + feed_grabbed_to_self(src,T) +*/ +// +// Simple proc for animals to have their digestion toggled on/off externally +// +/mob/living/simple_animal/verb/toggle_digestion() + set name = "Toggle Animal's Digestion" + set desc = "Enables digestion on this mob for 20 minutes." + set category = "Vore" + set src in oview(1) + + var/datum/belly/B = vore_organs[vore_selected] + if(faction != usr.faction) + usr << "This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you." + return + if(B.digest_mode == "Hold") + var/confirm = alert(usr, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will disable itself after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel") + if(confirm == "Enable") + B.digest_mode = "Digest" + spawn(12000) //12000=20 minutes + if(src) B.digest_mode = "Hold" + else + var/confirm = alert(usr, "This mob is currently set to digest all stomach contents. Do you want to disable this?", "Disabling [name]'s Digestion", "Disable", "Cancel") + if(confirm == "Disable") + B.digest_mode = "Hold" \ No newline at end of file diff --git a/code/citadel/vore/eating/vore_vr.dm b/code/citadel/vore/eating/vore_vr.dm new file mode 100644 index 0000000000..b506147799 --- /dev/null +++ b/code/citadel/vore/eating/vore_vr.dm @@ -0,0 +1,123 @@ + +/* +VVVVVVVV VVVVVVVV OOOOOOOOO RRRRRRRRRRRRRRRRR EEEEEEEEEEEEEEEEEEEEEE +V::::::V V::::::V OO:::::::::OO R::::::::::::::::R E::::::::::::::::::::E +V::::::V V::::::V OO:::::::::::::OO R::::::RRRRRR:::::R E::::::::::::::::::::E +V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEEE::::E + V:::::V V:::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE + V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E:::::E + V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E::::::EEEEEEEEEE + V:::::V V:::::V O:::::O O:::::O R:::::::::::::RR E:::::::::::::::E + V:::::V V:::::V O:::::O O:::::O R::::RRRRRR:::::R E:::::::::::::::E + V:::::V V:::::V O:::::O O:::::O R::::R R:::::R E::::::EEEEEEEEEE + V:::::V:::::V O:::::O O:::::O R::::R R:::::R E:::::E + V:::::::::V O::::::O O::::::O R::::R R:::::R E:::::E EEEEEE + V:::::::V O:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEEEE:::::E + V:::::V OO:::::::::::::OO R::::::R R:::::RE::::::::::::::::::::E + V:::V OO:::::::::OO R::::::R R:::::RE::::::::::::::::::::E + VVV OOOOOOOOO RRRRRRRR RRRRRRREEEEEEEEEEEEEEEEEEEEEE + +-Aro <3 */ + +// +// Overrides/additions to stock defines go here, as well as hooks. Sort them by +// the object they are overriding. So all /mob/living together, etc. +// +/datum/configuration + var/items_survive_digestion = 1 //For configuring if the important_items survive digestion +/* +// +// The datum type bolted onto normal preferences datums for storing Virgo stuff +// +/client + var/datum/vore_preferences/prefs_vr + +/hook/client_new/proc/add_prefs_vr(client/C) + C.prefs_vr = new/datum/vore_preferences(C) + if(C.prefs_vr) + return 1 + + return 0 + +/datum/vore_preferences + //Actual preferences + var/digestable = 1 + var/list/belly_prefs = list() + + //Mechanically required + var/path + var/slot + var/client/client + var/client_ckey + +/datum/vore_preferences/New(client/C) + if(istype(C)) + client = C + client_ckey = C.ckey + load_vore_preferences(C) +*/ +// +// Check if an object is capable of eating things, based on vore_organs +// +/proc/is_vore_predator(var/mob/living/O) + if(istype(O,/mob/living)) + if(O.vore_organs.len > 0) + return 1 + + return 0 + +// +// Belly searching for simplifying other procs +// +/proc/check_belly(atom/movable/A) + if(istype(A.loc,/mob/living)) + var/mob/living/M = A.loc + for(var/I in M.vore_organs) + var/datum/belly/B = M.vore_organs[I] + if(A in B.internal_contents) + return(B) + + return 0 + +/* +// Save/Load Vore Preferences +// +/datum/preferences/proc/load_vore() + if(!client || !client_ckey) return 0 //No client, how can we save? + + slot = client.prefs.default_slot + + path = client.prefs.path + + if(!path) return 0 //Path couldn't be set? + if(!fexists(path)) //Never saved before + save_vore() //Make the file first + return 1 + + var/savefile/S = new /savefile(path) + if(!S) return 0 //Savefile object couldn't be created? + + S.cd = "/character[slot]" + + S["digestable"] >> digestable + S["belly_prefs"] >> belly_prefs + + if(isnull(digestable)) + digestable = 1 + if(isnull(belly_prefs)) + belly_prefs = list() + + return 1 + +/datum/preferences/proc/save_vore() + if(!path) return 0 + if(!slot) return 0 + var/savefile/S = new /savefile(path) + if(!S) return 0 + S.cd = "/character[slot]" + + S["digestable"] << digestable + S["belly_prefs"] << belly_prefs + + return 1 +*/ \ No newline at end of file diff --git a/code/citadel/vore/eating/vorehooks_vr.dm b/code/citadel/vore/eating/vorehooks_vr.dm new file mode 100644 index 0000000000..e69de29bb2 diff --git a/code/citadel/vore/eating/vorepanel_vr.dm b/code/citadel/vore/eating/vorepanel_vr.dm new file mode 100644 index 0000000000..48765e445f --- /dev/null +++ b/code/citadel/vore/eating/vorepanel_vr.dm @@ -0,0 +1,457 @@ +// +// Vore management panel for players +// + +/mob/living/proc/insidePanel() + set name = "Vore Panel" + set category = "Vore" + + var/datum/vore_look/picker_holder = new() + picker_holder.loop = picker_holder + picker_holder.selected = vore_organs[vore_selected] + + var/dat = picker_holder.gen_vui(src) + + picker_holder.popup = new(src, "insidePanel","Inside!", 400, 600, picker_holder) + picker_holder.popup.set_content(dat) + picker_holder.popup.open() + +// +// Callback Handler for the Inside form +// +/datum/vore_look + var/datum/belly/selected + var/datum/browser/popup + var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action. + +/datum/vore_look/Topic(href,href_list[]) + if (vp_interact(href, href_list)) + popup.set_content(gen_vui(usr)) + usr << output(popup.get_content(), "insidePanel.browser") + +/datum/vore_look/proc/gen_vui(var/mob/living/user) + var/dat + + if (is_vore_predator(user.loc)) + var/mob/living/eater = user.loc + var/datum/belly/inside_belly + + //This big block here figures out where the prey is + inside_belly = check_belly(user) + + if(inside_belly) + dat += "You are currently inside [eater]'s [inside_belly]!

" + + if(inside_belly.inside_flavor) + dat += "[inside_belly.inside_flavor]

" + + if (inside_belly.internal_contents.len > 1) + dat += "You can see the following around you:
" + for (var/atom/movable/O in inside_belly.internal_contents) + if(istype(O,/mob/living)) + var/mob/living/M = O + //That's just you + if(M == user) + continue + //Anything else + dat += "[O]" + else + dat += "You aren't inside anyone." + + dat += "
" + + dat += "
    " + for(var/K in user.vore_organs) //Fuggin can't iterate over values + var/datum/belly/B = user.vore_organs[K] + if(B == selected) + dat += "
  1. [B.name]" + else + dat += "
  2. [B.name]" + + var/spanstyle + switch(B.digest_mode) + if(DM_HOLD) + spanstyle = "" + if(DM_DIGEST) + spanstyle = "color:red;" + if(DM_DIGESTF) + spanstyle = "color:red;" + if(DM_HEAL) + spanstyle = "color:green;" + + dat += " ([B.internal_contents.len])
  3. " + + if(user.vore_organs.len < 10) + dat += "
  4. New+
  5. " + dat += "
" + dat += "
" + + // Selected Belly (contents, configuration) + if(!selected) + dat += "No belly selected. Click one to select it." + else + if(selected.internal_contents.len > 0) + dat += "Contents: " + for(var/O in selected.internal_contents) + dat += "[O]" + + //If there's more than one thing, add an [All] button + if(selected.internal_contents.len > 1) + dat += "\[All\]" + + dat += "
" + + //Belly Name Button + dat += "Name:" + dat += " '[selected.name]'" + + //Digest Mode Button + dat += "
Belly Mode:" + dat += " [selected.digest_mode]" + + //Belly verb + dat += "
Vore Verb:" + dat += " '[selected.vore_verb]'" + + //Inside flavortext + dat += "
Flavor Text:" + dat += " '[selected.inside_flavor]'" + + //Belly sound + dat += "
Set Vore Sound" + dat += "Test" + + //Belly messages + dat += "
Belly Messages" + + //Delete button + dat += "
Delete Belly" + + dat += "
" + + //Under the last HR, save and stuff. + dat += "Save Prefs" + dat += "Refresh" + + switch(user.digestable) + if(1) + dat += "Toggle Digestable" + if(0) + dat += "Toggle Digestable" + + //Returns the dat html to the vore_look + return dat + +/datum/vore_look/proc/vp_interact(href, href_list) + var/mob/living/user = usr + for(var/H in href_list) + + if(href_list["close"]) + del(src) // Cleanup + return + + if(href_list["outsidepick"]) + var/tgt = locate(href_list["outsidepick"]) + var/datum/belly/OB = locate(href_list["outsidebelly"]) + var/intent = "Examine" + + if(istype(tgt,/mob/living)) + var/mob/living/M = tgt + intent = alert("What do you want to do to them?","Query","Examine","Help Out","Devour") + switch(intent) + if("Examine") //Examine a mob inside another mob + M.examine(user) + + if("Help Out") //Help the inside-mob out + user << "You begin to push [M] to freedom!" + M << "[usr] begins to push you to freedom!" + M.loc << "Someone is trying to escape from inside you!" + sleep(50) + if(prob(33)) + OB.release_specific_contents(M) + usr << "You manage to help [M] to safety!" + M << "[user] pushes you free!" + M.loc << "[M] forces free of the confines of your body!" + else + user << "[M] slips back down inside despite your efforts." + M << " Even with [user]'s help, you slip back inside again." + M.loc << "Your body efficiently shoves [M] back where they belong." + + if("Devour") //Eat the inside mob + if(!user.vore_selected) + user << "Pick a belly on yourself first!" + return 1 + + var/datum/belly/TB = user.vore_organs[user.vore_selected] + user << "You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!" + M << "[user] begins to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!" + M.loc << "Someone inside you is eating someone else!" + + sleep(TB.nonhuman_prey_swallow_time) + if((user in OB.internal_contents) && (M in OB.internal_contents)) + user << "You manage to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!" + M << "[user] manages to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!" + M.loc << "Someone inside you has eaten someone else!" + M.loc = user + TB.nom_mob(M) + OB.internal_contents -= M + + else if(istype(tgt,/obj/item)) + var/obj/item/T = tgt + intent = alert("What do you want to do to that?","Query","Examine","Use Hand") + switch(intent) + if("Examine") + T.examine(user) + + if("Use Hand") + if(user.stat) + user << "You can't do that in your state!" + return 1 + + user.ClickOn(T) + sleep(5) //Seems to exit too fast for the panel to update + + if(href_list["insidepick"]) + var/intent + + //Handle the [All] choice. Ugh inelegant. Someone make this pretty. + if(href_list["pickall"]) + intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all") + switch(intent) + if("Cancel") + return 1 + + if("Eject all") + if(user.stat) + user << "You can't do that in your state!" + return 1 + + selected.release_all_contents() + playsound(user, 'sound/effects/splat.ogg', 50, 1) + + if("Move all") + if(user.stat) + user << "You can't do that in your state!" + return 1 + + var/choice = input("Move all where?","Select Belly") in user.vore_organs + "Cancel - Don't Move" + + if(choice == "Cancel - Don't Move") + return 1 + else + var/datum/belly/B = user.vore_organs[choice] + for(var/atom/movable/tgt in selected.internal_contents) + selected.internal_contents -= tgt + B.internal_contents += tgt + + tgt << "You're squished from [user]'s [selected] to their [B]!" + + for(var/mob/hearer in range(1,user)) + hearer << sound('sound/vore/squish2.ogg',volume=80) + return 1 + + + var/atom/movable/tgt = locate(href_list["insidepick"]) + intent = "Examine" + intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move") + switch(intent) + if("Examine") + tgt.examine(user) + + if("Eject") + if(user.stat) + user << "You can't do that in your state!" + return 1 + + selected.release_specific_contents(tgt) + playsound(user, 'sound/effects/splat.ogg', 50, 1) + + if("Move") + if(user.stat) + user << "You can't do that in your state!" + return 1 + + var/choice = input("Move [tgt] where?","Select Belly") in user.vore_organs + "Cancel - Don't Move" + + if(choice == "Cancel - Don't Move") + return 1 + else + var/datum/belly/B = user.vore_organs[choice] + selected.internal_contents -= tgt + B.internal_contents += tgt + + tgt << "You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(B.name)]!" + for(var/mob/hearer in range(1,user)) + hearer << sound('sound/vore/squish2.ogg',volume=80) + + if(href_list["newbelly"]) + if(user.vore_organs.len >= 10) + return 1 + + var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null) + + if(length(new_name) > 12 || length(new_name) < 2) + usr << "Entered belly name is too long." + return 0 + if(new_name in user.vore_organs) + usr << "No duplicate belly names, please." + return 0 + + var/datum/belly/NB = new(user) + NB.name = new_name + user.vore_organs[new_name] = NB + selected = NB + + if(href_list["bellypick"]) + selected = locate(href_list["bellypick"]) + user.vore_selected = selected.name + + if(href_list["b_name"]) + var/new_name = html_encode(input(usr,"Belly's new name:","New Name") as text|null) + + if(length(new_name) > 12 || length(new_name) < 2) + usr << "Entered belly name length invalid (must be longer than 2, shorter than 12)." + return 0 + if(new_name in user.vore_organs) + usr << "No duplicate belly names, please." + return 0 + + user.vore_organs[new_name] = selected + user.vore_organs -= selected.name + selected.name = new_name + + if(href_list["b_mode"]) + var/list/menu_list = selected.digest_modes + + if(selected.digest_modes.len == 1) // Don't do anything + return 1 + if(selected.digest_modes.len == 2) // Just toggle... there's probably a more elegant way to do this... + var/index = selected.digest_modes.Find(selected.digest_mode) + switch(index) + if(1) + selected.digest_mode = selected.digest_modes[2] + if(2) + selected.digest_mode = selected.digest_modes[1] + else + selected.digest_mode = input("Choose Mode (currently [selected.digest_mode])") in menu_list + + if(href_list["b_desc"]) + var/new_desc = html_encode(input(usr,"Belly Description (1024 char limit):","New Description",selected.inside_flavor) as message|null) + new_desc = readd_quotes(new_desc) + + if(length(new_desc) > 1024) + usr << "Entered belly desc too long. 1024 character limit." + return 0 + + selected.inside_flavor = new_desc + + if(href_list["b_msgs"]) + var/list/messages = list( + "Digest Message (to prey)", + "Digest Message (to you)", + "Struggle Message (outside)", + "Struggle Message (inside)", + "Examine Message (when full)", + "Reset All To Default", + "Cancel - No Changes" + ) + + alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.") + var/choice = input(user,"Select a type to modify. Messages from each topic are pulled at random when needed.","Pick Type") in messages + var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name." + + switch(choice) + if("Digest Message (to prey)") + var/new_message = input(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",selected.get_messages("dmp")) as message + if(new_message) + selected.set_messages(new_message,"dmp") + + if("Digest Message (to you)") + var/new_message = input(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",selected.get_messages("dmo")) as message + if(new_message) + selected.set_messages(new_message,"dmo") + + if("Struggle Message (outside)") + var/new_message = input(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",selected.get_messages("smo")) as message + if(new_message) + selected.set_messages(new_message,"smo") + + if("Struggle Message (inside)") + var/new_message = input(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",selected.get_messages("smi")) as message + if(new_message) + selected.set_messages(new_message,"smi") + + if("Examine Message (when full)") + var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging'). Do not use %pred or %prey in this type."+help,"Examine Message (when full)",selected.get_messages("em")) as message + if(new_message) + selected.set_messages(new_message,"em") + + if("Reset All To Default") + var/confirm = alert(user,"This will delete any custom messages. Are you sure?","Confirmation","DELETE","Cancel") + if(confirm == "DELETE") + selected.digest_messages_prey = initial(selected.digest_messages_prey) + selected.digest_messages_owner = initial(selected.digest_messages_owner) + selected.struggle_messages_outside = initial(selected.struggle_messages_outside) + selected.struggle_messages_inside = initial(selected.struggle_messages_inside) + + if("Cancel - No Changes") + return 1 + + if(href_list["b_verb"]) + var/new_verb = html_encode(input(usr,"New verb when eating (infinitive tense, e.g. nom or swallow):","New Verb") as text|null) + + if(length(new_verb) > 12 || length(new_verb) < 2) + usr << "Entered verb length invalid (must be longer than 2, shorter than 12)." + return 0 + + selected.vore_verb = new_verb + + if(href_list["b_sound"]) + var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") in vore_sounds + "Cancel - No Changes" + + if(choice == "Cancel") + return 1 + + selected.vore_sound = vore_sounds[choice] + + if(href_list["b_soundtest"]) + user << selected.vore_sound + + if(href_list["b_del"]) + if(selected.internal_contents.len) + usr << "Can't delete bellies with contents!" + else if(selected.immutable) + usr << "This belly is marked as undeletable." + else if(user.vore_organs.len == 1) + usr << "You must have at least one belly." + else + var/alert = alert("Are you sure you want to delete [selected]?","Confirmation","Delete","Cancel") + if(alert == "Delete" && !selected.internal_contents.len) + user.vore_organs -= selected.name + user.vore_organs.Remove(selected) + selected = user.vore_organs[1] + user.vore_selected = user.vore_organs[1] + + if(href_list["saveprefs"]) + if(!user.save_vore_prefs()) + user << "ERROR: Preferences failed to save!" + else + user << "Preferences saved!" + + if(href_list["toggledg"]) + var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable. Don't abuse this button by toggling it back and forth to extend a scene or whatever, or you'll make the admins cry. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion") + switch(choice) + if("Cancel") + return 1 + if("Allow Digestion") + user.digestable = 1 + if("Prevent Digestion") + user.digestable = 0 + + // message_admins("[key_name(user)] toggled their digestability to [user.digestable] ([user ? "JMP" : "null"])") + + if(user.client.prefs) + user.client.prefs.digestable = user.digestable + + //Refresh when interacted with, returning 1 makes vore_look.Topic update + return 1 diff --git a/code/citadel/vore/fluffstuff/custom_boxes_vr.dm b/code/citadel/vore/fluffstuff/custom_boxes_vr.dm new file mode 100644 index 0000000000..d66de51a4e --- /dev/null +++ b/code/citadel/vore/fluffstuff/custom_boxes_vr.dm @@ -0,0 +1,124 @@ +// BEGIN - DO NOT EDIT PROTOTYPE +/obj/item/weapon/storage/box/fluff + name = "Undefined Fluff Box" + desc = "This should have a description. Tell an admin." + storage_slots = 7 + var/list/has_items = list() + +/obj/item/weapon/storage/box/fluff/New() + storage_slots = has_items.len + allowed = list() + for(var/P in has_items) + allowed += P + new P(src) + ..() + return +// END - DO NOT EDIT PROTOTYPE + + +/* TEMPLATE +// ckey:Character Name +/obj/item/weapon/storage/box/fluff/charactername + name = "" + desc = "" + has_items = list( + /obj/item/clothing/head/thing1, + /obj/item/clothing/shoes/thing2, + /obj/item/clothing/suit/thing3, + /obj/item/clothing/under/thing4) +*/ + +//POLARISTODO - These fail to compile since not all items are ported yet +// bwoincognito:Tasald Corlethian +/obj/item/weapon/storage/box/fluff/tasald + name = "Tasald's Kit" + desc = "A kit containing Talsald's equipment." + has_items = list( + /obj/item/clothing/suit/storage/det_suit/fluff/tasald, + /obj/item/clothing/suit/storage/det_suit/fluff/tas_coat, + /obj/item/clothing/under/det/fluff/tasald, + /obj/item/fluff/permit/tasald_corlethian, + /obj/item/weapon/gun/projectile/revolver/detective/fluff/tasald_corlethian, + /obj/item/weapon/implanter/loyalty) + +// jemli:Cirra Mayhem +/obj/item/weapon/storage/box/fluff/cirra + name = "Instant Pirate Kit" + desc = "Just add Akula!" + has_items = list( + /obj/item/clothing/head/pirate, + /obj/item/clothing/glasses/eyepatch, + /obj/item/clothing/suit/pirate, + /obj/item/clothing/under/pirate) + +// joey4298:Emoticon +/obj/item/weapon/storage/box/fluff/emoticon + name = "Emoticon's Mime Kit" + desc = "Specially packaged for the hungry catgirl mime with a taste for clown." + has_items = list( + /obj/item/device/fluff/id_kit_mime, + /obj/item/clothing/gloves/white, + /obj/item/clothing/head/beret, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing, + /obj/item/clothing/shoes/black, + /*/obj/item/toy/crayon/mime*/) //Need to track down the code for crayons before adding this back in + +//joanrisu:Joan Risu +/obj/item/weapon/storage/backpack/dufflebag/sec/fluff/joanrisu + name = "Joan's Workbag" + desc = "A duffle bag Joan uses to carry her work equipment." + slowdown = 0 + + New() + ..() + new /obj/item/clothing/accessory/holster/hip(src) + new /obj/item/clothing/suit/storage/fluff/fedcoat/fedcapt(src) + new /obj/item/weapon/card/id/centcom/fluff/joanbadge(src) + new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) + new /obj/item/clothing/suit/armor/det_suit(src) + new /obj/item/fluff/permit/joanrisu(src) + new /obj/item/clothing/accessory/storage/black_vest(src) + new /obj/item/weapon/sword/fluff/joanaria(src) + new /obj/item/weapon/flame/lighter/zippo/fluff/joan(src) + new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src) + +//joanrisu:Katarina Eine +/obj/item/weapon/storage/backpack/dufflebag/sec/fluff/Katarina + name = "Katarina's Workbag" + desc = "A duffle bag Katarina uses to carry her tools." + slowdown = 0 + + New() + ..() + new /obj/item/clothing/accessory/holster/hip(src) + new /obj/item/clothing/suit/storage/fluff/fedcoat(src) + new /obj/item/weapon/gun/energy/gun/fluff/dominator(src) + new /obj/item/clothing/suit/armor/det_suit(src) + new /obj/item/clothing/accessory/storage/black_vest(src) + new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src) + new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src) + new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src) + new /obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina(src) + new /obj/item/clothing/under/rank/internalaffairs/fluff/joan(src) + +//Razerwing:Archer Maximus +/obj/item/weapon/storage/box/fluff/archermaximus + desc = "Personal Effects" + has_items = list( + /obj/item/fluff/permit/archermaximus, + /obj/item/weapon/gun/projectile/colt/fluff/archercolt) + +// arokha:Aronai Kadigan +/obj/item/weapon/storage/backpack/dufflebag/emt/fluff/aro + name = "Aronai's Equipment" + desc = "A big dufflebag, containing the stuff Aronai likes to carry with him." + slowdown = 0 //HAX! + + New() + ..() + new /obj/item/clothing/head/helmet/space/fluff/aronai(src) + new /obj/item/clothing/suit/space/fluff/aronai(src) + new /obj/item/device/suit_cooling_unit(src) + new /obj/item/weapon/material/hatchet/tacknife/combatknife(src) + new /obj/item/weapon/card/id/centcom/fluff/aro(src) + new /obj/item/weapon/reagent_containers/hypospray/fluff/aronai(src) diff --git a/code/citadel/vore/fluffstuff/custom_clothes_vr.dm b/code/citadel/vore/fluffstuff/custom_clothes_vr.dm new file mode 100644 index 0000000000..904cf4ab51 --- /dev/null +++ b/code/citadel/vore/fluffstuff/custom_clothes_vr.dm @@ -0,0 +1,684 @@ +/* TUTORIAL + "icon" is the file with the HUD/ground icon for the item + "icon_state" is the iconstate in this file for the item + "icon_override" is the file with the on-mob icons, can be the same file + "item_state" is the iconstate for the on-mob icons: + item_state_s is used for worn uniforms on mobs + item_state_r and item_state_l are for being held in each hand + some do not have a suffix, like gloves. plan accordingly, maybe add _mob? + "overlay_state" is the iconstate for ties/accessories, for some reason they don't + just use the item_state variable + + If you don't have a special HUD/ground sprite, don't worry about it. + Just set both the icon_state and item_state to the same thing, + and it will use the top direction sprite (facing the viewer) + for your HUD/item sprite. This usually looks fine! + + Advanced: + "item_state_slots" can replace "item_state", it is a list: + item_state_slots["slotname1"] = "item state for that slot" + item_state_slots["slotname2"] = "item state for that slot" +*/ + +/* TEMPLATE +//ckey:Character Name +/obj/item/clothing/type/fluff/charactername + name = "" + desc = "" + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "myicon" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "myicon" + +*/ + +//benemuel:Yuuko Shimmerpond +/obj/item/clothing/under/fluff/sakura_hokkaido_kimono + name = "Sakura Kimono" + desc = "A pale-pink, nearly white, kimono with a red and gold obi. There is a embroidered design of cherry blossom flowers covering the kimono." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "sh_kimono" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "sh_kimono_mob" + +//BeyondMyLife:Kilano Soryu +/obj/item/clothing/under/dress/fluff/kilano + name = "Bleached Dress" + desc = "It appears that this was once a captain's dress, it's blueish color has been turned white by bleach, only the gold markings remain to slightly signify what it once was." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "kilanodress" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "kilanodress_mob" + + species_restricted = null + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + +//BeyondMyLife:Kilano Soryu +/obj/item/clothing/gloves/fluff/kilano + name = "Bleached Gloves" + desc = "Some old captain's gloves, bleached white, almost unrecognizable from the color change besides the gold trim." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "kilanogloves" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "kilanogloves_mob" + species_restricted = null + +//JoanRisu:Joan Risu +/obj/item/clothing/under/suit_jacket/female/fluff/asuna + name = "Joan's Historia Uniform" + desc = "A red and white outfit used by Joan during her explorer days. Looks almost like a red school uniform." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "joanasuna" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "joanasuna" + +//Unknown. Please check records from the forums. +/obj/item/clothing/under/suit_jacket/female/fluff/miqote + name = "Miqo'te Seperates" + desc = "This two-part set of clothing is very popular on the planet Hydaelyn. While made of very robust materials, its usefulness as armor is negated by the exposed midriff." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "miqote" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "miqote" + +//JoanRisu:Joan Risu +/obj/item/clothing/under/fluff/nightgown + name = "nightgown" + desc = "A seethrough nightgown. For those intimate nights with your significant other." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "joannightgown" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "joannightgown" + +//Vorrarkul:Lucina Dakarim +/obj/item/clothing/under/dress/fluff/lucinadress + name = "Elegant Purple Dress" + desc = "An expertly tailored dress, made out of fine fabrics. The interwoven necklace appears to be made out of gold, with three complicated symbols engraved in the front." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "solara_dress" + + icon_override = 'icons/mob/uniform.dmi' + item_state = "solara_dress" + +//For general use +/obj/item/clothing/suit/armor/hos/fluff/brittrenchcoat + name = "Britania Trench Coat" + desc = "An armored trench coat from the Brittanian Empire. It looks so British." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "brittrenchcoat" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "brittrenchcoat" + +//For general use +/obj/item/clothing/suit/armor/hos/nazi_greatcoat + name = "Greatcoat" + desc = "Perfect attire for kicking down the doors of suspected dissidents; this coat gives off an imposing look, while offering a luxuriously plush fur liner." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "greatcoat" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "greatcoat_mob" + +//For general use +/obj/item/clothing/suit/storage/fluff/fedcoat + name = "Federation Uniform Jacket" + desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Set phasers to awesome." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "fedcoat" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "fedcoat" + + blood_overlay_type = "coat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + allowed = list( + /obj/item/weapon/tank/emergency_oxygen, + /obj/item/device/flashlight, + /obj/item/weapon/gun/energy, + /obj/item/weapon/gun/projectile, + /obj/item/ammo_magazine, + /obj/item/ammo_casing, +// /obj/item/weapon/storage/fancy/shotgun_ammo, + /obj/item/weapon/melee/baton, + /obj/item/weapon/handcuffs, +// /obj/item/device/detective_scanner, + /obj/item/device/taperecorder) + armor = list(melee = 50, bullet = 15, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) + var/unbuttoned = 0 + + verb/toggle() + set name = "Toggle coat buttons" + set category = "Object" + set src in usr + + if(!usr.canmove || usr.stat || usr.restrained()) + return 0 + + switch(unbuttoned) + if(0) + icon_state = "[initial(icon_state)]_open" + item_state = "[initial(item_state)]_open" + unbuttoned = 1 + usr << "You unbutton the coat." + if(1) + icon_state = "[initial(icon_state)]" + item_state = "[initial(item_state)]" + unbuttoned = 0 + usr << "You button up the coat." + usr.update_inv_wear_suit() + + //Variants + fedblue + name = "Federation Uniform Jacket" + desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. Wearing this may make you feel all scientific." + icon_state = "fedblue" + item_state = "fedblue" + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0) + + fedeng + name = "Federation Uniform Jacket" + desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it.Wearing it may make you feel like checking a warp core, whatever that is." + icon_state = "fedeng" + item_state = "fedeng" + armor = list(melee = 0, bullet = 0, laser = 0,energy = 10, bomb = 0, bio = 30, rad = 35) + + fedcapt + name = "Federation Uniform Jacket" + desc = "A uniform jacket from the United Federation. Starfleet still uses this uniform and there are variations of it. You feel like a commanding officer of Starfleet." + icon_state = "fedcapt" + item_state = "fedcapt" + armor = list(melee = 50, bullet = 5, laser = 15,energy = 10, bomb = 0, bio = 0, rad = 0) + +/*POLARISTODO - Needs rework in update_icons as it doesn't use item_state +//For general use +/obj/item/clothing/glasses/welding/fluff/yellow + name = "Yellow Goggles" + desc = "A neat looking pair of goggles" + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "gogyellow" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "gogyellow" + +/obj/item/clothing/glasses/welding/fluff/blue + name = "Blue Goggles" + desc = "A neat looking pair of goggles" + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "gogblue" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "gogblue" +*/ + +//wickedtemp:chakat tempest +/obj/item/clothing/glasses/hud/health/fluff/wickedtemphud + name = "Purple MedHUD" + desc = "A standard Medical HUD, only this one is colored purple with a violet lens." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "healthhud" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "healthhud" + +//For general use +/obj/item/clothing/accessory/fluff/smilepin + name = "Smiley Pin" + desc = "A pin with a stupid grin on its face" + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "smilepin" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + overlay_state = "" //They don't have one + +//For general use +/obj/item/clothing/accessory/fluff/heartpin + name = "Love Pin" + desc = "A cute heart pin." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "heartpin" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + overlay_state = "" //They don't have one + +//john.wayne9392:Harmony Prechtl +/obj/item/clothing/suit/armor/captain/fluff/harmsuit + name = "Harmony's Captain Armor" + desc = "A modified Captain Armor suit for Harmony Prechtl." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "harmarmor" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "harmarmor" + +//john.wayne9392:Harmony Prechtl +/obj/item/clothing/head/helmet/space/capspace/fluff/harmhelm + name = "Harmony's Captain Helmet" + desc = "A modified Captain helmet for Harmony Prechtl." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "harmspace" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "harmspace_mob" + +//john.wayne9392:Harmony Prechtl +/obj/item/clothing/under/rank/captain/fluff/harmuniform + name = "Harmony's Captain uniform" + desc = "A customized Captain uniform for Harmony Prechtl, given to her as a gift by Central Command for her service." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "harmcaptain" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "harmcaptain" + //Variant + centcom + name = "\improper CentCom administrator's uniform" + desc = "It's a green jumpsuit with some gold markings denoting the rank of \"Administrator\"." + +//john.wayne9392:Harmony Prechtl +/obj/item/clothing/head/centhat/fluff/harmhat + name = "Harmony's CentCom hat" + desc = "It's good to be queen." + +// bwoincognito:Tasald Corlethian +/obj/item/clothing/under/det/fluff/tasald + name = "Tasald's outfit" + desc = "Tasald's outfit. Very green." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "tasaldsuit" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "tasaldsuit" + +// bwoincognito:Tasald Corlethian +/obj/item/clothing/suit/storage/det_suit/fluff/tasald + name = "Tasald's Vest" + desc = "A fancy looking vest. You look like a smooth operating officer in this." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "tasvest" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "tasvest" + + blood_overlay_type = "coat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +// bwoincognito:Tasald Corlethian +/obj/item/clothing/suit/storage/det_suit/fluff/tas_coat + name = "Armored Colony coat" + desc = "Dark green and grey colored sleeveless long coat with two thick metal shoulder pads. has seen some wear and tear, with noticeable patches in the fabric, scratches on the shoulder pads, but with a clean patch on the left upper chest. It has a red NT marked on the right shoulder pad and red Security on the left. " + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "tasaldcoat" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "tasaldcoat_mob" + + blood_overlay_type = "coat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +//Event Costumes Below +/obj/item/clothing/head/helmet/fluff/freddy + name = "Animatronic Suit Helmet" + desc = "Votre toast, je peux vous le rendre." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "freddyhead" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "freddyhead_mob" + permeability_coefficient = 0.01 + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + flags_inv = HIDEMASK|HIDEEARS + cold_protection = HEAD + siemens_coefficient = 0.9 + + //Bonnie Head + bonnie + desc = "Children's entertainer." + icon_state = "bonniehead" + item_state = "bonniehead_mob" + + //Foxy Head + foxy + desc = "I guess he doesn't like being watched." + icon_state = "foxyhead" + item_state = "foxyhead_mob" + + //Chica Head + chica + desc = "LET'S EAT!" + icon_state = "chicahead" + item_state = "chicahead_mob" + +//Anamatronic Suits +/obj/item/clothing/suit/fluff/freddy + name = "Animatronic Suit" + desc = "Votre toast, je peux vous le rendre." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "freddysuit" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "freddysuit_mob" + + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.02 + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS + siemens_coefficient = 0.9 + + //Bonnie Suit + bonnie + desc = "Children's entertainer." + icon_state = "bonniesuit" + item_state = "bonniesuit_mob" + + //Foxy Suit + foxy + desc = "I guess he doesn't like being watched." + icon_state = "foxysuit" + item_state = "foxysuit_mob" + + + //Chica Suit + chica + desc = "LET'S EAT!" + icon_state = "chicasuit" + item_state = "chicasuit_mob" + +//End event costumes + +//scree:Scree +/obj/item/clothing/head/helmet/space/void/engineering/fluff/screehelm + name = "Modified Tajara Helmet" + desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding. This one doesn't look like it was made for humans. Its been modified to include headlights." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "scree-helm" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "scree-helm_mob" + + light_overlay = "helmet_light_dual" + + species_restricted = null + + mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + ..() + if(H.ckey != "scree") + H << "Your face and whoever is meant for this helmet are too different." + return 0 + else + return 1 + +//scree:Scree +/obj/item/clothing/suit/space/void/engineering/fluff/screespess + name = "Modified Winged Suit" + desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding. This one doesn't look like it was made for humans. This one was made with a special personal shielding for someone's wings." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "scree-spess" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "scree-spess_mob" + + species_restricted = null + + mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + ..() + if(H.ckey != "scree") + H << "The gloves only have three fingers, not to mention the accomidation for extra limbs." + return 0 + else + return 1 + +//scree:Scree +/obj/item/clothing/under/fluff/screesuit + name = "Scree's feathers" + desc = "A mop of fluffy blue feathers, the honkmother only knows what kind of bird they originally came from." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "screesuit" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "screesuit" + + mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + ..() + if(H.ckey != "scree") + H << "Are you just going to tape them on or what? This isn't gonna work." + return 0 + else + return 1 + +//HOS Hardsuit +/obj/item/clothing/suit/space/void/security/fluff/hos // ToDo: Rig version. + name = "\improper prototype voidsuit" + desc = "A customized security voidsuit made to match the Head of Security's obession with black. Has additional composite armor." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "rig-hos" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "rig-hos_mob" + +//HOS Hardsuit Helmet +/obj/item/clothing/head/helmet/space/void/security/fluff/hos // ToDo: Rig version. + name = "\improper prototype voidsuit helmet" + desc = "A customized security voidsuit helmet customized to include the Head of Security's signature hat. Has additional composite armor." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "rig0-hos" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "rig0-hos_mob" + +//adk09:Lethe +/obj/item/clothing/head/helmet/hos/fluff/lethe + name = "Lethe's Hat" + desc = " This is Lethe's Hat! A little tag attached inside reads: 'If found please return to Lethe! Or else!' It looks rather worn in. It also lacks armor." + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + + icon = 'icons/obj/clothing/hats.dmi' + icon_state = "hoscap" + + icon_override = 'icons/mob/head.dmi' + item_state = "hoscap" + +/obj/item/weapon/storage/belt/utility/fluff/vulpine + name = "vulpine belt" + desc = "A tool-belt in Atmos colours." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "vulpine_belt" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "vulpine_belt_mob" + + storage_slots = 9 + New() + ..() + new /obj/item/weapon/screwdriver(src) + new /obj/item/weapon/wrench(src) + new /obj/item/weapon/weldingtool(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/wirecutters(src) + new /obj/item/device/multitool(src) + new /obj/item/stack/cable_coil(src, 30, "red") + new /obj/item/stack/cable_coil(src, 30, "green") + +// molenar:Giliana Gamish +/obj/item/clothing/suit/storage/toggle/labcoat/fluff/molenar + name = "Gili Custom Labcoat" + desc = " Custom made, lengthened labcoat with water resistant, durable material. And a custom set of holes inserted for Deathclaw anatomy. A tag inside has 'G.G.' monogram on it" + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "molenar" + icon_open = "molenar_open" + icon_closed = "molenar" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "molenar" + +//scree:Scree +/obj/item/clothing/head/fluff/pompom + name = "Pom-Pom" + desc = "A fluffy little thingus on a thin stalk, ideal for impersonating moogles and anglerfish. Kupomnomnom." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "pom" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "pom_mob" + + w_class = 2.0 + on = 0 + brightness_on = 5 + light_overlay = null + + attack_self(mob/user) + if(!isturf(user.loc)) + user << "You cannot turn the light on while in this [user.loc]" + return + + switch(on) + if(0) + on = 1 + user << "You light up your pom-pom." + icon_state = "pom-on" + item_state = "pom-on_mob" + if(1) + on = 0 + user << "You dim your pom-pom." + icon_state = "pom" + item_state = "pom_mob" + + update_light(user) + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.head == src) + H.update_inv_head() + +// arokha : Aronai Kadigan +/obj/item/clothing/head/helmet/space/fluff/aronai + name = "Aronai's Helmet" + desc = "This spacesuit helmet appears to be custom-made for someone with pointed ears and a muzzle. \ + It is form-fitting enough that it's unlikely to fit anyone but the person it was intended for. \ + 'Aronai' is printed on the back of the helmet." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "arohelm" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "arohelm_mob" + + light_overlay = "helmet_light_dual" + camera_networks = list(NETWORK_MEDICAL) + + mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + ..() + if(H.ckey != "arokha") + H << "You try to wear the helmet, but it doesn't fit." + return 0 + else + return 1 + +/obj/item/clothing/suit/space/fluff/aronai + name = "Aronai's Spacesuit" + desc = "This spacesuit appears to be custom-made for someone with digitigrade legs and a tail. \ + It is form-fitting enough that it's unlikely to fit anyone but the person it was intended for. \ + 'Aronai' is printed just above the spine on the back of the neckpiece. It has no space for an O2 tank. \ + In fact, it's practically paper-thin. It doesn't seem to retain body heat at all." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "arosuit" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "arosuit_mob" + w_class = 4 //Oh but I can. + allowed = list(/obj/item/device/suit_cooling_unit) //Can't fit O2 tanks + + mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) + ..() + if(H.ckey != "arokha") + H << "You try to fit into the suit, to no avail." + return 0 + else + return 1 + +//Viveret:Keturah +/obj/item/clothing/under/dress/maid/ + name = "Maid Outfit" + desc = "A french maid outfit made ironically in Gaia's version of the far east." + +//JoanRisu:Joan Risu +/obj/item/clothing/head/helmet/space/fluff/joan + name = "Joan's Combat Space Helmet" + desc = "A customized combat space helmet made for a certain squirrely Commissioned Officer. \ + The top has the signature ears that are held up with a harder back covering. 'Joan' is engraved on the back.\ + There are some indications that the helmet has seen combat." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "joanhelm" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "joanhelm_mob" + + light_overlay = "helmet_light" + + +//JoanRisu:Joan Risu +/obj/item/clothing/suit/space/fluff/joan + name = "Joan's Combat Spacesuit" + desc = "A customized combat spacesuit made for a certain squirrely Commissioned Officer, tail slot included. \ + On the right shoulder, the United Federation's Emblem sits proudly. On the left, there are faded indications \ + that there were different ranks painted on and off. On the collar where the suit is softer is a rectangular \ + name-tag with the name 'Joan' on it. There are indications that the suit has seen combat." + + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "joansuit" + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "joansuit_mob" + +/obj/item/clothing/under/rank/internalaffairs/fluff/joan + desc = "The plain, professional attire of a Federation Law Enforcement Detective. The collar is immaculately starched." + name = "Federation Dress Shirt" + icon_state = "internalaffairs" + item_state = "ba_suit" + worn_state = "internalaffairs" + rolled_sleeves = 0 + starting_accessories = list(/obj/item/clothing/accessory/black) diff --git a/code/citadel/vore/fluffstuff/custom_guns_vr.dm b/code/citadel/vore/fluffstuff/custom_guns_vr.dm new file mode 100644 index 0000000000..314d1ecac2 --- /dev/null +++ b/code/citadel/vore/fluffstuff/custom_guns_vr.dm @@ -0,0 +1,472 @@ +/* TUTORIAL + "icon" is the file with the HUD/ground icon for the item + "icon_state" is the iconstate in this file for the item + "icon_override" is the file with the on-mob icons, can be the same file + "item_state" is the iconstate for the on-mob icons: + item_state_s is used for worn uniforms on mobs + item_state_r and item_state_l are for being held in each hand + + "item_state_slots" can replace "item_state", it is a list: + item_state_slots["slotname1"] = "item state for that slot" + item_state_slots["slotname2"] = "item state for that slot" + + on guns, in particular: + item_state being null makes it look for exactly the icon_state in the on-mob file, + including any 0,75,etc appended from the energy bar setting + item_state being present prevents different mode sprites, sadly, but you may + be able to override this on the gun itself with a proc +*/ + +/* TEMPLATE +//ckey:Character Name +/obj/item/weapon/gun/type/fluff/charactername + name = "" + desc = "" + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "myicon" + + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = "myicon" + +*/ + +//////////////////// Projectile Weapons //////////////////// +// For general use +/obj/item/weapon/gun/projectile/automatic/battlerifle + name = "\improper BR55 Service Rifle" + desc = "You had your chance to be afraid before you joined my beloved Corps! But, to guide you back to the true path, I brought this motivational device! Uses unique 9.5x40mm rounds." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "battlerifle" + icon_override = 'icons/obj/gun_vr.dmi' + item_state = "battlerifle" + item_icons = null + w_class = 4 + recoil = 2 // The battlerifle was known for its nasty recoil. + max_shells = 36 + caliber = "9.5x40mm" + origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2) + ammo_type = /obj/item/ammo_casing/a95mm + magazine_type = /obj/item/ammo_magazine/battlerifle + allowed_magazines = list(/obj/item/ammo_magazine/battlerifle) + fire_sound = 'sound/weapons/battlerifle.ogg' + load_method = MAGAZINE + slot_flags = SLOT_BACK + //requires_two_hands = 1 + one_handed_penalty = 4 // The weapon itself is heavy + +// For general use +/obj/item/weapon/gun/projectile/shotgun/pump/unsc + name = "\improper M45E Tactical Shotgun" + desc = "All you greenhorns who wanted to see Xenomorphs up close... this is your lucky day." + + icon = 'icons/obj/gun_vr.dmi' + icon_state = "haloshotgun" + + icon_override = 'icons/obj/gun_vr.dmi' + item_state = "haloshotgun" + item_icons = null + + ammo_type = /obj/item/ammo_casing/shotgun + max_shells = 12 + +// jertheace : Jeremiah 'Ace' Acacius +/obj/item/weapon/gun/projectile/shotgun/pump/unsc/fluff/ace + name = "Ace's M45D Tactical Shotgun" // D-model holds half as many shells as the normal version so as not to be OP as shit. Better than shotgun, worse than combat shotgun. + desc = "Owned by the respected (or feared?) veteran Captain of VORE Station. Inscribed on the barrel are the words \"Speak softly, and carry a big stick.\" It has a folding stock so it can fit into bags." + w_class = 3 // Because collapsable stock so it fits in backpacks. + ammo_type = /obj/item/ammo_casing/shotgun/stunshell + max_shells = 6 + +// bwoincognito:Tasald Corlethian +/obj/item/weapon/gun/projectile/revolver/detective/fluff/tasald_corlethian + name = "Big Iron revolver" + desc = "A .38 revolver for veteran rangers on the planet Orta. The right side of the handle has a logo for Quarion industries, and the left is the Rangers. The primary ammo for this gun is .38 rubber. According to the CentCom Chief of Security, this revolver was more controversial than it needed to be." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "tasaldrevolver" + + item_state = "revolver" + + fire_sound = 'sound/weapons/pistol.ogg' + ammo_type = /obj/item/ammo_casing/c38r + var/recentpump = 0 + var/cocksound = 'sound/weapons/revolvercock.ogg' + + consume_next_projectile() + if(chambered) + return chambered.BB + usr << "It's a single action revolver, pull the hammer back!" + return null + + attack_self(mob/living/user as mob) + if(world.time >= recentpump + 10) + pump(user) + recentpump = world.time + + proc/pump(mob/M as mob) + playsound(M, cocksound, 60, 1) + + if(chambered)//We have a shell in the chamber + chambered.loc = get_turf(src)//Eject casing + chambered = null + + if(loaded.len) + var/obj/item/ammo_casing/AC = loaded[1] //load next casing. + loaded -= AC //Remove casing from loaded list. + chambered = AC + + update_icon() + +// wankersonofjerkin : Ryan Winz +/obj/item/weapon/gun/projectile/revolver/fluff/ryan_winz_revolver + name = "Ryan's 'Devilgun'" + desc = "You notice the serial number on the revolver is 666. The word 'Sin' is engraved on the blood-red rosewood grip. Uses .357 rounds." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "ryan_winz" + + item_state = "revolver" + +/obj/item/weapon/gun/projectile/revolver/fluff/ryan_winz_revolver/redemption + name = "Ryan's 'Redeemer'" + desc = "You notice the serial number on the revolver is 667. The word 'Redemption' is engraved on dark rosewood grip. Uses .357 rounds." + +// sasoperative : Joseph Skinner +/obj/item/weapon/gun/projectile/revolver/shotgun/fluff/sasoperative + name = "\"The Jury\"" + desc = "A customized variant of the \"The Judge\" revolver sold by Cybersun Industries, built specifically for Joseph Skinner. Uses 12g shells." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "jury" + + item_state = "gun" + + accuracy = 0 // Because I know you're not an idiot who needs to be nerfed. -Ace + ammo_type = /obj/item/ammo_casing/shotgun/beanbag + +// For general use +/obj/item/weapon/gun/projectile/automatic/stg + name = "\improper Sturmgewehr" + desc = "An STG-560 built by RauMauser. Experience the terror of the Siegfried line, redone for the 26th century! The Kaiser would be proud. Uses unique 7.92x33mm Kurz rounds." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "stg60" + item_state = "arifle" + w_class = 4 + max_shells = 30 + caliber = "kurz" + origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 2, TECH_ILLEGAL = 6) + magazine_type = /obj/item/ammo_magazine/stg + allowed_magazines = list(/obj/item/ammo_magazine/stg) + load_method = MAGAZINE + +/obj/item/weapon/gun/projectile/automatic/stg/update_icon(var/ignore_inhands) + ..() + icon_state = (ammo_magazine)? "stg60" : "stg60-empty" + item_state = (ammo_magazine)? "arifle" : "arifle-empty" + if(!ignore_inhands) update_held_icon() + +// For general use +/obj/item/weapon/gun/projectile/automatic/m14/fluff/gallian + name = "\improper Gallian 4 Rifle" + desc = "The ever reliable Gallian 4 Rifle. Produced by the National Armory on the Planet of Gaia located in Gallia, the Gallian 4 Rifle offers high accuracy and is widely used in the United Federation's Military. Uses 7.62mm rounds." + +// For general use +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/zmkar + name = "\improper ZM Kar 1" + desc = "A reproduction of an old ZM Kar 1 Rifle from the Autocratic East Europan Imperial Alliance of Gaia. Popular among imperials and collectors within the Federation and its allies. Uses 7.62mm rounds." + +// For general use +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/wicked + name = "Wicked Butterfly ZM Kar S1" + desc = "A customized bolt-action sniper rifle that was carried by some of the most revered snipers in the Federation. The stock has a small butterfly engraved on it. Uses 7.62mm rounds." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "wickedbutterfly" + + icon_override = 'icons/obj/gun_vr.dmi' + item_state = "SVD" + item_icons = null + + recoil = 2 //extra kickback + accuracy = -1 + scoped_accuracy = 2 + load_method = SINGLE_CASING + + verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) + +// For general use +/obj/item/weapon/gun/projectile/automatic/pdw // Vorestation SMG because the WT550 is ugly and bad. + name = "personal defense weapon" + desc = "The X-9MM is a select-fire personal defense weapon designed in-house by Xing Private Security. It was made to compete with the WT550 Saber, but hasn't yet caught on in popularity outside of the Virgo-Erigone system. Uses 9mm rounds." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "pdw" + item_state = "c20r" // Placeholder + w_class = 3 + caliber = "9mm" + origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2) + slot_flags = SLOT_BELT + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/mc9mml + allowed_magazines = list(/obj/item/ammo_magazine/mc9mm, /obj/item/ammo_magazine/mc9mml) + + firemodes = list( + list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), + list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6)) + ) + +/obj/item/weapon/gun/projectile/automatic/pdw/update_icon(var/ignore_inhands) + ..() + if(istype(ammo_magazine,/obj/item/ammo_magazine/mc9mm)) + icon_state = "pdw-short" + else + icon_state = (ammo_magazine)? "pdw" : "pdw-empty" + if(!ignore_inhands) update_held_icon() + + +//Currently, the only problem I have now is that this weapon's item_state isn't working. +/obj/item/weapon/gun/projectile/automatic/fluff/crestrose + name = "Crescent Rose" + desc = "Can you match my resolve? If so then you will succeed. I believe that the human spirit is indomitable. Keep Moving Forward. Uses 5.56mm rounds." + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "crestrose_fold" + + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = "crestrose_fold_mob" + + w_class = 4 + origin_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 4) + slot_flags = null + fire_sound = 'sound/weapons/Gunshot_light.ogg' + load_method = MAGAZINE + force = 3 + recoil = 2 + var/on = 0 + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' + hitsound = null + caliber = "a556" + magazine_type = /obj/item/ammo_magazine/a556 + allowed_magazines = list(/obj/item/ammo_magazine/a556) + +/obj/item/weapon/gun/projectile/automatic/fluff/crestrose/attack_self(mob/user as mob) + on = !on + if(on) + user.visible_message("With a press of a button, [user]'s gun turns into a deadly scythe.",\ + "You extend The Rose's thorns.",\ + "You hear an ominous click.") + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "crestrose" + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = "crestrose_mob" + w_class = 4 + force = 15//Obscenely robust + attack_verb = list("slashed", "cut", "drives") + hitsound = 'sound/weapons/bladeslice.ogg' + else + user.visible_message("\The [user] folds the weapon back up into a gun.",\ + "You fold up the weapon.",\ + "You hear a click.") + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "crestrose_fold" + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = "crestrose_fold_mob" + w_class = 3 + force = 3//Not so obscenely robust + attack_verb = list("hit", "melee'd") + hitsound = null + update_icon() + + +/obj/item/weapon/gun/projectile/automatic/fluff/crestrose/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + if(default_parry_check(user, attacker, damage_source) && prob(50)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) + return 1 + return 0 + +// molenar:Kari Akiren +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/fluff/kari_akiren + name = "clockwork rifle" + desc = "Brass, copper, and lots of gears. Well lubricated for fluid movement as each round is loaded, locked, and fired. Just like clockwork." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "clockworkrifle" + + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = "clockworkrifle" + item_icons = null + +//Razerwing:Archer Maximus +/obj/item/weapon/gun/projectile/colt/fluff/archercolt + name = "\improper MEUSOC .45" + desc = "Some serious drywall work, coming up!" + +//////////////////// Energy Weapons //////////////////// +//arokha:Aronai Kadigan +/obj/item/weapon/gun/energy/gun/fluff/aro + name = "\improper KIN-H21" + desc = "The Kitsuhana Heavy Industries standard Imperial Navy energy sidearm, commonly called the KIN21. This one appears to have been modified to have additional features at the cost of battery life." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "kinh21stun100" + + item_state = "laser" + + modifystate = "kinh21stun" + + projectile_type = /obj/item/projectile/beam/stun/kin21 + + max_shots = 8 + charge_cost = 125 + charge_meter = 1 + + firemodes = list( + list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/kin21, modifystate="kinh21stun", fire_sound='sound/weapons/Taser.ogg'), + list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="kinh21kill", fire_sound='sound/weapons/blaster_pistol.ogg'), + list(mode_name="shrink", projectile_type=/obj/item/projectile/beam/shrinklaser, modifystate="kinh21shrink", fire_sound='sound/weapons/wave.ogg'), + list(mode_name="grow", projectile_type=/obj/item/projectile/beam/growlaser, modifystate="kinh21grow", fire_sound='sound/weapons/pulse3.ogg'), + ) + +// -------------- Dominator ------------- +/obj/item/weapon/gun/energy/gun/fluff/dominator + name = "\improper MWPSB Dominator" + desc = "A MWPSB's Dominator from the Federation. Like the basic Energy Gun, this gun has two settings. It is used by the United Federation Public Safety Bureau's Criminal Investigation Division." + + icon = 'icons/vore/custom_guns_vr.dmi' + icon_state = "dominatorstun100" + + icon_override = 'icons/vore/custom_guns_vr.dmi' + item_state = null + item_icons = null + + fire_sound = 'sound/weapons/Taser.ogg' + projectile_type = /obj/item/projectile/beam/stun + + modifystate = "dominatorstun" + + firemodes = list( + list(mode_name="stun", charge_cost=100,projectile_type=/obj/item/projectile/beam/stun, modifystate="dominatorstun", fire_sound='sound/weapons/Taser.ogg'), + list(mode_name="lethal", charge_cost=125,projectile_type=/obj/item/projectile/beam/dominator, modifystate="dominatorkill", fire_sound='sound/weapons/gauss_shoot.ogg'), + ) + +// ------------ Energy Luger ------------ +/obj/item/weapon/gun/energy/gun/eluger + name = "energy Luger" + desc = "The finest sidearm produced by RauMauser, this pistol can punch a hole through inch thick steel plating. This ain't your great-grand-daddy's Luger! Can switch between stun and kill." + + icon = 'icons/obj/gun_vr.dmi' + icon_state = "elugerstun100" + + item_state = "gun" + + charge_cost = 100 //How much energy is needed to fire. + projectile_type = /obj/item/projectile/beam/stun + + modifystate = "elugerstun" + fire_sound = 'sound/weapons/Taser.ogg' + + firemodes = list( + list(mode_name="stun", charge_cost=100,projectile_type=/obj/item/projectile/beam/stun, modifystate="elugerstun", fire_sound='sound/weapons/Taser.ogg'), + list(mode_name="lethal", charge_cost=200,projectile_type=/obj/item/projectile/beam/eluger, modifystate="elugerkill", fire_sound='sound/weapons/eluger.ogg'), + ) + +//////////////////// Custom Ammo //////////////////// +//---------------- Beams ---------------- +/obj/item/projectile/beam/eluger + name = "laser beam" + icon_state = "emitter" + +/obj/item/projectile/beam/dominator + name = "dominator lethal beam" + icon_state = "xray" + muzzle_type = /obj/effect/projectile/xray/muzzle + tracer_type = /obj/effect/projectile/xray/tracer + impact_type = /obj/effect/projectile/xray/impact + +/obj/item/projectile/beam/stun/kin21 + name = "kinh21 stun beam" + icon_state = "omnilaser" + muzzle_type = /obj/effect/projectile/laser_omni/muzzle + tracer_type = /obj/effect/projectile/laser_omni/tracer + impact_type = /obj/effect/projectile/laser_omni/impact + +//--------------- StG-60 ---------------- +/obj/item/ammo_magazine/stg + name = "box mag (7.92x33mm Kurz)" + icon = 'icons/obj/ammo_vr.dmi' + icon_state = "stg_30rnd" + caliber = "kurz" + ammo_type = /obj/item/ammo_casing/stg + max_ammo = 30 + mag_type = MAGAZINE + +/obj/item/ammo_casing/stg + desc = "A 7.92×33mm Kurz casing." + icon_state = "rifle-casing" + caliber = "kurz" + projectile_type = /obj/item/projectile/bullet/rifle/a762 + +/obj/item/ammo_magazine/stg/empty + initial_ammo = 0 + +//------------- Battlerifle ------------- +/obj/item/ammo_magazine/battlerifle + name = "box mag (9.5x40mm)" + icon = 'icons/obj/ammo_vr.dmi' + icon_state = "battlerifle" + caliber = "9.5x40mm" + ammo_type = /obj/item/ammo_casing/a95mm + max_ammo = 36 + mag_type = MAGAZINE + multiple_sprites = 1 + +/obj/item/ammo_casing/a95mm + desc = "A 9.5x40mm bullet casing." + icon_state = "rifle-casing" + caliber = "9.5x40mm" + projectile_type = /obj/item/projectile/bullet/rifle/a95mm + +/obj/item/projectile/bullet/rifle/a95mm + damage = 40 + penetrating = 2 // Better penetration than the 7.62mm + +/obj/item/ammo_magazine/battlerifle/empty + initial_ammo = 0 + +//---------------- PDW ------------------ +/obj/item/ammo_magazine/mc9mml + name = "\improper SMG magazine (9mm)" + icon = 'icons/obj/ammo_vr.dmi' + icon_state = "smg" + origin_tech = list(TECH_COMBAT = 2) + mag_type = MAGAZINE + matter = list(DEFAULT_WALL_MATERIAL = 1800) + caliber = "9mm" + ammo_type = /obj/item/ammo_casing/c9mm + max_ammo = 30 + multiple_sprites = 1 + +/obj/item/ammo_magazine/mc9mml/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/mc9mml/ap + name = "\improper SMG magazine (9mm armor-piercing)" + ammo_type = /obj/item/ammo_casing/c9mm/ap + +/obj/item/ammo_magazine/mc9mml/flash + name = "\improper SMG magazine (9mm flash)" + ammo_type = /obj/item/ammo_casing/c9mmf + +/obj/item/ammo_magazine/mc9mml/rubber + name = "\improper SMG magazine (9mm rubber)" + ammo_type = /obj/item/ammo_casing/c9mmr + +/obj/item/ammo_magazine/mc9mml/practice + name = "\improper SMG magazine (9mm practice)" + ammo_type = /obj/item/ammo_casing/c9mmp \ No newline at end of file diff --git a/code/citadel/vore/fluffstuff/custom_items_vr.dm b/code/citadel/vore/fluffstuff/custom_items_vr.dm new file mode 100644 index 0000000000..4f53c5866a --- /dev/null +++ b/code/citadel/vore/fluffstuff/custom_items_vr.dm @@ -0,0 +1,345 @@ +/* TUTORIAL + "icon" is the file with the HUD/ground icon for the item + "icon_state" is the iconstate in this file for the item + "icon_override" is the file with the on-mob icons, can be the same file + "item_state" is the iconstate for the on-mob icons: + item_state_s is used for worn uniforms on mobs + item_state_r and item_state_l are for being held in each hand + + "item_state_slots" can replace "item_state", it is a list: + item_state_slots["slotname1"] = "item state for that slot" + item_state_slots["slotname2"] = "item state for that slot" +*/ + +/* TEMPLATE +//ckey:Character Name +/obj/item/weapon/fluff/charactername + name = "" + desc = "" + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "myicon" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "myicon" + +*/ + +//For general use +/obj/item/device/modkit_conversion + name = "modification kit" + desc = "A kit containing all the needed tools and parts to modify a suit and helmet." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "modkit" + var/parts = 3 + var/from_helmet = /obj/item/clothing/head/helmet/space/void + var/from_suit = /obj/item/clothing/suit/space/void + var/to_helmet = /obj/item/clothing/head/cardborg + var/to_suit = /obj/item/clothing/suit/cardborg + + //Conversion proc + afterattack(obj/O, mob/user as mob) + var/flag + var/to_type + if(istype(O,from_helmet)) + flag = 1 + to_type = to_helmet + else if(istype(O,from_suit)) + flag = 2 + to_type = to_suit + else + return + if(!(parts & flag)) + user << "This kit has no parts for this modification left." + return + if(istype(O,to_type)) + user << "[O] is already modified." + return + if(!isturf(O.loc)) + user << "[O] must be safely placed on the ground for modification." + return + playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1) + var/N = new to_type(O.loc) + user.visible_message("[user] opens \the [src] and modifies \the [O] into \the [N].","You open \the [src] and modify \the [O] into \the [N].") + qdel(O) + parts &= ~flag + if(!parts) + qdel(src) + +//JoanRisu:Joan Risu +/obj/item/weapon/flame/lighter/zippo/fluff/joan + name = "Federation Zippo Lighter" + desc = "A red zippo lighter with the United Federation Logo on it." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "joanzip" + +//JoanRisu:Joan Risu +/obj/item/weapon/sword/fluff/joanaria + name = "Aria" + desc = "A beautifully crafted rapier owned by Joan Risu. It has a thin blade and is used for quick attacks." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "joanaria" + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "joanariamob" + origin_tech = "materials=7" + force = 15 + sharp = 1 + edge = 1 + hitsound = 'sound/weapons/bladeslice.ogg' + + +/obj/item/weapon/sword/fluff/joanaria/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + + if(default_parry_check(user, attacker, damage_source) && prob(75)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) + return 1 + return 0 + +//joanrisu:Katarina Eine +/obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina + name = "tactical Knife" + desc = "A tactical knife with a small butterly engraved on the blade." + +obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") + + if(default_parry_check(user, attacker, damage_source) && prob(75)) + user.visible_message("\The [user] parries [attack_text] with \the [src]!") + playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1) + return 1 + return 0 + +//For General use +/obj/item/weapon/sword/fluff/joanaria/scisword + name = "Scissor Blade" + desc = "A sword that can not only cut down your enemies, it can also cut fabric really neatly" + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "scisword" + origin_tech = "materials=7" + + +//john.wayne9392:Harmony Prechtl +/obj/item/weapon/twohanded/fireaxe/fluff/mjollnir + name = "Mjollnir" + desc = "Large hammer that looks like it can do a great deal of damage if properly used." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "harmonymjollnir" + origin_tech = "materials=7" + attack_verb = list("attacked", "hammered", "smashed", "slammed", "crushed") + +//JoanRisu:Joan Risu +/obj/item/weapon/card/id/centcom/fluff/joanbadge + name = "Faded Badge" + desc = "A faded badge, backed with leather, that reads 'NT Security Force' across the front." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "joanbadge" + registered_name = "Joan Risu" + assignment = "Centcom Officer" + + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("[user] flashes their golden security badge.\nIt reads:NT Security.","You display the faded badge.\nIt reads: NT Security.") + + attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("[user] invades [M]'s personal space, thrusting [src] into their face insistently.","You invade [M]'s personal space, thrusting [src] into their face insistently.") + +//JoanRisu:Joan Risu +/obj/item/device/pda/heads/hos/fluff/joanpda + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "pda-joan" + +//Vorrarkul:Lucina Dakarim +/obj/item/device/pda/heads/hos/fluff/lucinapda + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "pda-lucina" + +//john.wayne9392:Harmony Prechtl +/obj/item/device/modkit_conversion/fluff/harmonyspace + name = "Harmony's captain space suit modkit" + desc = "A kit containing all the needed tools and parts to modify a Captain's hardsuit. It has green and yellow parts inside." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "harmony_kit" + + from_helmet = /obj/item/clothing/head/helmet/space/capspace + from_suit = /obj/item/clothing/suit/armor/captain + to_helmet = /obj/item/clothing/head/helmet/space/capspace/fluff/harmhelm + to_suit = /obj/item/clothing/suit/armor/captain/fluff/harmsuit + +//john.wayne9392:Harmony Prechtl +/obj/item/device/modkit_conversion/fluff/harmonysuit + name = "Harmony's captain suit modkit" + desc = "A sewing kit containing all the needed tools and fabric to modify a Captain's suit and hat. It has green and yellow fabrics inside." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "harmony_kit" + + from_helmet = /obj/item/clothing/head/caphat + from_suit = /obj/item/clothing/under/rank/captain + to_helmet = /obj/item/clothing/head/centhat/fluff/harmhat + to_suit = /obj/item/clothing/under/rank/captain/fluff/harmuniform + +//scree:Scree +/obj/item/device/modkit_conversion/fluff/screekit + name = "Scree's hardsuit modification kit" + desc = "A kit containing all the needed tools and parts to modify a hardsuit for a specific user. This one looks like it's fitted for a winged creature." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "modkit" + + from_helmet = /obj/item/clothing/head/helmet/space/void/engineering + from_suit = /obj/item/clothing/suit/space/void/engineering + to_helmet = /obj/item/clothing/head/helmet/space/void/engineering/fluff/screehelm + to_suit = /obj/item/clothing/suit/space/void/engineering/fluff/screespess + +//General Use +/obj/item/weapon/flag + name = "Nanotrasen Banner" + desc = "I pledge allegiance to the flag of a megacorporation in space." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "Flag_Nanotrasen" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "Flag_Nanotrasen_mob" + + attack_self(mob/user as mob) + if(isliving(user)) + user.visible_message("[user] waves their Banner around!","You wave your Banner around.") + + attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("[user] invades [M]'s personal space, thrusting [src] into their face insistently.","You invade [M]'s personal space, thrusting [src] into their face insistently.") + + + federation + name = "Federation Banner" + desc = "Space, The Final Frontier. Sorta. Just go with it and say the damn oath." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "flag_federation" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "flag_federation_mob" + + xcom + name = "Alien Combat Command Banner" + desc = "A banner bearing the symbol of a task force fighting an unknown alien power." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "flag_xcom" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "flag_xcom_mob" + + advent + name = "ALIEN Coalition Banner" + desc = "A banner belonging to traitors who work for an unknown alien power." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "flag_advent" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "flag_advent_mob" + + +//zodiacshadow: ? +/obj/item/device/radio/headset/fluff/zodiacshadow + name = "Nehi's 'phones" + desc = "A pair of old-fashioned purple headphones for listening to music that also double as an NT-approved headset; they connect nicely to any standard PDA. One side is engraved with the letters NEHI, the other having an elaborate inscription of the words \"My voice is my weapon of choice\" in a fancy font. A modern polymer allows switching between modes to either allow one to hear one's surroundings or to completely block them out." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "headphones" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "headphones_mob" + + +// OrbisA: Richard D'angelo +/obj/item/weapon/melee/fluff/holochain + name = "Holographic Chain" + desc = "A High Tech solution to simple perversions. It has a red leather handle and the initials R.D. on the silver base." + + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "holochain" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "holochain_mob" + + flags = CONDUCT | NOBLOODY + no_attack_log = 1 //if you want to turn on the attack log for this, comment/delete this line. Orbis. + slot_flags = SLOT_BELT + force = 10 + throwforce = 3 + w_class = 3 + damtype = HALLOSS + attack_verb = list("flogged", "whipped", "lashed", "disciplined", "chastised", "flayed") + +// joey4298:Emoticon +/obj/item/device/fluff/id_kit_mime + name = "Mime ID reprinter" + desc = "Stick your ID in one end and it'll print a new ID out the other!" + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "labeler1" + + afterattack(obj/O, mob/user as mob) + var/new_icon = "mime" + if(istype(O,/obj/item/weapon/card/id) && O.icon_state != new_icon) + //O.icon = src.icon // just in case we're using custom sprite paths with fluff items. + O.icon_state = new_icon // Changes the icon without changing the access. + playsound(user.loc, 'sound/items/polaroid2.ogg', 100, 1) + user.visible_message(" [user] reprints their ID.") + del(src) + else if(O.icon_state == new_icon) + user << "[O] already has been reprinted." + return + else + user << "This isn't even an ID card you idiot." + return + +//arokha:Aronai Kadigan +/obj/item/weapon/card/id/centcom/fluff/aro + registered_name = "CONFIGURE ME" + assignment = "CC Medical" + var/configured = 0 + + attack_self(mob/user as mob) + if(configured == 1) return ..() + + user.set_id_info(src) + configured = 1 + user << "Card settings set." + +//arokha:Aronai Kadigan +/obj/item/weapon/reagent_containers/hypospray/fluff/aronai + name = "worn hypospray" + desc = "This hypospray seems a bit well-used. The blue band indicates it's from the CentCom medical division. There's an 'A' scratched into the bottom." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "aro_hypo" + + New() + ..() + reagents.add_reagent("inaprovaline", 5) + reagents.add_reagent("tricordrazine", 25) + +//Swat43:Fortune Bloise +/obj/item/weapon/storage/backpack/satchel/fluff/swat43bag + name = "Coloured Satchel" + desc = "That's a coloured satchel with red stripes, with a heart and ripley logo on each side." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "swat43-bag" + + icon_override = 'icons/vore/custom_items_vr.dmi' + item_state = "swat43-bag_mob" + + +//Dhaeleena:Dhaeleena M'iar +/obj/item/clothing/accessory/medal/silver/security/fluff/dhael + desc = "An award for distinguished combat and sacrifice in defence of corporate commercial interests. Often awarded to security staff. It's engraved with the letters S.W.A.T." + +//Vorrarkul:Lucina Dakarim +/obj/item/clothing/accessory/medal/gold/fluff/lucina + name = "Medal of Medical Excellence" + desc = "A medal awarded to Lucina Darkarim for excellence in medical service." diff --git a/code/citadel/vore/fluffstuff/custom_permits_vr.dm b/code/citadel/vore/fluffstuff/custom_permits_vr.dm new file mode 100644 index 0000000000..19eddd95da --- /dev/null +++ b/code/citadel/vore/fluffstuff/custom_permits_vr.dm @@ -0,0 +1,130 @@ +// BEGIN - DO NOT EDIT PROTOTYPE +/obj/item/fluff/permit + name = "Sample Permit" + desc = {"There is a bright red SAMPLE PERMIT stamped across the stock photo displayed on the card. Obviously this is only an example to educate security. + NAME: First Last | RACE: Human | HOMEWORLD: Moon (if applicable), Planet, System + DOB: DD/Mon/YYYY | HEIGHT: XXcm | SEX: Female + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to ___________________. + This license expires on DD/Month/YYYY and must be renewed by CentCom prior to this date."} + icon = 'icons/obj/card.dmi' + icon_state = "guest" + w_class = 1 +// END - DO NOT EDIT PROTOTYPE + +/* TEMPLATE +/obj/item/fluff/permit/charactername + name = "Name's Thing Permit" + desc = {" + NAME: Firstname Lastname | RACE: Human | HOMEWORLD: Earth, Sol + DOB: DD/Mon/YYYY | HEIGHT: XXXcm | SEX: X + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry XYZ. CONDITIONS. + This license expires on DD/Mon/YYYY and must be renewed by CentCom prior to this date."} +*/ + +// bwoincognito:Tasald Corlethian +/obj/item/fluff/permit/tasald_corlethian + name = "Tasald Ajax Corlethian's Sidearm Permit" + desc = {" + NAME: Tasald Ajax Corlethian | RACE: Vulpine | HOMEWORLD: Iscyn, Orta + DOB: 09/Sep/2529 | HEIGHT: 187cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one .38 pistol. + This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."} + +/* +// jertheace:Jeremiah 'Ace' Acacius +/obj/item/fluff/permit/jerace + name = "Ace's Shotgun Permit" + desc = {" + NAME: Jeremiah Acacius | RACE: Human | HOMEWORLD: Earth, Sol + DOB: 17/Jun/2532 | HEIGHT: 178cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry one M45D shotgun loaded with less-than-lethal munitions as a head of staff. Else this weapon is to be turned in to security for holding until the end of the shift. + This license expires on 01/Jun/2560 and must be renewed by CentCom prior to this date."} +*/ + +/* +// sasoperative:Joseph Skinner +/obj/item/fluff/permit/josephskinner + name = "Joseph Skinner's 12g Revolver Permit" + desc = {" + NAME: Joseph Cyrus Skinner | RACE: Human | HOMEWORLD: Earth, Sol + DOB: 10/Jun/2532 | HEIGHT: 162.5cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one 12 gauge revolver loaded with less-than-lethal munitions as a member of security or head of staff. Else this weapon is to be turned in to security for holding until the end of the shift. + This license expires on 29/Nov/2559 and must be renewed by CentCom prior to this date."} +*/ + +/* +// wankersonofjerkin:Ryan Winz +/obj/item/fluff/permit/ryanwinz + name = "Ryan Winz's Revolver Permit" + desc = {" + NAME: Ryan Winz | RACE: Human | HOMEWORLD: New Ekaterina, Moskva + DOB: 27/Oct/2536 | HEIGHT: 172cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry one Colt Single-Action Army revolver as a security officer or head of staff. Else this weapon is to be turned in to security for holding until the end of the shift. + This license expires on 26/Dec/2559 and must be renewed by CentCom prior to this date."} +*/ + +// bwoincognito:Tasald Corlethian +/obj/item/fluff/permit/tasald_corlethian + name = "Tasald Ajax Corlethian's Sidearm Permit" + desc = {" + NAME: Tasald Ajax Corlethian | RACE: Vulpine | HOMEWORLD: Iscyn, Orta + DOB: 09/Sep/2529 | HEIGHT: 187cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one .38 pistol. + This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."} + +// arokha:Aronai Kadigan +/obj/item/fluff/permit/aronai_kadigan + name = "Aronai Kadigan's Sidearm Permit" + desc = {" + NAME: Aronai Kadigan | RACE: Cross Fox | HOMEWORLD: New Kitsuhana, KHI1 + DOB: 12/Jul/2530 | HEIGHT: 188cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one KIN-H21 (Egun Variant). + This license expires on 30/Sep/2560 and must be renewed by CentCom prior to this date."} + +// joanrisu:Joan Risu +/obj/item/fluff/permit/joanrisu + name = "Joan Risu's Sidearm Permit" + desc = {" + NAME: Joan Risu | RACE: Squirrelkin | HOMEWORLD: Luna, Gaia, Koi + DOB: 16/Apr/2536 | HEIGHT: 161cm | SEX: Female + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one MWPSB Dominator. + This license expires on 11/Dec/2560 and must be renewed by CentCom prior to this date."} + +// molenar:Kari Akiren +/obj/item/fluff/permit/kari_akiren + name = "Kari Akiren's Rifle Permit" + desc = {" + NAME: Kari Akiren | RACE: Inkling | HOMEWORLD: Supesu + DOB: 26-Jun-2553 | HEIGHT: 163cm | SEX: Female + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one Clockwork Rifle (bolt-action variant). + This license expires on 14/Dec/2560 and must be renewed by CentCom prior to this date."} + +//eekasqueak: Serkii Miishy +/obj/item/fluff/permit/serkiimiishy + name = "Serkii Miishy's Stun Revolver Permit" + desc = {" + NAME: Serkii Miishy | RACE: Mousemorph | HOMEWORLD: Mars, Sol + DOB: 10/9/2441 | HEIGHT: 122cm | SEX: Male + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one stun revolver. + This license expires on 30/March/2561 and must be renewed by CentCom prior to this date."} + +//Razerwing:Archer Maximus +/obj/item/fluff/permit/archermaximus + name = "Archer Maximus's MEUSOC 45 Permit" + desc = {" + NAME: FArcher Maximus | RACE: Human | HOMEWORLD: Charybdis + DOB: 04/18/2521 | HEIGHT: 172.7cm | SEX: female + + The individual named above is licensed by the Nanotrasen Department of Civil Protection to openly carry a MEUSOC 45. CONDITIONS. + This license expires on 31/May/2561 and must be renewed by CentCom prior to this date."} diff --git a/code/citadel/vore/hook-defs_vr.dm b/code/citadel/vore/hook-defs_vr.dm new file mode 100644 index 0000000000..629b1ba8f3 --- /dev/null +++ b/code/citadel/vore/hook-defs_vr.dm @@ -0,0 +1,37 @@ +//The base hooks themselves + +//New() hooks +/hook/client_new + +/hook/mob_new + +/hook/living_new + +/hook/carbon_new + +/hook/human_new + +/hook/simple_animal_new + +//Hooks for interactions +/hook/living_attackby + +// +//Hook helpers to expand hooks to others +// +/hook/mob_new/proc/chain_hooks(mob/M) + var/result = 1 + if(isliving(M)) + if(!hook_vr("living_new",args)) + result = 0 + + if(iscarbon(M)) + if(!hook_vr("carbon_new",args)) + result = 0 + + if(ishuman(M)) + if(!hook_vr("human_new",args)) + result = 0 + + //Return 1 to superhook + return result \ No newline at end of file diff --git a/code/citadel/vore/resizing/grav_pull_vr.dm b/code/citadel/vore/resizing/grav_pull_vr.dm new file mode 100644 index 0000000000..921d1ab2b9 --- /dev/null +++ b/code/citadel/vore/resizing/grav_pull_vr.dm @@ -0,0 +1,63 @@ +// +// Gravity Pull effect which draws in movable objects to its center. +// In this case, "number" refers to the range. directions is ignored. +// +/datum/effect/effect/system/grav_pull + var/pull_radius = 3 + var/pull_anchored = 0 + var/break_windows = 0 + +/datum/effect/effect/system/grav_pull/set_up(range, num, loca) + pull_radius = range + number = num + if(istype(loca, /turf/)) + location = loca + else + location = get_turf(loca) + +/datum/effect/effect/system/grav_pull/start() + spawn(0) + if(holder) + src.location = get_turf(holder) + for(var/i=0, i < number, i++) + do_pull() + sleep(25) + +/datum/effect/effect/system/grav_pull/proc/do_pull() + //following is adapted from supermatter and singulo code + if(defer_powernet_rebuild != 2) + defer_powernet_rebuild = 1 + + // Let's just make this one loop. + for(var/atom/X in orange(pull_radius, location)) + // Movable atoms only + if(istype(X, /atom/movable)) + if(istype(X, /obj/effect/overlay)) continue + if(X && !istype(X, /mob/living/carbon/human)) + if(break_windows && istype(X, /obj/structure/window)) //shatter windows + var/obj/structure/window/W = X + W.ex_act(2.0) + + if(istype(X, /obj)) + var/obj/O = X + if(O.anchored) + if (!pull_anchored) continue // Don't pull anchored stuff unless configured + step_towards(X, location) // step just once if anchored + continue + + step_towards(X, location) // Step twice + step_towards(X, location) + + else if(istype(X,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = X + if(istype(H.shoes,/obj/item/clothing/shoes/magboots)) + var/obj/item/clothing/shoes/magboots/M = H.shoes + if(M.magpulse) + step_towards(H, location) //step just once with magboots + continue + step_towards(H, location) //step twice + step_towards(H, location) + + if(defer_powernet_rebuild != 2) + defer_powernet_rebuild = 0 + return diff --git a/code/citadel/vore/resizing/holder_micro_vr.dm b/code/citadel/vore/resizing/holder_micro_vr.dm new file mode 100644 index 0000000000..5cdecd9039 --- /dev/null +++ b/code/citadel/vore/resizing/holder_micro_vr.dm @@ -0,0 +1,33 @@ +// Micro Holders - Extends /obj/item/weapon/holder + +/obj/item/weapon/holder/micro + name = "micro" + desc = "Another crewmember, small enough to fit in your hand." + icon_state = "micro" + slot_flags = SLOT_FEET | SLOT_HEAD | SLOT_ID + w_class = 2 + item_icons = null // Override value from parent. We don't have magic sprites. + pixel_y = 0 // Override value from parent. + +/obj/item/weapon/holder/micro/examine(var/mob/user) + for(var/mob/living/M in contents) + M.examine(user) + +/obj/item/weapon/holder/MouseDrop(mob/M as mob) + ..() + if(M != usr) return + if(usr == src) return + if(!Adjacent(usr)) return + if(istype(M,/mob/living/silicon/ai)) return + for(var/mob/living/carbon/human/O in contents) + O.show_inv(usr) + +/obj/item/weapon/holder/micro/attack_self(var/mob/living/user) + for(var/mob/living/carbon/human/M in contents) + M.help_shake_act(user) + +/obj/item/weapon/holder/micro/update_state() + // If any items have been dropped by contained mob, drop them to floor. + for(var/obj/O in contents) + O.forceMove(get_turf(src)) + ..() diff --git a/code/citadel/vore/resizing/resize_vr.dm b/code/citadel/vore/resizing/resize_vr.dm new file mode 100644 index 0000000000..6288b6fe5f --- /dev/null +++ b/code/citadel/vore/resizing/resize_vr.dm @@ -0,0 +1,197 @@ + +//these aren't defines so they can stay in this file +var/const/RESIZE_HUGE = 2 +var/const/RESIZE_BIG = 1.5 +var/const/RESIZE_NORMAL = 1 +var/const/RESIZE_SMALL = 0.5 +var/const/RESIZE_TINY = 0.25 + +//average +var/const/RESIZE_A_HUGEBIG = (RESIZE_HUGE + RESIZE_BIG) / 2 +var/const/RESIZE_A_BIGNORMAL = (RESIZE_BIG + RESIZE_NORMAL) / 2 +var/const/RESIZE_A_NORMALSMALL = (RESIZE_NORMAL + RESIZE_SMALL) / 2 +var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 + +// Adding needed defines to /mob/living +// Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff. +/mob/living + var/size_multiplier = 1 //multiplier for the mob's icon size + +// Define holder_type on types we want to be scoop-able +//mob/living/carbon/human +// holder_type = /obj/item/weapon/holder/micro + +/** + * Scale up the size of a mob's icon by the size_multiplier. + * NOTE: mob/living/carbon/human/update_icons() has a more complicated system and + * is already applying this transform. BUT, it does not call ..() + * as long as that is true, we should be fine. If that changes we need to + * re-evaluate. + */ +/mob/living/update_icons() +// ASSERT(!iscarbon(src)) + var/matrix/M = matrix() + M.Scale(size_multiplier) + M.Translate(0, 16*(size_multiplier-1)) + src.transform = M + +/** + * Get the effective size of a mob. + * Currently this is based only on size_multiplier for micro/macro stuff, + * but in the future we may also incorporate the "mob_size", so that + * a macro mouse is still only effectively "normal" or a micro dragon is still large etc. + */ +/mob/living/proc/get_effective_size() + return src.size_multiplier + +/** + * Resizes the mob immediately to the desired mod, animating it growing/shrinking. + * It can be used by anything that calls it. + */ +/mob/living/proc/resize(var/new_size) + var/matrix/resize = matrix() // Defines the matrix to change the player's size + resize.Scale(new_size) //Change the size of the matrix + + if(new_size >= RESIZE_NORMAL) + resize.Translate(0, -1 * (1 - new_size) * 16) //Move the player up in the tile so their feet align with the bottom + + animate(src, transform = resize, time = 5) //Animate the player resizing + size_multiplier = new_size //Change size_multiplier so that other items can interact with them + +/** + * Verb proc for a command that lets players change their size OOCly. + * Ace was here! Redid this a little so we'd use math for shrinking characters. This is the old code. + */ + /* +/mob/living/proc/set_size() + set name = "Set Character Size" + set category = "Vore" + var/nagmessage = "DO NOT ABUSE THESE COMMANDS. They are not here for you to play with. \ + We were originally going to remove them but kept them for popular demand. \ + Do not abuse their existence outside of ERP scenes where they apply, \ + or reverting OOCly unwanted changes like someone lolshooting the crew with a shrink ray. -Ace" + + var/size_name = input(nagmessage, "Pick a Size") in player_sizes_list + if (size_name && player_sizes_list[size_name]) + src.resize(player_sizes_list[size_name]) + message_admins("[key_name(src)] used the resize command in-game to be [size_name]. \ + ([src ? "JMP" : "null"])") + +/** Add the set_size() proc to usable verbs. */ +/hook/living_new/proc/resize_setup(mob/living/M) + M.verbs += /mob/living/proc/set_size + return 1 + +/** + * Attempt to scoop up this mob up into M's hands, if the size difference is large enough. + * @return false if normal code should continue, 1 to prevent normal code. + */ +/mob/living/proc/attempt_to_scoop(var/mob/living/carbon/human/M) + if(!istype(M)) + return 0; + if(M.buckled) + usr << "You have to unbuckle \the [M] before you pick them up." + return 0 + if(M.get_effective_size() - src.get_effective_size() >= 0.75) + var/obj/item/weapon/holder/m_holder = get_scooped(M) + if (m_holder) + return 1 + else + return 0; // Unable to scoop, let other code run +*/ +/** + * Handle bumping into someone with helping intent. + * Called from /mob/living/Bump() in the 'brohugs all around' section. + * @return false if normal code should continue, 1 to prevent normal code. + * // TODO - can the now_pushing = 0 be moved up? What does it do anyway? + */ +/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob) + if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY) + // Both small! Go ahead and + now_pushing = 0 + return 1 + if(abs(src.get_effective_size() - tmob.get_effective_size()) >= 0.75) + now_pushing = 0 + if(src.get_effective_size() > tmob.get_effective_size()) +// var/mob/living/carbon/human/M = src +// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) +// src << "You carefully slither around [tmob]." +// tmob << "[src]'s huge tail slithers past beside you!" +// else + src << "You carefully step over [tmob]." + tmob << "[src] steps over you carefully!" + if(tmob.get_effective_size() > src.get_effective_size()) +// var/mob/living/carbon/human/M = tmob +// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) +// src << "You jump over [tmob]'s thick tail." +// tmob << "[src] bounds over your tail." +// else + src << "You run between [tmob]'s legs." + tmob << "[src] runs between your legs." + return 1 + +/** + * Handle bumping into someone without mutual help intent. + * Called from /mob/living/Bump() + * NW was here, adding even more options for stomping! + * + * @return false if normal code should continue, 1 to prevent normal code. + */ +/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob) + ASSERT(istype(tmob)) // Baby don't hurt me + + if(src.a_intent == "disarm" && src.canmove && !src.buckled) + // If bigger than them by at least 0.75, move onto them and print message. + if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75) + now_pushing = 0 + src.forceMove(tmob.loc) + tmob.Stun(4) + +// var/mob/living/carbon/human/M = src +// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) +// src << "You carefully squish [tmob] under your tail!" +// tmob << "[src] pins you under their tail!" +// else + src << "You pin [tmob] beneath your foot!" + tmob << "[src] pins you beneath their foot!" + return 1 + + if(src.a_intent == "harm" && src.canmove && !src.buckled) + if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75) + now_pushing = 0 + src.forceMove(tmob.loc) + tmob.adjustStaminaLoss(15) + tmob.adjustBruteLoss(2) + +// var/mob/living/carbon/human/M = src +// if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) + // src << "You steamroller over [tmob] with your heavy tail!" +// tmob << "[src] ploughs you down mercilessly with their heavy tail!" + // else + src << "You bring your foot down heavily upon [tmob]!" + tmob << "[src] steps carelessly on your body!" + return 1 +/* + if(src.a_intent == "grab" && src.canmove && !src.buckled) + if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75) + now_pushing = 0 + src.forceMove(tmob.loc) + + var/mob/living/carbon/human/M = src + if(istype(M) && !M.shoes) + // User is a human (capable of scooping) and not wearing shoes! Scoop into foot slot! + equip_to_slot_if_possible(tmob.get_scooped(M), slot_shoes, 0, 1) +// if(istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) +// src << "You wrap up [tmob] with your powerful tail!" +// tmob << "[src] binds you with their powerful tail!" +// else + src << "You clench your toes around [tmob]'s body!" + tmob << "[src] grabs your body with their toes!" +// else if(istype(M) && istype(M.tail_style, /datum/sprite_accessory/tail/taur/naga)) +// src << "You carefully squish [tmob] under your tail!" +// tmob << "[src] pins you under their tail!" + else + src << "You pin [tmob] beneath your foot!" + tmob << "[src] pins you beneath their foot!" + return 1 +*/ \ No newline at end of file diff --git a/code/citadel/vore/resizing/sizegun_vr.dm b/code/citadel/vore/resizing/sizegun_vr.dm new file mode 100644 index 0000000000..2d88c7ab25 --- /dev/null +++ b/code/citadel/vore/resizing/sizegun_vr.dm @@ -0,0 +1,83 @@ +// +// Size Gun +// + +/obj/item/weapon/gun/energy/sizegun + name = "shrink ray" + desc = "A highly advanced ray gun with two settings: Shrink and Grow. Warning: Do not insert into mouth." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "sizegun-shrink100" // Someone can probably do better. -Ace + item_state = null //so the human update icon uses the icon_state instead + fire_sound = 'sound/weapons/wave.ogg' + charge_cost = 100 + projectile_type = /obj/item/projectile/beam/shrinklaser + origin_tech = "redspace=1;bluespace=4" + modifystate = "sizegun-shrink" + self_recharge = 1 + firemodes = list( + list(mode_name = "grow", + projectile_type = /obj/item/projectile/beam/growlaser, + modifystate = "sizegun-grow", + fire_sound = 'sound/weapons/pulse3.ogg' + ), + list(mode_name = "shrink", + projectile_type = /obj/item/projectile/beam/shrinklaser, + modifystate = "sizegun-shrink", + fire_sound = 'sound/weapons/wave.ogg' + )) + +// +// Beams for size gun +// + +/obj/item/projectile/beam/shrinklaser + name = "shrink beam" + icon_state = "xray" + nodamage = 1 + damage = 0 + check_armour = "laser" + + muzzle_type = /obj/effect/projectile/xray/muzzle + tracer_type = /obj/effect/projectile/xray/tracer + impact_type = /obj/effect/projectile/xray/impact + +/obj/item/projectile/beam/shrinklaser/on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living)) + var/mob/living/M = target + switch(M.size_multiplier) + if(RESIZE_HUGE to INFINITY) + M.resize(RESIZE_BIG) + if(RESIZE_BIG to RESIZE_HUGE) + M.resize(RESIZE_NORMAL) + if(RESIZE_NORMAL to RESIZE_BIG) + M.resize(RESIZE_SMALL) + if((0 - INFINITY) to RESIZE_NORMAL) + M.resize(RESIZE_TINY) + M.update_icons() + return 1 + +/obj/item/projectile/beam/growlaser + name = "growth beam" + icon_state = "bluelaser" + nodamage = 1 + damage = 0 + check_armour = "laser" + + muzzle_type = /obj/effect/projectile/laser_blue/muzzle + tracer_type = /obj/effect/projectile/laser_blue/tracer + impact_type = /obj/effect/projectile/laser_blue/impact + +/obj/item/projectile/beam/growlaser/on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living)) + var/mob/living/M = target + switch(M.size_multiplier) + if(RESIZE_BIG to RESIZE_HUGE) + M.resize(RESIZE_HUGE) + if(RESIZE_NORMAL to RESIZE_BIG) + M.resize(RESIZE_BIG) + if(RESIZE_SMALL to RESIZE_NORMAL) + M.resize(RESIZE_NORMAL) + if((0 - INFINITY) to RESIZE_TINY) + M.resize(RESIZE_SMALL) + M.update_icons() + return 1 diff --git a/code/citadel/vore/trycatch_vr.dm b/code/citadel/vore/trycatch_vr.dm new file mode 100644 index 0000000000..7a369df24d --- /dev/null +++ b/code/citadel/vore/trycatch_vr.dm @@ -0,0 +1,62 @@ +/* +This file is for jamming single-line procs into Polaris procs. +It will prevent runtimes and allow their code to run if VOREStation's fails. +It will also log when we mess up our code rather than making it vague. + +Call it at the top of a stock proc with... + +if(attempt_vr(object,proc to call,args)) return + +...if you are replacing an entire proc. + +The proc you're attemping should return nonzero values on success. +*/ + +/proc/attempt_vr(callon, procname, list/args=null) + try + if(!callon || !procname) + // error("attempt_vr: Invalid obj/proc: [callon]/[procname]") + return 0 + + var/result = call(callon,procname)(arglist(args)) + + return result + + catch + log_admin("attempt_vr runtimed when calling [procname] on [callon].") + // error("attempt_vr catch: [e] on [e.file]:[e.line]") +// return 0 + +/* +This is the _vr version of calling hooks. +It's meant to have different messages, and also the try/catch block. +For when you want hooks and want to know when you ruin everything, +vs when Polaris ruins everything. + +Call it at the top of a stock proc with... + +if(hook_vr(proc,args)) return + +...if you are replacing an entire proc. + +The hooks you're calling should return nonzero values on success. +*/ +/proc/hook_vr(hook, list/args=null) + try + var/hook_path = text2path("/hook/[hook]") + if(!hook_path) + // error("hook_vr: Invalid hook '/hook/[hook]' called.") + return 0 + + var/caller = new hook_path + var/status = 1 + for(var/P in typesof("[hook_path]/proc")) + if(!call(caller, P)(arglist(args))) + // error("hook_vr: Hook '[P]' failed or runtimed.") + status = 0 + + return status + + catch + log_admin("hook_vr itself failed or runtimed. Exception below.") +// error("hook_vr catch: [e] on [e.file]:[e.line]") diff --git a/code/citadel/vore/weight/fit_vr.dmi b/code/citadel/vore/weight/fit_vr.dmi new file mode 100644 index 0000000000..07d6893532 Binary files /dev/null and b/code/citadel/vore/weight/fit_vr.dmi differ diff --git a/code/citadel/vore/weight/fitness_machines_vr.dm b/code/citadel/vore/weight/fitness_machines_vr.dm new file mode 100644 index 0000000000..55e4d012d8 --- /dev/null +++ b/code/citadel/vore/weight/fitness_machines_vr.dm @@ -0,0 +1,141 @@ +/obj/machinery/workout + name = "fitness lifter" + icon = 'code/modules/vore/weight/fit_vr.dmi' + icon_state = "fitnesslifter" //Sprites ripped from goon. + desc = "A utility often used to lose weight." + anchored = 1 + use_power = 0 + idle_power_usage = 0 + active_power_usage = 0 + +/obj/machinery/workout/attackby(obj/item/W, var/mob/living/user) + if(istype(W, /obj/item/weapon/wrench)) + src.add_fingerprint(user) + user.visible_message("[user] has [anchored ? "un" : ""]secured \the [src].", "You [anchored ? "un" : ""]secure \the [src].") + anchored = !anchored + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + return + +/obj/machinery/workout/attack_hand(var/mob/living/user) + if(!anchored) + user << "For safety reasons, you are required to have this equipment wrenched down before using it!" + return + + else if(user.loc != src.loc) + user << "For safety reasons, you need to be sitting in the fitness lifter for it to work!" + return + + else if(user.nutrition > 70 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise. + user.setClickCooldown(40) + user.dir = src.dir + user.nutrition = user.nutrition - 20 //Working out burns a lot of calories! + user.weight = user.weight - 0.05 //Burn a bit of weight. Not much, but quite a bit. This can't be spammed, as they'll need nutrition to be able to work out. + flick("fitnesslifter2",src) + user << "You lift some weights." + + else if(user.nutrition < 70) + user << "You need more energy to workout on the mat!" + + else if(user.weight < 70) + user << "You're too skinny to risk losing any more weight!" + + else + user << "You're unable to use the fitness lifter." + return //Something went wrong. They shouldn't see this. + +/obj/machinery/workout/shipped + anchored = 0 // For cargo. + + +/obj/machinery/punching_bag + name = "punching bag" + icon = 'code/modules/vore/weight/fit_vr.dmi' + icon_state = "punchingbag" + desc = "A bag often used to releive stress and burn fat." + anchored = 1 + density = 1 + use_power = 0 + idle_power_usage = 0 + active_power_usage = 0 + +/obj/machinery/punching_bag/attack_hand(var/mob/living/user) + + if(user.nutrition > 35 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise. + user.setClickCooldown(10) + user.nutrition = user.nutrition - 10 //A punching bag uses less calories. + user.weight = user.weight - 0.025 //And burns less weight. + flick("punchingbag2",src) + var/message = pick( + "You slam your fist into the punching bag.", + "You jab the punching bag with your elbow.") + user << message + playsound(src.loc, "punch", 50, 1) + + else if(user.nutrition < 35) + user << "You need more energy to workout on the mat!" + + else if(user.weight < 70) + user << "You're too skinny to risk losing any more weight!" + + else + user << "You're unable to use the punching bag." + return //Something went wrong. They shouldn't see this. + + +/obj/machinery/punching_clown + name = "clown punching bag" + icon = 'code/modules/vore/weight/fit_vr.dmi' + icon_state = "bopbag" + desc = "A bag often used to releive stress and burn fat. It has a clown on the front of it." + anchored = 0 + density = 1 + use_power = 0 + idle_power_usage = 0 + active_power_usage = 0 + +/obj/machinery/punching_clown/attack_hand(var/mob/living/user) + + if(user.nutrition > 35 && user.weight > 70) //If they have enough nutrition and body weight, they can exercise. + user.setClickCooldown(10) + user.nutrition = user.nutrition - 10 + user.weight = user.weight - 0.025 + flick("bopbag2",src) + var/message = pick( + "You slam your fist into the punching bag.", + "You jab the punching bag with your elbow.", + "You hammer the clown right in it's face with your fist.", + "A honk emits from the punching bag as you hit it.") + user << message + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + playsound(src.loc, "clownstep", 50, 1) + playsound(src.loc, "punch", 50, 1) + + else if(user.nutrition < 35) + user << "You need more energy to workout on the mat!" + + else if(user.weight < 70) + user << "You're too skinny to risk losing any more weight!" + + else + user << "You're unable to use the punching bag." + return //Something went wrong. They shouldn't see this. + +/obj/machinery/scale + name = "scale" + icon = 'code/modules/vore/weight/fit_vr.dmi' + icon_state = "scale" + desc = "A scale used to measure ones weight relative to their size and species." + anchored = 1 // Set to 0 when we can construct or dismantle these. + use_power = 0 + idle_power_usage = 0 + active_power_usage = 0 + var/kilograms + +/obj/machinery/scale/attack_hand(var/mob/living/user) + if(user.loc != src.loc) + user << "You need to be standing on top of the scale for it to work!" + return + if(user.weight) //Just in case. + kilograms = round(text2num(user.weight),4) / 2.20463 + user << "Your relative weight is [user.weight]lb / [kilograms]kg." + user.visible_message("[user]'s relative weight is [user.weight]lb / [kilograms]kg.") diff --git a/code/citadel/whitelist.dm b/code/citadel/whitelist.dm deleted file mode 100644 index d53fd2b461..0000000000 --- a/code/citadel/whitelist.dm +++ /dev/null @@ -1,6 +0,0 @@ -var/list/whitelist_keys=new() -proc/is_whitelisted(var/keychk) - keychk=ckey(keychk) - if(whitelist_keys.Find(keychk)) - return 1 - return 0 \ No newline at end of file diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm new file mode 100644 index 0000000000..475537300c --- /dev/null +++ b/code/controllers/hooks.dm @@ -0,0 +1,39 @@ +/** + * @file hooks.dm + * Implements hooks, a simple way to run code on pre-defined events. + */ + +/** @page hooks Code hooks + * @section hooks Hooks + * A hook is defined under /hook in the type tree. + * + * To add some code to be called by the hook, define a proc under the type, as so: + * @code +/hook/foo/proc/bar() + if(1) + return 1 //Sucessful + else + return 0 //Error, or runtime. + * @endcode + * All hooks must return nonzero on success, as runtimes will force return null. + */ + +/** + * Calls a hook, executing every piece of code that's attached to it. + * @param hook Identifier of the hook to call. + * @returns 1 if all hooked code runs successfully, 0 otherwise. + */ +/proc/callHook(hook, list/args=null) + var/hook_path = text2path("/hook/[hook]") + if(!hook_path) + // error("Invalid hook '/hook/[hook]' called.") + return 0 + + var/caller = new hook_path + var/status = 1 + for(var/P in typesof("[hook_path]/proc")) + if(!call(caller, P)(arglist(args))) + // error("Hook '[P]' failed or runtimed.") + status = 0 + + return status diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 8d47a1a58d..63104023bb 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -186,6 +186,16 @@ H.adjustBrainLoss(CLONE_INITIAL_DAMAGE) H.Paralyse(4) + if(H.client.prefs) + H.vore_organs = H.client.prefs.belly_prefs.Copy() + for(var/I in H.vore_organs) + var/datum/belly/B = H.vore_organs[I] + B.owner = H + B.internal_contents = list() + B.digest_mode = DM_HOLD + +// H.flavor_text = R.flavor.Copy() + if(grab_ghost_when == CLONER_FRESH_CLONE) clonemind.transfer_to(H) H.ckey = ckey diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 25e9573fe0..8fd54c1a9d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -105,6 +105,10 @@ var/list/preferences_datums = list() //var/metadata = "" var/flavor_text = "" + // Vore prefs + var/digestable = 1 + var/list/belly_prefs = list() + var/unlock_content = 0 var/list/ignoring = list() @@ -123,6 +127,8 @@ var/list/preferences_datums = list() var/loaded_preferences_successfully = load_preferences() if(loaded_preferences_successfully) if(load_character()) + if(load_vore_preferences()) + return return //we couldn't load character data so just randomize the character appearance + name random_character() //let's create a random character then - rather than a fat, bald and naked man. @@ -1252,12 +1258,15 @@ var/list/preferences_datums = list() if("save") save_preferences() save_character() + save_vore_preferences() if("load") load_preferences() load_character() + load_vore_preferences() if("changeslot") + load_vore_preferences(text2num(href_list["num"])) if(!load_character(text2num(href_list["num"]))) random_character() real_name = random_unique_name(gender) @@ -1289,6 +1298,23 @@ var/list/preferences_datums = list() character.name = character.real_name character.flavor_text = flavor_text + if(!length(belly_prefs)) + var/datum/belly/B = new /datum/belly(src) + B.immutable = 1 + B.name = "Stomach" + B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [character]." + belly_prefs[B.name] = B + + character.vore_organs = belly_prefs + + character.vore_selected = character.vore_organs[1] + + for(var/I in character.vore_organs) + var/datum/belly/B = character.vore_organs[I] + B.owner = character + + character.digestable = digestable + character.gender = gender character.age = age diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 655cfff137..30d98ca110 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -172,6 +172,44 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car backbag = DBACKPACK +// +// Save/Load Vore Preferences +// +/datum/preferences/proc/load_vore_preferences(slot) + if(!path) return 0 //Path couldn't be set? + if(!fexists(path)) //Never saved before + save_vore_preferences() //Make the file first + return 1 + + var/savefile/S = new /savefile(path) + if(!S) return 0 //Savefile object couldn't be created? + + S.cd = "/character[slot]" + + S["digestable"] >> digestable + S["belly_prefs"] >> belly_prefs + + if(isnull(digestable)) + digestable = 1 + if(isnull(belly_prefs)) + belly_prefs = list() + + return 1 + +/datum/preferences/proc/save_vore_preferences() + if(!path) + return 0 + var/savefile/S = new /savefile(path) + if(!S) + return 0 + S.cd = "/character[default_slot]" + + S["digestable"] << digestable + S["belly_prefs"] << belly_prefs + + return 1 + + /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return diff --git a/code/modules/client/preferences_vr.dm b/code/modules/client/preferences_vr.dm new file mode 100644 index 0000000000..0f9b6935d3 --- /dev/null +++ b/code/modules/client/preferences_vr.dm @@ -0,0 +1,8 @@ +//File isn't currently being used. +/datum/preferences + var/biological_gender = MALE + var/identifying_gender = MALE + +/datum/preferences/proc/set_biological_gender(var/gender) + biological_gender = gender + identifying_gender = gender \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine_vr.dm b/code/modules/mob/living/carbon/human/examine_vr.dm new file mode 100644 index 0000000000..8578db809e --- /dev/null +++ b/code/modules/mob/living/carbon/human/examine_vr.dm @@ -0,0 +1,54 @@ +/mob/living/carbon/human/proc/examine_nutrition() + var/message = "" + var/nutrition_examine = round(nutrition) + var/t_He = "It" //capitalised for use at the start of each line. + var/t_His = "Its" + var/t_his = "its" + var/t_is = "is" + var/t_has = "has" + switch(gender) + if(MALE) + t_He = "He" + t_his = "his" + t_His = "His" + if(FEMALE) + t_He = "She" + t_his = "her" + t_His = "Her" + if(PLURAL) + t_He = "They" + t_his = "their" + t_His = "Their" + t_is = "are" + t_has = "have" + if(NEUTER) + t_He = "It" + t_his = "its" + t_His = "Its" + switch(nutrition_examine) + if(0 to 49) + message = "[t_He] [t_is] starving! You can hear [t_his] stomach snarling from across the room!\n" + if(50 to 99) + message = "[t_He] [t_is] extremely hungry. A deep growl occasionally rumbles from [t_his] empty stomach.\n" + if(100 to 499) + return message //Well that's pretty normal, really. + if(500 to 864) // Fat. + message = "[t_He] [t_has] a stuffed belly, bloated fat and round from eating too much.\n" + if(1200 to 1934) // One person fully digested. + message = "[t_He] [t_is] sporting a large, round, sagging stomach. It's contains at least their body weight worth of glorping slush.\n" + if(1935 to 3004) // Two people. + message = "[t_He] [t_is] engorged with a huge stomach that sags and wobbles as they move. [t_He] must have consumed at least twice their body weight. It looks incredibly soft.\n" + if(3005 to 4074) // Three people. + message = "[t_His] stomach is firmly packed with digesting slop. [t_He] must have eaten at least a few times worth their body weight! It looks hard for them to stand, and [t_his] gut jiggles when they move.\n" + if(4075 to 10000) // Four or more people. + message = "[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!\n" + return message + +/mob/living/carbon/human/proc/examine_bellies() + var/message = "" + + for (var/I in src.vore_organs) + var/datum/belly/B = vore_organs[I] + message += B.get_examine_msg() + + return message \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 4dbadb9cc9..3fd7d721f7 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -367,13 +367,13 @@ skipcatch = 1 //can't catch the now embedded item return ..() -/* Disabling this for now so it doesn't get in the way. -Cactus + /mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) - if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling)) - devour_mob(pulling) + if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && iscarbon(pulling)) + vore_attack(user, pulling) else ..() -*/ + /mob/living/carbon/human/grippedby(mob/living/user) if(w_uniform) w_uniform.add_fingerprint(user) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 7425b5b3ae..46196c0bbe 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -46,6 +46,8 @@ if(loc) environment = loc.return_air() + if(ismob(loc)) return + var/datum/gas_mixture/breath if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube"))) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index b58c711fb2..e9e2f54702 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -211,12 +211,12 @@ /mob/living/acid_act(acidpwr, toxpwr, acid_volume) take_organ_damage(min(10*toxpwr, acid_volume * toxpwr)) -/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0) -// if(user == src) -// var/mob/living/target -// if(pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling)) -// target = pulling -// user.vore_initiate(target,user) +/mob/living/proc/grabbedby(mob/living/carbon/user, mob/living/target, supress_message = 0) + +// if(grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling) && user.zone_selected == "mouth") +// src.vore_attack(src, devour_time = 100) //It would be better to define it on this level instead of human_defense.dm, but you'd probably need to do more work down the line. ex: xeno devour code +// return + if(anchored) return 0 if(!user.pulling || user.pulling != src) diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm new file mode 100644 index 0000000000..ec0d15bcd7 --- /dev/null +++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm @@ -0,0 +1,3 @@ +/mob/living/simple_animal + // List of targets excluded (for now) from being eaten by this mob. + var/list/prey_exclusions = list() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index da6541445e..ad0bcfc9ac 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -22,6 +22,7 @@ var/next_mob_id = 0 else living_mob_list += src prepare_huds() + hook_vr("mob_new",list(src)) ..() /atom/proc/prepare_huds() diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm new file mode 100644 index 0000000000..2cb4634758 --- /dev/null +++ b/code/modules/mob/say_vr.dm @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////// +////////////////////SUBTLE COMMAND//////////////////// +////////////////////////////////////////////////////// +/mob + var/use_me = 1 + +/mob/verb/me_verb_subtle(message as text) //This would normally go in say.dm + set name = "Subtle" + set category = "IC" + set desc = "Emote to nearby people (and your pred/prey)" + + if(say_disabled) //This is here to try to identify lag problems + usr << "Speech is currently admin-disabled." + return + + message = sanitize(message) + + if(use_me) + usr.emote_vr("me",4,message) + else + usr.emote_vr(message) + + + +/mob/proc/custom_emote_vr(var/m_type=1,var/message = null) //This would normally go in emote.dm + if(stat || !use_me && usr == src) + src << "You are unable to emote." + return + + var/muzzled = is_muzzled() + if(m_type == 2 && muzzled) return + + var/input + if(!message) + input = sanitize(input(src,"Choose an emote to display.") as text|null) + else + input = message + + if(input) + message = "[src] [input]" + else + return + + + if (message) + log_emote("[name]/[key] : [message]") + + for(var/mob/M in player_list) + if (!M.client) + continue //skip monkeys and leavers + if (istype(M, /mob/new_player)) + continue + if(findtext(message," snores.")) //Because we have so many sleeping people. + break + if(M.stat == DEAD && !(M in viewers(src,null))) + M.show_message(message, m_type) + var/list/subtle = hearers(1,src) + for(var/I in subtle) + /*if(isobj(I)) //micros in hand + spawn(0) + if(I) //It's possible that it could be deleted in the meantime. + var/obj/O = I + I.show_message(src, message, 2) */ + if(ismob(I)) + var/mob/M = I + M.show_message(message, 2) + + + +/mob/proc/emote_vr(var/act, var/type, var/message) //This would normally go in say.dm + if(act == "me") + return custom_emote_vr(type, message) \ No newline at end of file diff --git a/config/admins.txt b/config/admins.txt index c0a463d0df..ead4baf7bf 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -8,4 +8,4 @@ # NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. # ############################################################################################### -JayEh = Host \ No newline at end of file +Jayehh = Host diff --git a/sound/vore/StomachTransfer.ogg b/sound/vore/StomachTransfer.ogg new file mode 100644 index 0000000000..c81da56f50 Binary files /dev/null and b/sound/vore/StomachTransfer.ogg differ diff --git a/sound/vore/death1.ogg b/sound/vore/death1.ogg new file mode 100644 index 0000000000..34f4e189f5 Binary files /dev/null and b/sound/vore/death1.ogg differ diff --git a/sound/vore/death10.ogg b/sound/vore/death10.ogg new file mode 100644 index 0000000000..92ce0fd9bd Binary files /dev/null and b/sound/vore/death10.ogg differ diff --git a/sound/vore/death2.ogg b/sound/vore/death2.ogg new file mode 100644 index 0000000000..2476b0f08c Binary files /dev/null and b/sound/vore/death2.ogg differ diff --git a/sound/vore/death3.ogg b/sound/vore/death3.ogg new file mode 100644 index 0000000000..d8a666067d Binary files /dev/null and b/sound/vore/death3.ogg differ diff --git a/sound/vore/death4.ogg b/sound/vore/death4.ogg new file mode 100644 index 0000000000..4fce54da79 Binary files /dev/null and b/sound/vore/death4.ogg differ diff --git a/sound/vore/death5.ogg b/sound/vore/death5.ogg new file mode 100644 index 0000000000..371cf17155 Binary files /dev/null and b/sound/vore/death5.ogg differ diff --git a/sound/vore/death6.ogg b/sound/vore/death6.ogg new file mode 100644 index 0000000000..78fc1b0637 Binary files /dev/null and b/sound/vore/death6.ogg differ diff --git a/sound/vore/death7.ogg b/sound/vore/death7.ogg new file mode 100644 index 0000000000..419a5bedd5 Binary files /dev/null and b/sound/vore/death7.ogg differ diff --git a/sound/vore/death8.ogg b/sound/vore/death8.ogg new file mode 100644 index 0000000000..b15ab6a7d2 Binary files /dev/null and b/sound/vore/death8.ogg differ diff --git a/sound/vore/death9.ogg b/sound/vore/death9.ogg new file mode 100644 index 0000000000..3709541d60 Binary files /dev/null and b/sound/vore/death9.ogg differ diff --git a/sound/vore/digest1.ogg b/sound/vore/digest1.ogg new file mode 100644 index 0000000000..058ca78f7e Binary files /dev/null and b/sound/vore/digest1.ogg differ diff --git a/sound/vore/digest10.ogg b/sound/vore/digest10.ogg new file mode 100644 index 0000000000..5db775ae29 Binary files /dev/null and b/sound/vore/digest10.ogg differ diff --git a/sound/vore/digest11.ogg b/sound/vore/digest11.ogg new file mode 100644 index 0000000000..d81ac72dea Binary files /dev/null and b/sound/vore/digest11.ogg differ diff --git a/sound/vore/digest12.ogg b/sound/vore/digest12.ogg new file mode 100644 index 0000000000..6b44127cd8 Binary files /dev/null and b/sound/vore/digest12.ogg differ diff --git a/sound/vore/digest2.ogg b/sound/vore/digest2.ogg new file mode 100644 index 0000000000..0e8bef1db8 Binary files /dev/null and b/sound/vore/digest2.ogg differ diff --git a/sound/vore/digest3.ogg b/sound/vore/digest3.ogg new file mode 100644 index 0000000000..2077f31399 Binary files /dev/null and b/sound/vore/digest3.ogg differ diff --git a/sound/vore/digest4.ogg b/sound/vore/digest4.ogg new file mode 100644 index 0000000000..27a786bc40 Binary files /dev/null and b/sound/vore/digest4.ogg differ diff --git a/sound/vore/digest5.ogg b/sound/vore/digest5.ogg new file mode 100644 index 0000000000..849c1335be Binary files /dev/null and b/sound/vore/digest5.ogg differ diff --git a/sound/vore/digest6.ogg b/sound/vore/digest6.ogg new file mode 100644 index 0000000000..5f0cc86eb1 Binary files /dev/null and b/sound/vore/digest6.ogg differ diff --git a/sound/vore/digest7.ogg b/sound/vore/digest7.ogg new file mode 100644 index 0000000000..f224cc3fa3 Binary files /dev/null and b/sound/vore/digest7.ogg differ diff --git a/sound/vore/digest8.ogg b/sound/vore/digest8.ogg new file mode 100644 index 0000000000..04b742bd49 Binary files /dev/null and b/sound/vore/digest8.ogg differ diff --git a/sound/vore/digest9.ogg b/sound/vore/digest9.ogg new file mode 100644 index 0000000000..866c95b874 Binary files /dev/null and b/sound/vore/digest9.ogg differ diff --git a/sound/vore/gulp.ogg b/sound/vore/gulp.ogg new file mode 100644 index 0000000000..b463e7fb18 Binary files /dev/null and b/sound/vore/gulp.ogg differ diff --git a/sound/vore/insert.ogg b/sound/vore/insert.ogg new file mode 100644 index 0000000000..0574733d4d Binary files /dev/null and b/sound/vore/insert.ogg differ diff --git a/sound/vore/insertion1.ogg b/sound/vore/insertion1.ogg new file mode 100644 index 0000000000..a026591f07 Binary files /dev/null and b/sound/vore/insertion1.ogg differ diff --git a/sound/vore/insertion2.ogg b/sound/vore/insertion2.ogg new file mode 100644 index 0000000000..b682e3aaf8 Binary files /dev/null and b/sound/vore/insertion2.ogg differ diff --git a/sound/vore/insertion3.ogg b/sound/vore/insertion3.ogg new file mode 100644 index 0000000000..7dabf3f077 Binary files /dev/null and b/sound/vore/insertion3.ogg differ diff --git a/sound/vore/schlorp.ogg b/sound/vore/schlorp.ogg new file mode 100644 index 0000000000..c9cd5a3413 Binary files /dev/null and b/sound/vore/schlorp.ogg differ diff --git a/sound/vore/squish1.ogg b/sound/vore/squish1.ogg new file mode 100644 index 0000000000..8a87758048 Binary files /dev/null and b/sound/vore/squish1.ogg differ diff --git a/sound/vore/squish2.ogg b/sound/vore/squish2.ogg new file mode 100644 index 0000000000..c8f96fc6e2 Binary files /dev/null and b/sound/vore/squish2.ogg differ diff --git a/sound/vore/squish3.ogg b/sound/vore/squish3.ogg new file mode 100644 index 0000000000..60e364c80a Binary files /dev/null and b/sound/vore/squish3.ogg differ diff --git a/sound/vore/squish4.ogg b/sound/vore/squish4.ogg new file mode 100644 index 0000000000..e9bd8e7bf5 Binary files /dev/null and b/sound/vore/squish4.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 3ca0e84a15..e22b7368ee 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -70,8 +70,10 @@ #include "code\__HELPERS\radio.dm" #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\text.dm" +#include "code\__HELPERS\text_vr.dm" #include "code\__HELPERS\time.dm" #include "code\__HELPERS\type2type.dm" +#include "code\__HELPERS\type2type_vr.dm" #include "code\__HELPERS\unsorted.dm" #include "code\__HELPERS\sorts\__main.dm" #include "code\__HELPERS\sorts\InsertSort.dm" @@ -128,10 +130,21 @@ #include "code\_onclick\hud\swarmer.dm" #include "code\citadel\_helpers.dm" #include "code\citadel\organs.dm" +#include "code\citadel\vore\hook-defs_vr.dm" +#include "code\citadel\vore\trycatch_vr.dm" +#include "code\citadel\vore\eating\belly_vr.dm" +#include "code\citadel\vore\eating\bellymodes_vr.dm" +#include "code\citadel\vore\eating\living_vr.dm" +#include "code\citadel\vore\eating\simple_animal_vr.dm" +#include "code\citadel\vore\eating\vore_vr.dm" +#include "code\citadel\vore\eating\vorehooks_vr.dm" +#include "code\citadel\vore\eating\vorepanel_vr.dm" +#include "code\citadel\vore\resizing\resize_vr.dm" #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" +#include "code\controllers\hooks.dm" #include "code\controllers\master.dm" #include "code\controllers\subsystem.dm" #include "code\controllers\subsystem\air.dm" @@ -995,6 +1008,7 @@ #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" #include "code\modules\client\preferences_toggles.dm" +#include "code\modules\client\preferences_vr.dm" #include "code\modules\clothing\chameleon.dm" #include "code\modules\clothing\clothing.dm" #include "code\modules\clothing\glasses\engine_goggles.dm" @@ -1273,6 +1287,7 @@ #include "code\modules\mob\mob_movement.dm" #include "code\modules\mob\mob_transformation_simple.dm" #include "code\modules\mob\say.dm" +#include "code\modules\mob\say_vr.dm" #include "code\modules\mob\status_procs.dm" #include "code\modules\mob\transform_procs.dm" #include "code\modules\mob\update_icons.dm" @@ -1351,6 +1366,7 @@ #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\emote.dm" #include "code\modules\mob\living\carbon\human\examine.dm" +#include "code\modules\mob\living\carbon\human\examine_vr.dm" #include "code\modules\mob\living\carbon\human\human.dm" #include "code\modules\mob\living\carbon\human\human_attackalien.dm" #include "code\modules\mob\living\carbon\human\human_attackhand.dm"