mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-28 10:31:59 +00:00
* - I rearranged X_defense.dm mob files, more damage_procs.dm.Here's what's inside: * X_defense.dm: is for the procs of attacks onto the mob, all the XXX_act() proc (things happening to the mob), as well as protection check and get procs (armor, ear prot, projectile dismemberment) * damage_procs.dm: actual damage procs like adjustBruteLoss() getfireloss, any proc that handles damaging. - some bugfixes with gibspawner effects. - monkey's bodyparts can be dismembered and are used to create its icon. - brains are no longer carbons. - all carbon have bodyparts that can be dropped when the mob is gibbed. - adminspawned bodyparts now have a default icon. - robotic parts are now a child of bodyparts. - health analyzer on alien/monkey shows damage on each limb - added admin option to add/remove bodyparts for all carbon (instead of just remove on humans) - Fixes keycheck message spam for janicart and all when trying to move. - Fixes bug with buckling to a scooter while limbless. - removed arg "hit_zone" in proj's on_hit() because we can already use the def_zone var (where hit_zone got its value) - Fixes mob not getting any damage when hit by a projectile on their missing limb, despite a hit message shown). carbon/apply_damage() now when we specify a def_zone and the corresponding BP is missing we default to the chest instead of stopping the proc. Consistently with how human/attacked_by() default to its attack to chest if missing limb. - Fixes mini uzi icon when empty and no mag (typo). - I renamed and changed a bit check_eye_prot and ear prot - renamed flash_eyes to flash_act() - I made a soundbang_act() similar to flash_act but for loud bangs. - added a gib and dust animation to larva. - husked monkeys - no damage overlay for husk or skeleton. - damage overlay for robotic limb now. - no damage overlay when organic bodypart husked. - one handed human with a bloody hand still get a bloody single hand overlay. - fix admin heal being unable to heal robotic bodyparts. - slightly touched robotic bodypart sprites (head one pixel too high) - Fixes 18532 "beheaded husk has hair". - Fixes 18584 "Ling stasis appearance bug" - no more eyes or lipstick on husks. - can remove flashes/wires/cells from robot chest and head with crowbar. - Fixes not being able to surgically amputate robotic arm/leg. * More merge conflict fixes and adding the new files I forgot to add. * of course I forgot birdstation * More typos and stuff I forgot to undo. * Fixing a typo in examine.dm Removing an unnecessary check. Making admin heal regenerate limbs on all carbons. Monkey-human transformation now transfer missing limbs info and presence of a cavity implant. NODISMEMBER species can still lack a limb if the mob lacked a limb and changed into that new species. Changeling Regenerate ability now also regenerate limbs when in monkey form. (and remove some cryptic useless code) * Fixing more conflicts with remie's multihands PR. * Fixes runtime with hud when calling build_hand_slots(). Fixes lightgeist healing not working. Fixes null.handle_fall() runtimes with pirate mobs. Fixes typo in has_left_hadn() and has_right_hand(). * Derp, forgot to remove debug message.
393 lines
13 KiB
Plaintext
393 lines
13 KiB
Plaintext
|
|
/////////////////////////// DNA DATUM
|
|
/datum/dna
|
|
var/unique_enzymes
|
|
var/struc_enzymes
|
|
var/uni_identity
|
|
var/blood_type
|
|
var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man)
|
|
var/list/features = list("FFF") //first value is mutant color
|
|
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
|
|
var/list/mutations = list() //All mutations are from now on here
|
|
var/list/temporary_mutations = list() //Timers for temporary mutations
|
|
var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
|
|
var/mob/living/holder
|
|
|
|
/datum/dna/New(mob/living/new_holder)
|
|
if(new_holder)
|
|
holder = new_holder
|
|
|
|
/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
|
|
if(!istype(destination))
|
|
return
|
|
destination.dna.unique_enzymes = unique_enzymes
|
|
destination.dna.uni_identity = uni_identity
|
|
destination.dna.blood_type = blood_type
|
|
destination.set_species(species.type, icon_update=0)
|
|
destination.dna.features = features.Copy()
|
|
destination.dna.real_name = real_name
|
|
destination.dna.temporary_mutations = temporary_mutations.Copy()
|
|
if(transfer_SE)
|
|
destination.dna.struc_enzymes = struc_enzymes
|
|
|
|
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
|
new_dna.unique_enzymes = unique_enzymes
|
|
new_dna.struc_enzymes = struc_enzymes
|
|
new_dna.uni_identity = uni_identity
|
|
new_dna.blood_type = blood_type
|
|
new_dna.features = features.Copy()
|
|
new_dna.species = new species.type
|
|
new_dna.real_name = real_name
|
|
new_dna.mutations = mutations.Copy()
|
|
|
|
/datum/dna/proc/add_mutation(mutation_name)
|
|
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
|
HM.on_acquiring(holder)
|
|
|
|
/datum/dna/proc/remove_mutation(mutation_name)
|
|
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
|
HM.on_losing(holder)
|
|
|
|
/datum/dna/proc/check_mutation(mutation_name)
|
|
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
|
return mutations.Find(HM)
|
|
|
|
/datum/dna/proc/remove_all_mutations()
|
|
remove_mutation_group(mutations)
|
|
|
|
/datum/dna/proc/remove_mutation_group(list/group)
|
|
if(!group)
|
|
return
|
|
for(var/datum/mutation/human/HM in group)
|
|
HM.force_lose(holder)
|
|
|
|
/datum/dna/proc/generate_uni_identity()
|
|
. = ""
|
|
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
|
|
|
|
L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
|
|
if(ishuman(holder))
|
|
var/mob/living/carbon/human/H = holder
|
|
if(!hair_styles_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list)
|
|
L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len)
|
|
L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color)
|
|
if(!facial_hair_styles_list.len)
|
|
init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, facial_hair_styles_list, facial_hair_styles_male_list, facial_hair_styles_female_list)
|
|
L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len)
|
|
L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
|
|
L[DNA_SKIN_TONE_BLOCK] = construct_block(skin_tones.Find(H.skin_tone), skin_tones.len)
|
|
L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
|
|
|
|
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
|
if(L[i])
|
|
. += L[i]
|
|
else
|
|
. += random_string(DNA_BLOCK_SIZE,hex_characters)
|
|
return .
|
|
|
|
/datum/dna/proc/generate_struc_enzymes()
|
|
var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS)
|
|
var/result = ""
|
|
for(var/datum/mutation/human/A in good_mutations + bad_mutations + not_good_mutations)
|
|
if(A.name == RACEMUT && ismonkey(holder))
|
|
sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE)
|
|
mutations |= A
|
|
else
|
|
sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6"))
|
|
|
|
for(var/B in sorting)
|
|
result += B
|
|
return result
|
|
|
|
/datum/dna/proc/generate_unique_enzymes()
|
|
. = ""
|
|
if(istype(holder))
|
|
real_name = holder.real_name
|
|
. += md5(holder.real_name)
|
|
else
|
|
. += random_string(DNA_UNIQUE_ENZYMES_LEN, hex_characters)
|
|
return .
|
|
|
|
/datum/dna/proc/update_ui_block(blocknumber)
|
|
if(!blocknumber || !ishuman(holder))
|
|
return
|
|
var/mob/living/carbon/human/H = holder
|
|
switch(blocknumber)
|
|
if(DNA_HAIR_COLOR_BLOCK)
|
|
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color))
|
|
if(DNA_FACIAL_HAIR_COLOR_BLOCK)
|
|
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
|
|
if(DNA_SKIN_TONE_BLOCK)
|
|
setblock(uni_identity, blocknumber, construct_block(skin_tones.Find(H.skin_tone), skin_tones.len))
|
|
if(DNA_EYE_COLOR_BLOCK)
|
|
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
|
|
if(DNA_GENDER_BLOCK)
|
|
setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
|
|
if(DNA_FACIAL_HAIR_STYLE_BLOCK)
|
|
setblock(uni_identity, blocknumber, construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len))
|
|
if(DNA_HAIR_STYLE_BLOCK)
|
|
setblock(uni_identity, blocknumber, construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len))
|
|
|
|
/datum/dna/proc/mutations_say_mods(message)
|
|
if(message)
|
|
for(var/datum/mutation/human/M in mutations)
|
|
message = M.say_mod(message)
|
|
return message
|
|
|
|
/datum/dna/proc/mutations_get_spans()
|
|
var/list/spans = list()
|
|
for(var/datum/mutation/human/M in mutations)
|
|
spans |= M.get_spans()
|
|
return spans
|
|
|
|
/datum/dna/proc/species_get_spans()
|
|
var/list/spans = list()
|
|
if(species)
|
|
spans |= species.get_spans()
|
|
return spans
|
|
|
|
|
|
/datum/dna/proc/is_same_as(datum/dna/D)
|
|
if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
|
|
if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
|
|
return 1
|
|
return 0
|
|
|
|
//used to update dna UI, UE, and dna.real_name.
|
|
/datum/dna/proc/update_dna_identity()
|
|
uni_identity = generate_uni_identity()
|
|
unique_enzymes = generate_unique_enzymes()
|
|
|
|
/datum/dna/proc/initialize_dna(newblood_type)
|
|
if(newblood_type)
|
|
blood_type = newblood_type
|
|
unique_enzymes = generate_unique_enzymes()
|
|
uni_identity = generate_uni_identity()
|
|
struc_enzymes = generate_struc_enzymes()
|
|
features = random_features()
|
|
|
|
|
|
/datum/dna/stored //subtype used by brain mob's stored_dna
|
|
|
|
/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna.
|
|
return
|
|
|
|
/datum/dna/stored/remove_mutation(mutation_name)
|
|
return
|
|
|
|
/datum/dna/stored/check_mutation(mutation_name)
|
|
return
|
|
|
|
/datum/dna/stored/remove_all_mutations()
|
|
return
|
|
|
|
/datum/dna/stored/remove_mutation_group(list/group)
|
|
return
|
|
|
|
/////////////////////////// DNA MOB-PROCS //////////////////////
|
|
|
|
/mob/proc/set_species(datum/species/mrace, icon_update = 1)
|
|
return
|
|
|
|
/mob/living/brain/set_species(datum/species/mrace, icon_update = 1)
|
|
if(mrace)
|
|
if(ispath(mrace))
|
|
stored_dna.species = new mrace()
|
|
else
|
|
stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
|
|
|
|
|
|
/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
|
|
if(mrace && has_dna())
|
|
dna.species.on_species_loss(src)
|
|
var/old_species = dna.species
|
|
if(ispath(mrace))
|
|
dna.species = new mrace()
|
|
else
|
|
dna.species = mrace
|
|
dna.species.on_species_gain(src, old_species)
|
|
|
|
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
|
|
..()
|
|
if(icon_update)
|
|
update_body()
|
|
update_hair()
|
|
update_body_parts()
|
|
update_mutations_overlay()// no lizard with human hulk overlay please.
|
|
|
|
|
|
/mob/proc/has_dna()
|
|
return
|
|
|
|
/mob/living/carbon/has_dna()
|
|
return dna
|
|
|
|
|
|
/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures)
|
|
|
|
if(newfeatures)
|
|
dna.features = newfeatures
|
|
|
|
if(mrace)
|
|
set_species(mrace, icon_update=0)
|
|
|
|
if(newreal_name)
|
|
real_name = newreal_name
|
|
dna.generate_unique_enzymes()
|
|
|
|
if(newblood_type)
|
|
dna.blood_type = newblood_type
|
|
|
|
if(ui)
|
|
dna.uni_identity = ui
|
|
updateappearance(icon_update=0)
|
|
|
|
if(se)
|
|
dna.struc_enzymes = se
|
|
domutcheck()
|
|
|
|
if(mrace || newfeatures || ui)
|
|
update_body()
|
|
update_hair()
|
|
update_body_parts()
|
|
update_mutations_overlay()
|
|
|
|
|
|
/mob/living/carbon/proc/create_dna()
|
|
dna = new /datum/dna(src)
|
|
if(!dna.species)
|
|
var/rando_race = pick(config.roundstart_races)
|
|
dna.species = new rando_race()
|
|
|
|
//proc used to update the mob's appearance after its dna UI has been changed
|
|
/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
|
|
if(!has_dna())
|
|
return
|
|
gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
|
|
|
|
mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
|
|
..()
|
|
var/structure = dna.uni_identity
|
|
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
|
|
facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
|
|
skin_tone = skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), skin_tones.len)]
|
|
eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
|
|
facial_hair_style = facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), facial_hair_styles_list.len)]
|
|
hair_style = hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), hair_styles_list.len)]
|
|
if(icon_update)
|
|
update_body()
|
|
update_hair()
|
|
if(mutcolor_update)
|
|
update_body_parts()
|
|
if(mutations_overlay_update)
|
|
update_mutations_overlay()
|
|
|
|
|
|
/mob/proc/domutcheck()
|
|
return
|
|
|
|
/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
|
|
if(!has_dna())
|
|
return
|
|
|
|
for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations)
|
|
if(ismob(A.check_block(src, force_powers)))
|
|
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
|
|
|
|
update_mutations_overlay()
|
|
|
|
|
|
|
|
/////////////////////////// DNA HELPER-PROCS //////////////////////////////
|
|
/proc/getleftblocks(input,blocknumber,blocksize)
|
|
if(blocknumber > 1)
|
|
return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
|
|
|
|
/proc/getrightblocks(input,blocknumber,blocksize)
|
|
if(blocknumber < (length(input)/blocksize))
|
|
return copytext(input,blocksize*blocknumber+1,length(input)+1)
|
|
|
|
/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE)
|
|
return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
|
|
|
|
/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE)
|
|
if(!istring || !blocknumber || !replacement || !blocksize)
|
|
return 0
|
|
return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
|
|
|
|
/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
|
|
if(!has_dna())
|
|
return
|
|
var/datum/mutation/human/num = pick(candidates)
|
|
. = num.force_give(src)
|
|
|
|
/mob/living/carbon/proc/randmutb()
|
|
if(!has_dna())
|
|
return
|
|
var/datum/mutation/human/HM = pick((bad_mutations | not_good_mutations) - mutations_list[RACEMUT])
|
|
. = HM.force_give(src)
|
|
|
|
/mob/living/carbon/proc/randmutg()
|
|
if(!has_dna())
|
|
return
|
|
var/datum/mutation/human/HM = pick(good_mutations)
|
|
. = HM.force_give(src)
|
|
|
|
/mob/living/carbon/proc/randmutvg()
|
|
if(!has_dna())
|
|
return
|
|
var/datum/mutation/human/HM = pick((good_mutations) - mutations_list[HULK] - mutations_list[DWARFISM])
|
|
. = HM.force_give(src)
|
|
|
|
/mob/living/carbon/proc/randmuti()
|
|
if(!has_dna())
|
|
return
|
|
var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
|
|
var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters))
|
|
dna.uni_identity = newdna
|
|
updateappearance(mutations_overlay_update=1)
|
|
|
|
/mob/living/carbon/proc/clean_dna()
|
|
if(!has_dna())
|
|
return
|
|
dna.remove_all_mutations()
|
|
|
|
/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2)
|
|
clean_dna()
|
|
randmut(candidates, difficulty)
|
|
|
|
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
|
|
if(!M.has_dna())
|
|
return 0
|
|
if(se)
|
|
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
|
|
if(prob(probability))
|
|
M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, hex_characters))
|
|
M.domutcheck()
|
|
if(ui)
|
|
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
|
if(prob(probability))
|
|
M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, hex_characters))
|
|
M.updateappearance(mutations_overlay_update=1)
|
|
return 1
|
|
|
|
//value in range 1 to values. values must be greater than 0
|
|
//all arguments assumed to be positive integers
|
|
/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE)
|
|
var/width = round((16**blocksize)/values)
|
|
if(value < 1)
|
|
value = 1
|
|
value = (value * width) - rand(1,width)
|
|
return num2hex(value, blocksize)
|
|
|
|
//value is hex
|
|
/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE)
|
|
var/width = round((16**blocksize)/values)
|
|
value = round(hex2num(value) / width) + 1
|
|
if(value > values)
|
|
value = values
|
|
return value
|
|
|
|
/////////////////////////// DNA HELPER-PROCS
|