Merge branch 'master' into protRig

This commit is contained in:
Kashargul
2024-11-27 23:58:52 +01:00
committed by GitHub
281 changed files with 3627 additions and 3318 deletions
+1 -1
View File
@@ -223,7 +223,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
announce_ghost_joinleave(ghostize(1))
else
var/response
if(src.client && src.client.holder)
if(check_rights(R_ADMIN|R_SERVER|R_MOD,FALSE,src)) //No need to sanity check for client and holder here as that is part of check_rights
response = tgui_alert(src, "You have the ability to Admin-Ghost. The regular Ghost verb will announce your presence to dead chat. Both variants will allow you to return to your body using 'aghost'.\n\nWhat do you wish to do?", "Are you sure you want to ghost?", list("Admin Ghost", "Ghost", "Stay in body"))
if(response == "Admin Ghost")
if(!src.client)
+3 -1
View File
@@ -3,6 +3,7 @@
/mob/living
var/meat_amount = 0 // How much meat to drop from this mob when butchered
var/obj/meat_type // The meat object to drop
var/name_the_meat = TRUE
var/gib_on_butchery = FALSE
var/butchery_drops_organs = TRUE // Do we spawn and/or drop organs when butchered?
@@ -17,7 +18,8 @@
being_butchered = TRUE
while(meat_amount > 0 && do_after(user, 0.5 SECONDS * (mob_size / 10), src))
var/obj/item/meat = new meat_type(get_turf(src))
meat.name = "[src.name] [meat.name]"
if(name_the_meat)
meat.name = "[src.name] [meat.name]"
new /obj/effect/decal/cleanable/blood/splatter(get_turf(src))
meat_amount--
being_butchered = FALSE
+1 -1
View File
@@ -2,7 +2,7 @@
//Start of a breath chain, calls breathe()
/mob/living/carbon/handle_breathing()
if(air_master.current_cycle%4==2 || failed_last_breath || (health < CONFIG_GET(number/health_threshold_crit))) //First, resolve location and get a breath
if(SSair.current_cycle%4==2 || failed_last_breath || (health < CONFIG_GET(number/health_threshold_crit))) //First, resolve location and get a breath
breathe()
/mob/living/carbon/proc/breathe()
@@ -22,7 +22,7 @@
var/to_wear_r_radio = null
var/to_wear_uniform = /obj/item/clothing/under/color/grey
var/to_wear_suit = /obj/item/clothing/suit/armor/material/makeshift/glass
var/to_wear_gloves = /obj/item/clothing/gloves/ring/material/platinum
var/to_wear_gloves = /obj/item/clothing/accessory/ring/material/platinum
var/to_wear_shoes = /obj/item/clothing/shoes/galoshes
var/to_wear_belt = /obj/item/storage/belt/utility/full
var/to_wear_l_pocket = /obj/item/soap
@@ -9,6 +9,8 @@ var/list/_human_default_emotes = list(
/decl/emote/audible/synth/dwoop,
/decl/emote/audible/synth/boop,
/decl/emote/audible/synth/robochirp,
/decl/emote/audible/synth/ding,
/decl/emote/audible/synth/microwave,
/decl/emote/visible/nod,
/decl/emote/visible/shake,
/decl/emote/visible/shiver,
@@ -107,12 +107,10 @@
if(w_uniform && !(skip_gear & EXAMINE_SKIPJUMPSUIT) && w_uniform.show_examine)
//Ties
var/tie_msg
var/tie_msg_warn
if(istype(w_uniform,/obj/item/clothing/under) && !(skip_gear & EXAMINE_SKIPTIE))
var/obj/item/clothing/under/U = w_uniform
if(LAZYLEN(U.accessories))
tie_msg += ". Attached to it is"
tie_msg_warn += "! Attached to it is"
var/list/accessory_descs = list()
if(skip_gear & EXAMINE_SKIPHOLSTER)
for(var/obj/item/clothing/accessory/A in U.accessories)
@@ -139,12 +137,10 @@
//suit/armour
if(wear_suit)
var/tie_msg
var/tie_msg_warn
if(istype(wear_suit,/obj/item/clothing/suit))
var/obj/item/clothing/suit/U = wear_suit
if(LAZYLEN(U.accessories))
tie_msg += ". Attached to it is"
tie_msg_warn += "! Attached to it is"
var/list/accessory_descs = list()
for(var/accessory in U.accessories)
accessory_descs += "<a href='?src=\ref[src];lookitem_desc_only=\ref[accessory]'>\a [accessory]</a>"
@@ -185,10 +181,21 @@
//gloves
if(gloves && !(skip_gear & EXAMINE_SKIPGLOVES) && gloves.show_examine)
var/gloves_acc_msg
if(istype(gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = gloves
if(LAZYLEN(G.accessories))
gloves_acc_msg += ". Attached to it is"
var/list/accessory_descs = list()
for(var/obj/item/clothing/accessory/A in G.accessories)
accessory_descs += "<a href='?src=\ref[src];lookitem_desc_only=\ref[A]'>\a [A]</a>"
gloves_acc_msg += " [lowertext(english_list(accessory_descs))]."
if(gloves.blood_DNA)
msg += span_warning("[T.He] [T.has] [icon2html(gloves,user.client)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='?src=\ref[src];lookitem_desc_only=\ref[gloves]'>[gloves.name]</a> on [T.his] hands!")
msg += span_warning("[T.He] [T.has] [icon2html(gloves,user.client)] [gloves.gender==PLURAL?"some":"a"] [(gloves.blood_color != "#030303") ? "blood" : "oil"]-stained <a href='?src=\ref[src];lookitem_desc_only=\ref[gloves]'>[gloves.name]</a> on [T.his] hands![gloves_acc_msg]")
else
msg += "[T.He] [T.has] [icon2html(gloves,user.client)] <a href='?src=\ref[src];lookitem_desc_only=\ref[gloves]'>\a [gloves]</a> on [T.his] hands."
msg += "[T.He] [T.has] [icon2html(gloves,user.client)] <a href='?src=\ref[src];lookitem_desc_only=\ref[gloves]'>\a [gloves]</a> on [T.his] hands.[gloves_acc_msg]"
else if(blood_DNA && !(skip_body & EXAMINE_SKIPHANDS))
msg += span_warning("[T.He] [T.has] [(hand_blood_color != SYNTH_BLOOD_COLOUR) ? "blood" : "oil"]-stained hands!")
@@ -272,8 +272,12 @@
var/obj/item/clothing/gloves/G = H.gloves
real_damage += G.punch_force
hit_dam_type = G.punch_damtype
if(H.pulling_punches && !attack.sharp && !attack.edge) //SO IT IS DECREED: PULLING PUNCHES WILL PREVENT THE ACTUAL DAMAGE FROM RINGS AND KNUCKLES, BUT NOT THE ADDED PAIN, BUT YOU CAN'T "PULL" A KNIFE
hit_dam_type = AGONY
else if(istype(H.gloves, /obj/item/clothing/accessory))
var/obj/item/clothing/accessory/G = H.gloves
real_damage += G.punch_force
hit_dam_type = G.punch_damtype
if(H.pulling_punches && !attack.sharp && !attack.edge) //SO IT IS DECREED: PULLING PUNCHES WILL PREVENT THE ACTUAL DAMAGE FROM RINGS AND KNUCKLES, BUT NOT THE ADDED PAIN, BUT YOU CAN'T "PULL" A KNIFE
hit_dam_type = AGONY
real_damage *= damage_multiplier
rand_damage *= damage_multiplier
if(HULK in H.mutations)
@@ -82,10 +82,6 @@
var/obj/item/l_store = null
var/obj/item/s_store = null
var/used_skillpoints = 0
var/skill_specialization = null
var/list/skills = list()
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
var/special_voice = "" // For changing our voice. Used by a symptom.
+1 -1
View File
@@ -1780,7 +1780,7 @@
stomach_contents.Remove(M)
qdel(M)
continue
if(air_master.current_cycle%3==1)
if(SSair.current_cycle%3==1)
if(!(M.status_flags & GODMODE))
M.adjustBruteLoss(5)
adjust_nutrition(10)
@@ -212,6 +212,9 @@
var/can_space_freemove = FALSE // Can we freely move in space?
var/can_zero_g_move = FALSE // What about just in zero-g non-space?
var/swim_mult = 1 //multiplier to our z-movement rate for swimming
var/climb_mult = 1 //multiplier to our z-movement rate for lattices/catwalks
var/item_slowdown_mod = 1 // How affected by item slowdown the species is.
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
@@ -25,11 +25,9 @@
edge = TRUE
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/skill = user.skills["combat"]
var/obj/item/organ/external/affecting = target.get_organ(zone)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
if(!skill) skill = 1
attack_damage = CLAMP(attack_damage, 1, 5)
if(target == user)
@@ -242,6 +242,8 @@
reagent_tag = IS_TAJARA
allergens = ALLERGEN_STIMULANT
climb_mult = 0.75
move_trail = /obj/effect/decal/cleanable/blood/tracks/paw
heat_discomfort_level = 292
@@ -384,6 +384,8 @@
silk_reserve = 500
silk_max_reserve = 1000
climb_mult = 0.75
/datum/species/spider/handle_environment_special(var/mob/living/carbon/human/H)
if(H.stat == DEAD) // If they're dead they won't need anything.
return
@@ -110,6 +110,7 @@
water_breather = TRUE
water_movement = -4 //Negates shallow. Halves deep.
swim_mult = 0.5
flesh_color = "#AFA59E"
base_color = "#777777"
@@ -188,7 +188,9 @@
/datum/trait/negative/bad_swimmer
name = "Bad Swimmer"
desc = "You can't swim very well, all water slows you down a lot and you drown in deep water."
desc = "You can't swim very well, all water slows you down a lot and you drown in deep water. You also swim up and down 25% slower."
cost = -1
custom_only = FALSE
var_changes = list("bad_swimmer" = 1, "water_movement" = 4)
var_changes = list("bad_swimmer" = 1, "water_movement" = 4, "swim_mult" = 1.25)
varchange_type = TRAIT_VARCHANGE_LESS_BETTER
excludes = list(/datum/trait/positive/good_swimmer)
@@ -121,6 +121,7 @@
name = "Winged Flight"
desc = "Allows you to fly by using your wings. Don't forget to bring them!"
cost = 0
custom_only = FALSE
has_preferences = list("flight_vore" = list(TRAIT_PREF_TYPE_BOOLEAN, "Flight Vore enabled on spawn", TRAIT_VAREDIT_TARGET_MOB, FALSE))
/datum/trait/positive/winged_flight/apply(var/datum/species/S,var/mob/living/carbon/human/H)
@@ -241,12 +242,9 @@
cost = 1
var_changes = list("throwforce_absorb_threshold" = 10)
/datum/trait/positive/wall_climber
name = "Climber, Amateur"
desc = "You can climb certain walls without tools! This is likely a personal skill you developed."
desc = "You can climb certain walls without tools! This is likely a personal skill you developed. You can also climb lattices and ladders a little bit faster than everyone else."
tutorial = "You must approach a wall and right click it and select the \
'climb wall' verb to climb it. You suffer from a movement delay of 1.5 with this trait.\n \
Your total climb time is expected to be 17.5 seconds. Tools may reduce this. \n\n \
@@ -255,12 +253,12 @@
cost = 1
custom_only = FALSE
banned_species = list(SPECIES_TAJ, SPECIES_VASILISSAN) // They got unique climbing delay.
var_changes = list("can_climb" = TRUE)
var_changes = list("can_climb" = TRUE, "climb_mult" = 0.75)
excludes = list(/datum/trait/positive/wall_climber_pro, /datum/trait/positive/wall_climber_natural)
/datum/trait/positive/wall_climber_natural
name = "Climber, Natural"
desc = "You can climb certain walls without tools! This is likely due to the unique anatomy of your species. CUSTOM AND XENOCHIM ONLY"
desc = "You can climb certain walls without tools! This is likely due to the unique anatomy of your species. You can climb lattices and ladders slightly faster than everyone else. CUSTOM AND XENOCHIM ONLY"
tutorial = "You must approach a wall and right click it and select the \
'climb wall' verb to climb it. You suffer from a movement delay of 1.5 with this trait.\n \
Your total climb time is expected to be 17.5 seconds. Tools may reduce this. \n\n \
@@ -268,13 +266,13 @@
a climbable wall. To climbe like so, use the verb 'Climb Down Wall' in IC tab!"
cost = 0
custom_only = FALSE
var_changes = list("can_climb" = TRUE)
var_changes = list("can_climb" = TRUE, "climb_mult" = 0.75)
allowed_species = list(SPECIES_XENOCHIMERA, SPECIES_CUSTOM) //So that we avoid needless bloat for xenochim
excludes = list(/datum/trait/positive/wall_climber_pro, /datum/trait/positive/wall_climber)
/datum/trait/positive/wall_climber_pro
name = "Climber, Professional"
desc = "You can climb certain walls without tools! You are a professional rock climber at this, letting you climb almost twice as fast!"
desc = "You can climb certain walls without tools! You are a professional rock climber at this, letting you climb almost twice as fast! You can also climb lattices and ladders a fair bit faster than everyone else!"
tutorial = "You must approach a wall and right click it and select the \
'climb wall' verb to climb it. Your movement delay is just 1.25 with this trait.\n \
Your climb time is expected to be 9 seconds. Tools may reduce this. \n\n \
@@ -282,7 +280,7 @@
a climbable wall. To climbe like so, use the verb 'Climb Down Wall' in IC tab!"
cost = 2
custom_only = FALSE
var_changes = list("climbing_delay" = 1.25)
var_changes = list("climbing_delay" = 1.25, "climb_mult" = 0.5)
varchange_type = TRAIT_VARCHANGE_LESS_BETTER
excludes = list(/datum/trait/positive/wall_climber,/datum/trait/positive/wall_climber_natural)
@@ -292,3 +290,14 @@
/datum/trait/positive/wall_climber_pro/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..()
S.can_climb = TRUE
/datum/trait/positive/good_swimmer
name = "Pro Swimmer"
desc = "You were top of your group in swimming class! This is of questionable usefulness on most planets, but hey, maybe you'll get to visit a nice beach world someday?"
tutorial = "You move faster in water, and can move up and down z-levels faster than other swimmers!"
cost = 1
custom_only = FALSE
var_changes = list("water_movement" = -2, "swim_mult" = 0.5)
varchange_type = TRAIT_VARCHANGE_LESS_BETTER
excludes = list(/datum/trait/negative/bad_swimmer)
banned_species = list(SPECIES_AKULA) // They already swim better than this
+1 -1
View File
@@ -149,7 +149,7 @@ var/list/channel_to_radio_key = new
if(client)
if(message)
client.handle_spam_prevention(MUTE_IC)
if((client.prefs.muted & MUTE_IC) || say_disabled)
if((client.prefs.muted & MUTE_IC))
to_chat(src, span_warning("You cannot speak in IC (Muted)."))
return
+2
View File
@@ -9,6 +9,8 @@ var/list/_silicon_default_emotes = list(
/decl/emote/audible/synth/dwoop,
/decl/emote/audible/synth/boop,
/decl/emote/audible/synth/robochirp,
/decl/emote/audible/synth/ding,
/decl/emote/audible/synth/microwave,
/decl/emote/audible/synth/security,
/decl/emote/audible/synth/security/halt
)
@@ -579,7 +579,7 @@
'sound/vore/digest12.ogg')
playsound(src, churnsound, vol = 100, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/preference/toggle/digestion_noises)
//If the timing is right, and there are items to be touched
if(air_master.current_cycle%3==1 && length(touchable_items))
if(SSair.current_cycle%3==1 && length(touchable_items))
//Burn all the mobs or add them to the exclusion list
for(var/mob/living/T in (touchable_items))
@@ -203,9 +203,6 @@ var/list/mob_hat_cache = list()
can_pick_shell = FALSE
update_icon()
/mob/living/silicon/robot/drone/choose_icon()
return
/mob/living/silicon/robot/drone/pick_module()
return
@@ -25,6 +25,8 @@ var/list/_robot_default_emotes = list(
/decl/emote/audible/synth/dwoop,
/decl/emote/audible/synth/boop,
/decl/emote/audible/synth/robochirp,
/decl/emote/audible/synth/ding,
/decl/emote/audible/synth/microwave,
/decl/emote/audible/synth/security,
/decl/emote/audible/synth/security/halt,
//VOREStation Add
@@ -11,11 +11,6 @@
repick_laws()
// Forces synths to select an icon relevant to their module
if(!icon_selected)
icon_selection_tries = SSrobot_sprites.get_module_sprites_len(modtype, src) + 1
choose_icon(icon_selection_tries)
if(sprite_datum && module)
sprite_datum.do_equipment_glamour(module)
pick_module()
plane_holder.set_vis(VIS_AUGMENTED, TRUE)
+23 -104
View File
@@ -31,8 +31,7 @@
//Icon stuff
var/datum/robot_sprite/sprite_datum // Sprite datum, holding all our sprite data
var/icon_selected = 1 // If icon selection has been completed yet
var/icon_selection_tries = 0 // Remaining attempts to select icon before a selection is forced
var/icon_selected = FALSE // If icon selection has been completed yet
var/list/sprite_extra_customization = list()
var/rest_style = "Default"
var/notransform
@@ -47,6 +46,9 @@
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
var/ui_theme
var/selecting_module = FALSE
//3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/module_active = null
@@ -336,46 +338,17 @@
return module_sprites
*/
/mob/living/silicon/robot/proc/pick_module()
if(icon_selected)
return
if(module)
return
var/list/modules = list()
//VOREStatation Edit Start: shell restrictions
if(shell)
if(restrict_modules_to.len > 0)
modules.Add(restrict_modules_to)
else
modules.Add(shell_module_types)
else
if(restrict_modules_to.len > 0)
modules.Add(restrict_modules_to)
else
modules.Add(robot_module_types)
if(crisis || security_level == SEC_LEVEL_RED || crisis_override)
to_chat(src, span_red("Crisis mode active. Combat module available."))
modules |= emergency_module_types
for(var/module_name in whitelisted_module_types)
if(is_borg_whitelisted(src, module_name))
modules |= module_name
//VOREStatation Edit End: shell restrictions
modtype = tgui_input_list(usr, "Please, select a module!", "Robot module", modules)
if(module)
return
if(!(modtype in robot_modules))
return
if(!is_borg_whitelisted(src, modtype))
return
var/module_type = robot_modules[modtype]
transform_with_anim() //VOREStation edit: sprite animation
new module_type(src)
hands.icon_state = get_hud_module_icon()
feedback_inc("cyborg_[lowertext(modtype)]",1)
updatename()
hud_used.update_robot_modules_display()
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
robotact?.update_static_data_for_all_viewers()
var/list/module_sprites = SSrobot_sprites.get_module_sprites(module, src)
if(module_sprites.len == 1 || !client)
sprite_datum = module_sprites[1]
sprite_datum.do_equipment_glamour(module)
return
if(!selecting_module)
var/datum/tgui_module/robot_ui_module/ui = new(src)
ui.tgui_interact(src)
/mob/living/silicon/robot/proc/update_braintype()
if(istype(mmi, /obj/item/mmi/digital/posibrain))
@@ -436,15 +409,12 @@
to_chat(usr, "You can't pick another custom name. [isshell(src) ? "" : "Go ask for a name change."]")
return 0
spawn(0)
var/newname
newname = sanitizeSafe(tgui_input_text(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","", MAX_NAME_LEN), MAX_NAME_LEN)
if (newname)
custom_name = newname
sprite_name = newname
var/newname = sanitizeSafe(tgui_input_text(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","", MAX_NAME_LEN), MAX_NAME_LEN)
if (newname)
custom_name = newname
sprite_name = newname
updatename()
update_icon()
updatename()
/mob/living/silicon/robot/verb/extra_customization()
set name = "Customize Appearance"
@@ -744,6 +714,8 @@
to_chat(usr, span_filter_notice("You must access the borgs internals!"))
else if(!src.module && U.require_module)
to_chat(usr, span_filter_notice("The borg must choose a module before it can be upgraded!"))
else if(user == src && istype(W,/obj/item/borg/upgrade/utility/reset))
to_chat(usr, span_warning("You are restricted from reseting your own module."))
else if(U.locked)
to_chat(usr, span_filter_notice("The upgrade is locked and cannot be used yet!"))
else
@@ -796,6 +768,7 @@
notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, module.name)
module.Reset(src)
qdel(module)
icon_selected = FALSE
module = null
updatename("Default")
has_recoloured = FALSE
@@ -903,7 +876,7 @@
else if(istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = M
if(check_access(R.get_active_hand()) || istype(R.get_active_hand(), /obj/item/card/robot))
return 1
return TRUE
return 0
/mob/living/silicon/robot/proc/check_access(obj/item/I)
@@ -1088,60 +1061,6 @@
return
/mob/living/silicon/robot/proc/choose_icon(var/triesleft)
var/robot_species = null
if(!SSrobot_sprites)
to_chat(src, "Robot Sprites have not been initialized yet. How are you choosing a sprite? Harass a coder.")
return
var/list/module_sprites = SSrobot_sprites.get_module_sprites(modtype, src)
if(!module_sprites || !module_sprites.len)
to_chat(src, "Your module appears to have no sprite options. Harass a coder.")
return
icon_selected = 0
icon_selection_tries = triesleft
if(module_sprites.len == 1 || !client)
if(!(sprite_datum in module_sprites))
sprite_datum = module_sprites[1]
else
var/selection = tgui_input_list(src, "Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot Icon", module_sprites)
if(selection)
sprite_datum = selection
else
sprite_datum = module_sprites[1]
if(!istype(src,/mob/living/silicon/robot/drone))
robot_species = sprite_datum.name
if(notransform)
to_chat(src, "Your current transformation has not finished yet!")
choose_icon(icon_selection_tries)
return
else
transform_with_anim()
var/tempheight = vis_height
update_icon()
// This is bad but I dunno other way to 'reset' our resize offset based on vis_height changes other than resizing to normal and back.
if(tempheight != vis_height)
var/tempsize = size_multiplier
resize(1)
resize(tempsize)
if (module_sprites.len > 1 && triesleft >= 1 && client)
icon_selection_tries--
var/choice = tgui_alert(usr, "Look at your icon - is this what you want?", "Icon Choice", list("Yes","No"))
if(choice == "No")
choose_icon(icon_selection_tries)
return
icon_selected = 1
icon_selection_tries = 0
sprite_type = robot_species
if(hands)
update_hud()
to_chat(src, span_filter_notice("Your icon has been set. You now require a module reset to change it."))
/mob/living/silicon/robot/proc/set_default_module_icon()
if(!SSrobot_sprites)
return
@@ -73,7 +73,7 @@ var/global/list/robot_modules = list(
R.radio.recalculateChannels()
R.set_default_module_icon()
R.choose_icon(SSrobot_sprites.get_module_sprites_len(R.modtype, R) + 1)
R.pick_module()
if(!R.client)
R.icon_selected = FALSE // It wasnt a player selecting icon? Let them do it later!
@@ -93,7 +93,7 @@ var/global/list/robot_modules = list(
if(R.radio)
R.radio.recalculateChannels()
R.choose_icon(0)
R.set_default_module_icon()
R.scrubbing = FALSE
@@ -52,6 +52,10 @@
var/mob/living/silicon/robot/R = host
data["module_name"] = R.module ? "[R.module]" : null
if(R.emagged)
data["theme"] = "syndicate"
else if (R.ui_theme)
data["theme"] = R.ui_theme
if(!R.module)
return data
@@ -0,0 +1,179 @@
// Robot module selection
/datum/tgui_module/robot_ui_module
name = "Robot Module Configurator"
tgui_id = "RobotChoose"
var/selected_module
var/new_name
var/datum/robot_sprite/sprite_datum
/datum/tgui_module/robot_ui_module/tgui_state(mob/user)
return GLOB.tgui_self_state
/datum/tgui_module/robot_ui_module/tgui_close(mob/user)
. = ..()
if(isrobot(user))
var/mob/living/silicon/robot/R = user
R.selecting_module = FALSE
/datum/tgui_module/robot_ui_module/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
. = ..()
if(isrobot(user) && ui)
var/mob/living/silicon/robot/R = user
R.selecting_module = TRUE
/datum/tgui_module/robot_ui_module/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/robot_icons)
)
/datum/tgui_module/robot_ui_module/tgui_static_data()
var/list/data = ..()
var/mob/living/silicon/robot/R = host
var/list/modules = list()
if(R.module)
modules = list(R.modtype)
selected_module = R.modtype
else
if(LAZYLEN(R.restrict_modules_to) > 0)
modules.Add(R.restrict_modules_to)
else if(R.shell)
modules.Add(shell_module_types)
else
modules.Add(robot_module_types)
if(R.crisis || security_level == SEC_LEVEL_RED || R.crisis_override)
to_chat(R, span_red("Crisis mode active. Combat module available."))
modules |= emergency_module_types
for(var/module_name in whitelisted_module_types)
if(is_borg_whitelisted(R, module_name))
modules |= module_name
data["possible_modules"] = modules
if(R.emagged)
data["theme"] = "syndicate"
else if (R.ui_theme)
data["theme"] = R.ui_theme
return data
/datum/tgui_module/robot_ui_module/tgui_data()
var/list/data = ..()
var/mob/living/silicon/robot/R = host
var/datum/asset/spritesheet/robot_icons/spritesheet = get_asset_datum(/datum/asset/spritesheet/robot_icons)
data["currentName"] = new_name ? new_name : R.name
data["isDefaultName"] = !new_name
if(selected_module)
data["selected_module"] = selected_module
if(!SSrobot_sprites)
to_chat(R, span_warning("Robot Sprites have not been initialized yet. How are you choosing a sprite? Harass a coder."))
selected_module = null
return
var/list/module_sprites = SSrobot_sprites.get_module_sprites(selected_module, R)
if(!module_sprites || !module_sprites.len)
to_chat(R, span_warning("Your module appears to have no sprite options. Harass a coder."))
selected_module = null
return
var/list/available_sprites = list()
for(var/datum/robot_sprite/S in module_sprites)
var/model_type = "def"
if(istype(S, /datum/robot_sprite/dogborg))
model_type = "wide"
if(istype(S, /datum/robot_sprite/dogborg/tall))
model_type = "tall"
available_sprites += list(list("sprite" = S.name, "belly" = S.has_vore_belly_sprites, "type" = model_type))
data["possible_sprites"] = available_sprites
data["sprite_datum"] = sprite_datum
data["sprite_datum_class"] = null
data["sprite_datum_size"] = null
if(sprite_datum)
data["sprite_datum_class"] = sanitize_css_class_name("[sprite_datum.type]")
data["sprite_datum_size"] = spritesheet.icon_size_id(data["sprite_datum_class"] + "S") // just get the south icon's size, the rest will be the same
return data
/datum/tgui_module/robot_ui_module/tgui_act(action, params)
. = ..()
if(.)
return
var/mob/living/silicon/robot/R = host
switch(action)
if("pick_module")
if(R.module)
return
var/new_module = params["value"]
if(!(new_module in robot_modules))
return
if(!is_borg_whitelisted(R, new_module))
return
selected_module = new_module
if(sprite_datum)
var/new_datum
var/list/module_sprites = SSrobot_sprites.get_module_sprites(selected_module, R)
for(var/datum/robot_sprite/S in module_sprites)
if(S.name == sprite_datum.name)
new_datum = S
break
sprite_datum = new_datum
. = TRUE
if("pick_icon")
var/sprite = params["value"]
if(!sprite)
return
var/list/module_sprites = SSrobot_sprites.get_module_sprites(selected_module, R)
for(var/datum/robot_sprite/S in module_sprites)
if(S.name == sprite)
sprite_datum = S
break
. = TRUE
if("rename")
var/name = params["value"]
if(name)
new_name = sanitizeSafe(name, MAX_NAME_LEN)
. = TRUE
if("confirm")
R.apply_name(new_name)
R.apply_module(sprite_datum, selected_module)
R.transform_module()
close_ui()
. = TRUE
/mob/living/silicon/robot/proc/apply_name(var/new_name)
if(!custom_name)
if (new_name)
custom_name = new_name
sprite_name = new_name
/mob/living/silicon/robot/proc/apply_module(var/datum/robot_sprite/new_datum, var/new_module)
icon_selected = TRUE
var/module_type = robot_modules[new_module]
modtype = new_module
module = new module_type(src)
feedback_inc("cyborg_[lowertext(new_module)]",1)
updatename()
hud_used.update_robot_modules_display()
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
robotact?.update_static_data_for_all_viewers()
sprite_datum = new_datum
if(!istype(src,/mob/living/silicon/robot/drone))
sprite_type = sprite_datum.name
/mob/living/silicon/robot/proc/transform_module()
transform_with_anim()
var/tempheight = vis_height
update_icon()
// This is bad but I dunno other way to 'reset' our resize offset based on vis_height changes other than resizing to normal and back.
if(tempheight != vis_height)
var/tempsize = size_multiplier
resize(1)
resize(tempsize)
if(hands)
update_hud()
sprite_datum.do_equipment_glamour(module)
to_chat(src, span_filter_notice("Your icon has been set. You now require a module reset to change it."))
@@ -9,6 +9,7 @@
icon_selected = FALSE
can_be_antagged = FALSE
restrict_modules_to = list("Gravekeeper")
ui_theme = "malfunction"
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
@@ -9,6 +9,7 @@
icon_selected = FALSE
restrict_modules_to = list("Lost")
var/law_retries = 5
ui_theme = "malfunction"
/mob/living/silicon/robot/lost/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
@@ -8,6 +8,7 @@
idcard_type = /obj/item/card/id/syndicate
icon_selected = FALSE
restrict_modules_to = list("Protector", "Mechanist", "Combat Medic")
ui_theme = "syndicate"
/mob/living/silicon/robot/syndicate/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
@@ -0,0 +1,101 @@
//turkey - sprites and writing done by VerySoft
/mob/living/simple_mob/vore/turkeygirl
name = "turkeygirl"
desc = "A feathered woman! She looks like some kind of plump turkey!"
tt_desc = "Meleagris gallopian"
icon = 'icons/mob/turkey.dmi'
icon_state = "turkeygirl"
icon_living = "turkeygirl"
icon_dead = "turkeygirl-dead"
health = 100
maxHealth = 100
has_hands = TRUE
faction = "turkey"
response_help = "hugs"
response_disarm = "pushes"
response_harm = "punches"
attacktext = list("pecked")
has_langs = list(LANGUAGE_GALCOM , LANGUAGE_ANIMAL)
meat_amount = 100
meat_type = /obj/item/reagent_containers/food/snacks/meat/chicken
ai_holder_type = /datum/ai_holder/simple_mob/passive
say_list_type = /datum/say_list/turkey
vore_active = 1
vore_capacity = 2
vore_bump_chance = 10
vore_pounce_chance = 10
vore_pounce_maxhealth = 999
vore_ignores_undigestable = 0
vore_default_mode = DM_SELECT
vore_icons = SA_ICON_LIVING
vore_stomach_name = "Stomach"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
vore_standing_too = TRUE
/mob/living/simple_mob/vore/turkeygirl/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "The hot churning stomach of a turkey girl! The doughy flesh presses inward to form to your figure, thick slime coating everything, and very shortly that includes you as well! There isn't any escaping that constant full body motion, as her body works to ball yours up into a tight little package. Gurgling and glubbing with every shifting movement, while her pulse throbs through the flesh all around you with every beat of her heart. All in all, one thing is for certain! You've become turkey stuffing! Oh no..."
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
B.belly_fullscreen = "anibelly"
B.digest_brute = 1
B.digest_burn = 6
B.digestchance = 0
B.absorbchance = 0
B.escapechance = 15
B.colorization_enabled = TRUE
B.belly_fullscreen_color = "#521717"
/datum/say_list/turkey
speak = list("Gobble!", "Gobble gobble!", "Gobble gobble gobble!", "Give me something to be thankful for~", "Could use something to gobble~", "Why don't you make a pilgrimage over here and give me something good to eat?", "I want a treat... I could bite you too if you like~", "What's your favorite time of year?", "Autumn is the best time of year~", "You just gonna let a girl go hungry?")
/mob/living/simple_mob/vore/turkeygirl/update_icon()
. = ..()
if(stat == DEAD)
return
if(vore_fullness == 2 || nutrition >= 5000)
icon_state = "[icon_living]-2"
else if(vore_fullness == 1 || nutrition >= 2500)
icon_state = "[icon_living]-1"
if(resting)
icon_state = "[icon_state]-resting"
/mob/living/simple_mob/vore/turkeygirl/attackby(var/obj/item/reagent_containers/food/snacks/O as obj, var/mob/user as mob)
if(stat)
return ..()
if(!istype(O, /obj/item/reagent_containers/food/snacks))
return ..()
if(nutrition >= max_nutrition)
if(user == src)
to_chat(src, span_notice("You're too full to eat another bite."))
return
to_chat(user, span_notice("\The [src] seems too full to eat."))
return
user.setClickCooldown(user.get_attack_speed(O))
if(O.reagents)
O.reagents.trans_to_mob(src, O.bitesize, CHEM_INGEST)
adjust_nutrition(O.bitesize * 20)
O.bitecount ++
O.On_Consume(src)
if(O)
to_chat(user, span_notice("\The [src] takes a bite of \the [O]."))
if(user != src)
to_chat(src, span_notice("\The [user] feeds \the [O] to you."))
playsound(src, 'sound/items/eatfood.ogg', 75, 1)
update_icon()
@@ -9,7 +9,7 @@
icon_rest = "wah_rest"
icon = 'icons/mob/vore.dmi'
faction = FACTION_REDPANDA //stop naming stuff vaguely
faction = FACTION_REDPANDA
maxHealth = 30
health = 30
@@ -88,7 +88,7 @@ var/global/list/grub_machine_overlays = list()
return
if(istype(loc, /obj/machinery))
if(machine_effect && air_master.current_cycle%30)
if(machine_effect && SSair.current_cycle%30)
for(var/mob/M in player_list)
M << machine_effect
if(prob(10))
@@ -0,0 +1,43 @@
/mob/living/simple_mob/vore/turkey
name = "turkey"
desc = "A large turkey, all ready for stuffing."
tt_desc = "Meleagris gallopavo"
icon_state = "turkey"
icon_living = "turkey"
icon_dead = "turkeydead"
icon_rest = "turkeyrest"
icon = 'icons/mob/vore.dmi'
faction = FACTION_TURKEY
maxHealth = 25
health = 25
meat_amount = 1
meat_type = /obj/item/reagent_containers/food/snacks/rawturkey
name_the_meat = FALSE
response_help = "pats"
response_disarm = "gently pushes aside"
response_harm = "hits"
harm_intent_damage = 3
melee_damage_lower = 3
melee_damage_upper = 1
attacktext = list("pecked")
say_list_type = /datum/say_list/turkey
ai_holder_type = /datum/ai_holder/simple_mob/passive
allow_mind_transfer = TRUE
vore_active = 1
vore_bump_chance = 10
vore_bump_emote = "greedily leaps at"
vore_default_mode = DM_HOLD
vore_icons = SA_ICON_LIVING
/datum/say_list/turkey
speak = list("GOBBLEGOBBLE!","Gobble?","Gobblegobble...")
emote_hear = list("gobbles!")
emote_see = list("flaps its wings","pecks something on the floor","puffs up its feathers")
-213
View File
@@ -1,213 +0,0 @@
var/global/const
SKILL_NONE = 0
SKILL_BASIC = 1
SKILL_ADEPT = 2
SKILL_EXPERT = 3
SKILL_PROF = 4
/datum/skill/var
ID = "none" // ID of the skill, used in code
name = "None" // name of the skill
desc = "Placeholder skill" // detailed description of the skill
field = "Misc" // the field under which the skill will be listed
secondary = 0 // secondary skills only have two levels and cost significantly less
var/global/list/SKILLS = null
var/list/SKILL_ENGINEER = list("field" = "Engineering", "EVA" = SKILL_BASIC, "construction" = SKILL_ADEPT, "electrical" = SKILL_BASIC, "engines" = SKILL_ADEPT)
var/list/SKILL_ORGAN_ROBOTICIST = list("field" = "Science", "devices" = SKILL_ADEPT, "electrical" = SKILL_BASIC, "computer" = SKILL_ADEPT, "anatomy" = SKILL_BASIC)
var/list/SKILL_SECURITY_OFFICER = list("field" = "Security", "combat" = SKILL_BASIC, "weapons" = SKILL_ADEPT, "law" = SKILL_ADEPT, "forensics" = SKILL_BASIC)
var/list/SKILL_CHEMIST = list("field" = "Science", "chemistry" = SKILL_ADEPT, "science" = SKILL_ADEPT, "medical" = SKILL_BASIC, "devices" = SKILL_BASIC)
var/global/list/SKILL_PRE = list(JOB_ENGINEER = SKILL_ENGINEER, JOB_ROBOTICIST = SKILL_ORGAN_ROBOTICIST, JOB_SECURITY_OFFICER = SKILL_SECURITY_OFFICER, JOB_CHEMIST = SKILL_CHEMIST)
/datum/skill/management
ID = "management"
name = "Command"
desc = "Your ability to manage and commandeer other crew members."
/datum/skill/combat
ID = "combat"
name = "Close Combat"
desc = "This skill describes your training in hand-to-hand combat or melee weapon usage. While expertise in this area is rare in the era of firearms, experts still exist among athletes."
field = "Security"
/datum/skill/weapons
ID = "weapons"
name = "Weapons Expertise"
desc = "This skill describes your expertise with and knowledge of weapons. A low level in this skill implies knowledge of simple weapons, for example tazers and flashes. A high level in this skill implies knowledge of complex weapons, such as grenades, riot shields, pulse rifles or bombs. A low level in this skill is typical for security officers, a high level of this skill is typical for special agents and soldiers."
field = "Security"
/datum/skill/EVA
ID = "EVA"
name = "Extra-vehicular activity"
desc = "This skill describes your skill and knowledge of space-suits and working in vacuum."
field = "Engineering"
secondary = 1
/datum/skill/forensics
ID = "forensics"
name = "Forensics"
desc = "Describes your skill at performing forensic examinations and identifying vital evidence. Does not cover analytical abilities, and as such isn't the only indicator for your investigation skill. Note that in order to perform autopsy, the surgery skill is also required."
field = "Security"
/datum/skill/construction
ID = "construction"
name = "Construction"
desc = "Your ability to construct various buildings, such as walls, floors, tables and so on. Note that constructing devices such as APCs additionally requires the Electronics skill. A low level of this skill is typical for janitors, a high level of this skill is typical for engineers."
field = "Engineering"
/datum/skill/management
ID = "management"
name = "Command"
desc = "Your ability to manage and commandeer other crew members."
/datum/skill/knowledge/law
ID = "law"
name = "Corporate Law"
desc = "Your knowledge of corporate law and procedures. This includes Corporate Regulations, as well as general station rulings and procedures. A low level in this skill is typical for security officers, a high level in this skill is typical for Site Managers."
field = "Security"
secondary = 1
/datum/skill/devices
ID = "devices"
name = "Complex Devices"
desc = "Describes the ability to assemble complex devices, such as computers, circuits, printers, robots or gas tank assemblies(bombs). Note that if a device requires electronics or programming, those skills are also required in addition to this skill."
field = "Science"
/datum/skill/electrical
ID = "electrical"
name = "Electrical Engineering"
desc = "This skill describes your knowledge of electronics and the underlying physics. A low level of this skill implies you know how to lay out wiring and configure powernets, a high level of this skill is required for working complex electronic devices such as circuits or bots."
field = "Engineering"
/datum/skill/atmos
ID = "atmos"
name = "Atmospherics"
desc = "Describes your knowledge of piping, air distribution and gas dynamics."
field = "Engineering"
/datum/skill/engines
ID = "engines"
name = "Engines"
desc = "Describes your knowledge of the various engine types common on space stations, such as the singularity or anti-matter engine."
field = "Engineering"
secondary = 1
/datum/skill/computer
ID = "computer"
name = "Information Technology"
desc = "Describes your understanding of computers, software and communication. Not a requirement for using computers, but definitely helps. Used in telecommunications and programming of computers and AIs."
field = "Science"
/datum/skill/pilot
ID = "pilot"
name = "Heavy Machinery Operation"
desc = "Describes your experience and understanding of operating heavy machinery, which includes mechs and other large exosuits. Used in piloting mechs."
field = "Engineering"
/datum/skill/medical
ID = "medical"
name = "Medicine"
desc = "Covers an understanding of the human body and medicine. At a low level, this skill gives a basic understanding of applying common types of medicine, and a rough understanding of medical devices like the health analyzer. At a high level, this skill grants exact knowledge of all the medicine available on the station, as well as the ability to use complex medical devices like the body scanner or mass spectrometer."
field = "Medical"
/datum/skill/anatomy
ID = "anatomy"
name = "Anatomy"
desc = "Gives you a detailed insight of the human body. A high skill in this is required to perform surgery.This skill may also help in examining alien biology."
field = "Medical"
/datum/skill/virology
ID = "virology"
name = "Virology"
desc = "This skill implies an understanding of microorganisms and their effects on humans."
field = "Medical"
/datum/skill/genetics
ID = "genetics"
name = "Genetics"
desc = "Implies an understanding of how DNA works and the structure of the human DNA."
field = "Science"
/datum/skill/chemistry
ID = "chemistry"
name = "Chemistry"
desc = "Experience with mixing chemicals, and an understanding of what the effect will be. This doesn't cover an understanding of the effect of chemicals on the human body, as such the medical skill is also required for medical chemists."
field = "Science"
/datum/skill/botany
ID = "botany"
name = "Botany"
desc = "Describes how good a character is at growing and maintaining plants."
/datum/skill/cooking
ID = "cooking"
name = "Cooking"
desc = "Describes a character's skill at preparing meals and other consumable goods. This includes mixing alcoholic beverages."
/datum/skill/science
ID = "science"
name = "Science"
desc = "Your experience and knowledge with scientific methods and processes."
field = "Science"
/datum/attribute/var
ID = "none"
name = "None"
desc = "This is a placeholder"
/proc/setup_skills()
if(SKILLS == null)
SKILLS = list()
for(var/T in subtypesof(/datum/skill))
var/datum/skill/S = new T
if(S.ID != "none")
if(!SKILLS.Find(S.field))
SKILLS[S.field] = list()
var/list/L = SKILLS[S.field]
L += S
/mob/living/carbon/human/proc/GetSkillClass(points)
return CalculateSkillClass(points, age)
/proc/show_skill_window(var/mob/user, var/mob/living/carbon/human/M)
if(!istype(M)) return
if(SKILLS == null)
setup_skills()
if(!M.skills || M.skills.len == 0)
to_chat(user, "There are no skills to display.")
return
var/HTML = "<body>"
HTML += span_bold("Select your Skills") + "<br>"
HTML += "Current skill level: <b>[M.GetSkillClass(M.used_skillpoints)]</b> ([M.used_skillpoints])<br>"
HTML += "<table>"
for(var/V in SKILLS)
HTML += "<tr><th colspan = 5>" + span_bold("[V]")
HTML += "</th></tr>"
for(var/datum/skill/S in SKILLS[V])
var/level = M.skills[S.ID]
HTML += "<tr style='text-align:left;'>"
HTML += "<th>[S.name]</th>"
HTML += "<th><font color=[(level == SKILL_NONE) ? "red" : "black"]>\[Untrained\]</font></th>"
// secondary skills don't have an amateur level
if(S.secondary)
HTML += "<th></th>"
else
HTML += "<th><font color=[(level == SKILL_BASIC) ? "red" : "black"]>\[Amateur\]</font></th>"
HTML += "<th><font color=[(level == SKILL_ADEPT) ? "red" : "black"]>\[Trained\]</font></th>"
HTML += "<th><font color=[(level == SKILL_EXPERT) ? "red" : "black"]>\[Professional\]</font></th>"
HTML += "</tr>"
HTML += "</table>"
user << browse(null, "window=preferences")
user << browse(HTML, "window=show_skills;size=600x800")
return
/mob/living/carbon/human/verb/show_skills()
set category = "IC.Game"
set name = "Show Own Skills"
show_skill_window(src, src)
-7
View File
@@ -32,9 +32,6 @@
set desc = "Emote to nearby people (and your pred/prey)"
set hidden = 1
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, span_red("Speech is currently admin-disabled."))
return
//VOREStation Addition Start
if(forced_psay)
pme(message)
@@ -56,10 +53,6 @@
usr.emote(message)
/mob/proc/say_dead(var/message)
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, span_danger("Speech is currently admin-disabled."))
return
if(!client)
return // Clientless mobs shouldn't be trying to talk in deadchat.
-6
View File
@@ -8,9 +8,6 @@
set desc = "Emote to nearby people (and your pred/prey)"
set hidden = 1
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, "Speech is currently admin-disabled.")
return
if(forced_psay)
pme(message)
return
@@ -30,9 +27,6 @@
set category = "IC.Subtle"
set desc = "Emote to nearby people, with ability to choose which specific portion of people you wish to target."
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, "Speech is currently admin-disabled.")
return
if(forced_psay)
pme(message)
return
-12
View File
@@ -1,12 +0,0 @@
// We don't actually have a skills system, so return max skill for everything.
/mob/proc/get_skill_value(skill_path)
return SKILL_EXPERT
// A generic way of modifying success probabilities via skill values. Higher factor means skills have more effect. fail_chance is the chance at SKILL_NONE.
/mob/proc/skill_fail_chance(skill_path, fail_chance, no_more_fail = SKILL_EXPERT, factor = 1)
var/points = get_skill_value(skill_path)
if(points >= no_more_fail)
return 0
else
return fail_chance * 2 ** (factor*(SKILL_BASIC - points))
-1
View File
@@ -190,7 +190,6 @@
O.custom_speech_bubble = B.custom_speech_bubble
callHook("borgify", list(O))
O.namepick()
spawn(0) // Mobs still instantly del themselves, thus we need to spawn or O will never be returned
qdel(src)