diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 6f2515b55d..d323270592 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -275,6 +275,41 @@ BLIND // can't see anything update_icon(user) user.update_action_buttons() +/obj/item/clothing/head/attack_ai(var/mob/user) + if(!mob_wear_hat(user)) + return ..() + +/obj/item/clothing/head/attack_generic(var/mob/user) + if(!mob_wear_hat(user)) + return ..() + +/obj/item/clothing/head/proc/mob_wear_hat(var/mob/user) + if(!Adjacent(user)) + return 0 + var/success + if(istype(user, /mob/living/silicon/robot/drone)) + var/mob/living/silicon/robot/drone/D = user + if(D.hat) + success = 2 + else + D.wear_hat(src) + success = 1 + else if(istype(user, /mob/living/carbon/alien/diona)) + var/mob/living/carbon/alien/diona/D = user + if(D.hat) + success = 2 + else + D.wear_hat(src) + success = 1 + + if(!success) + return 0 + else if(success == 2) + user << "You are already wearing a hat." + else if(success == 1) + user << "You crawl under \the [src]." + return 1 + /obj/item/clothing/head/update_icon(var/mob/user) overlays.Cut() diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 26cbefc482..862602bd5c 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -5,10 +5,12 @@ icon = 'icons/obj/objects.dmi' slot_flags = SLOT_HEAD sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') + origin_tech = null item_icons = list( slot_l_hand_str = 'icons/mob/items/lefthand_holder.dmi', slot_r_hand_str = 'icons/mob/items/righthand_holder.dmi', ) + pixel_y = 8 /obj/item/weapon/holder/New() ..() @@ -31,6 +33,38 @@ qdel(src) +/obj/item/weapon/holder/proc/sync(var/mob/living/M) + dir = 2 + overlays.Cut() + icon = M.icon + icon_state = M.icon_state + color = M.color + name = M.name + desc = M.desc + overlays |= M.overlays + var/mob/living/carbon/human/H = loc + if(istype(H)) + if(H.l_hand == src) + H.update_inv_l_hand() + else if(H.r_hand == src) + H.update_inv_r_hand() + else + H.regenerate_icons() + +//Mob specific holders. +/obj/item/weapon/holder/diona + origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5) + slot_flags = SLOT_HEAD | SLOT_OCLOTHING + +/obj/item/weapon/holder/drone + origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5) + +/obj/item/weapon/holder/mouse + w_class = 1 + +/obj/item/weapon/holder/borer + origin_tech = list(TECH_BIO = 6) + /obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob) for(var/mob/M in src.contents) M.attackby(W,user) @@ -50,72 +84,5 @@ grabber << "You scoop up [src]." src << "[grabber] scoops you up." grabber.status_flags |= PASSEMOTES + H.sync(src) return H - -//Mob specific holders. - -/obj/item/weapon/holder/diona - name = "diona nymph" - desc = "It's a tiny plant critter." - icon_state = "nymph" - origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5) - slot_flags = SLOT_HEAD | SLOT_OCLOTHING - -/obj/item/weapon/holder/drone - name = "maintenance drone" - desc = "It's a small maintenance robot." - icon_state = "drone" - origin_tech = list(TECH_MAGNET = 3, TECH_ENGINERING = 5) - -/obj/item/weapon/holder/cat - name = "cat" - desc = "It's a cat. Meow." - icon_state = "cat" - origin_tech = null - -/obj/item/weapon/holder/mouse - name = "mouse" - desc = "It's a small rodent." - icon_state = "mouse_gray" - origin_tech = null - w_class = 1 - -/obj/item/weapon/holder/mouse/gray - icon_state = "mouse_gray" - -/obj/item/weapon/holder/mouse/white - icon_state = "mouse_white" - -/obj/item/weapon/holder/mouse/brown - icon_state = "mouse_brown" - -/obj/item/weapon/holder/borer - name = "cortical borer" - desc = "It's a slimy brain slug. Gross." - icon_state = "borer" - origin_tech = list(TECH_BIO = 6) - -/obj/item/weapon/holder/monkey - name = "monkey" - desc = "It's a monkey. Ook." - icon_state = "monkey" - -/obj/item/weapon/holder/monkey/farwa - name = "farwa" - desc = "It's a farwa." - icon_state = "farwa" - -/obj/item/weapon/holder/monkey/stok - name = "stok" - desc = "It's a stok. stok." - icon_state = "stok" - -/obj/item/weapon/holder/monkey/neaera - name = "neaera" - desc = "It's a neaera." - icon_state = "neara" - -/obj/item/weapon/holder/pai - name = "pAI" - desc = "It's a little robot." - icon_state = "pai" diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm index 86dc101eda..95f01a6dff 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona.dm @@ -9,6 +9,7 @@ universal_understand = 1 universal_speak = 0 // Dionaea do not need to speak to people other than other dionaea. holder_type = /obj/item/weapon/holder/diona + var/obj/item/hat /mob/living/carbon/alien/diona/New() @@ -32,3 +33,10 @@ /mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands. W.loc = get_turf(src) return 1 + +/mob/living/carbon/alien/diona/proc/wear_hat(var/obj/item/new_hat) + if(hat) + return + hat = new_hat + new_hat.loc = src + update_icons() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm index 956171abf7..45d1f6fe46 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm @@ -6,5 +6,22 @@ return get_scooped(H) return + else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand)) + hat.loc = get_turf(src) + H.put_in_hands(hat) + H.visible_message("\The [H] removes \the [src]'s [hat].") + hat = null + update_icons() else return ..() + +/mob/living/carbon/alien/diona/attackby(var/obj/item/weapon/W, var/mob/user) + if(user.a_intent == "help" && istype(W, /obj/item/clothing/head)) + if(hat) + user << "\The [src] is already wearing \the [hat]." + return + user.unEquip(W) + wear_hat(W) + user.visible_message("\The [user] puts \the [W] on \the [src].") + return + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/diona/update_icons.dm b/code/modules/mob/living/carbon/alien/diona/update_icons.dm index b39972cdad..1d694cf624 100644 --- a/code/modules/mob/living/carbon/alien/diona/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/diona/update_icons.dm @@ -6,3 +6,7 @@ icon_state = "[initial(icon_state)]_sleep" else icon_state = "[initial(icon_state)]" + + overlays.Cut() + if(hat) + overlays |= get_hat_icon(hat, 0, -8) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index db6c69b409..6ae24db2f6 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -37,7 +37,6 @@ bump_flag = MONKEY swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN - var/holder_type = /obj/item/weapon/holder/monkey /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) if(H.stat != CONSCIOUS) @@ -47,10 +46,6 @@ if(prob(1)) H.emote(pick("scratch","jump","roll","tail")) -/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) - ..() - H.holder_type = holder_type - /datum/species/monkey/get_random_name() return "[lowertext(name)] ([rand(100,999)])" @@ -66,7 +61,6 @@ flesh_color = "#AFA59E" base_color = "#333333" tail = "farwatail" - holder_type = /obj/item/weapon/holder/monkey/farwa /datum/species/monkey/skrell name = "Neara" @@ -81,7 +75,6 @@ blood_color = "#1D2CBF" reagent_tag = IS_SKRELL tail = null - holder_type = /obj/item/weapon/holder/monkey/neaera /datum/species/monkey/unathi name = "Stok" @@ -96,4 +89,3 @@ flesh_color = "#34AF10" base_color = "#066000" reagent_tag = IS_UNATHI - holder_type = /obj/item/weapon/holder/monkey/stok diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 65e8c2f278..5e7a6e2d90 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -127,7 +127,8 @@ //this handles hud updates. Calls update_vision() and handle_hud_icons() /mob/living/handle_regular_hud_updates() - if(!client) return 0 + if(!client) + return 0 ..() handle_vision() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index ad06c58d6e..4641c7d2de 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -6,7 +6,6 @@ emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person) small = 1 pass_flags = 1 - holder_type = /obj/item/weapon/holder/pai var/network = "SS13" var/obj/machinery/camera/current = null @@ -430,4 +429,4 @@ get_scooped(H) return else - return ..() + return ..() diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 04e3728c6a..37c40d7161 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -1,3 +1,23 @@ +var/list/mob_hat_cache = list() +/proc/get_hat_icon(var/obj/item/hat, var/offset_x = 0, var/offset_y = 0) + var/t_state = hat.icon_state + if(hat.item_state_slots && hat.item_state_slots[slot_head_str]) + t_state = hat.item_state_slots[slot_head_str] + else if(hat.item_state) + t_state = hat.item_state + var/key = "[t_state]_[offset_x]_[offset_y]" + if(!mob_hat_cache[key]) // Not ideal as there's no guarantee all hat icon_states + var/t_icon = INV_HEAD_DEF_ICON // are unique across multiple dmis, but whatever. + if(hat.icon_override) + t_icon = hat.icon_override + else if(hat.item_icons && (slot_head_str in hat.item_icons)) + t_icon = hat.item_icons[slot_head_str] + var/image/I = image(icon = t_icon, icon_state = t_state) + I.pixel_x = offset_x + I.pixel_y = offset_y + mob_hat_cache[key] = I + return mob_hat_cache[key] + /mob/living/silicon/robot/drone name = "drone" real_name = "drone" @@ -29,9 +49,26 @@ var/module_type = /obj/item/weapon/robot_module/drone var/can_pull_size = 2 var/can_pull_mobs + var/obj/item/hat + var/hat_x_offset = 0 + var/hat_y_offset = -13 holder_type = /obj/item/weapon/holder/drone +/mob/living/silicon/robot/drone/Destroy() + if(hat) + hat.loc = get_turf(src) + ..() + +/mob/living/silicon/robot/drone/construction + icon_state = "constructiondrone" + law_type = /datum/ai_laws/construction_drone + module_type = /obj/item/weapon/robot_module/drone/construction + can_pull_size = 5 + can_pull_mobs = 1 + hat_x_offset = 1 + hat_y_offset = -12 + /mob/living/silicon/robot/drone/New() ..() @@ -82,6 +119,8 @@ overlays += "eyes-[icon_state]" else overlays -= "eyes" + if(hat) // Let the drones wear hats. + overlays |= get_hat_icon(hat, hat_x_offset, hat_y_offset) /mob/living/silicon/robot/drone/choose_icon() return @@ -89,10 +128,25 @@ /mob/living/silicon/robot/drone/pick_module() return -//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..(). -/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob) +/mob/living/silicon/robot/drone/proc/wear_hat(var/obj/item/new_hat) + if(hat) + return + hat = new_hat + new_hat.loc = src + updateicon() - if(istype(W, /obj/item/borg/upgrade/)) +//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..(). +/mob/living/silicon/robot/drone/attackby(var/obj/item/weapon/W, var/mob/user) + + if(user.a_intent == "help" && istype(W, /obj/item/clothing/head)) + if(hat) + user << "\The [src] is already wearing \the [hat]." + return + user.unEquip(W) + wear_hat(W) + user.visible_message("\The [user] puts \the [W] on \the [src].") + return + else if(istype(W, /obj/item/borg/upgrade/)) user << "\The [src] is not compatible with \the [W]." return @@ -135,7 +189,7 @@ return ..() - + /mob/living/silicon/robot/drone/emag_act(var/remaining_charges, var/mob/user) if(!client || stat == 2) user << "There's not much point subverting this heap of junk." @@ -279,13 +333,6 @@ /mob/living/silicon/robot/drone/remove_robot_verbs() src.verbs -= silicon_subsystems -/mob/living/silicon/robot/drone/construction - icon_state = "constructiondrone" - law_type = /datum/ai_laws/construction_drone - module_type = /obj/item/weapon/robot_module/drone/construction - can_pull_size = 5 - can_pull_mobs = 1 - /mob/living/silicon/robot/drone/construction/welcome_drone() src << "You are a construction drone, an autonomous engineering and fabrication system.." src << "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible." diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index 0eaf1c8779..e5aa936a08 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -10,13 +10,13 @@ mail_destination = "" return - src << "\blue You configure your internal beacon, tagging yourself for delivery to '[new_tag]'." + src << "You configure your internal beacon, tagging yourself for delivery to '[new_tag]'." mail_destination = new_tag //Auto flush if we use this verb inside a disposal chute. var/obj/machinery/disposal/D = src.loc if(istype(D)) - src << "\blue \The [D] acknowledges your signal." + src << "\The [D] acknowledges your signal." D.flush_count = D.flush_every_ticks return @@ -27,5 +27,11 @@ if(H.a_intent == "help") get_scooped(H) return + else if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand)) + hat.loc = get_turf(src) + H.put_in_hands(hat) + H.visible_message("\The [H] removes \the [src]'s [hat].") + hat = null + updateicon() else return ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index a292ead1b1..171fc29933 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -78,7 +78,8 @@ flick("h_lathe_leave",src) time_last_drone = world.time - var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src)) + if(player.mob && player.mob.mind) player.mob.mind.reset() + var/mob/living/silicon/robot/drone/new_drone = PoolOrNew(drone_type, get_turf(src)) new_drone.transfer_personality(player) new_drone.master_fabricator = src @@ -90,7 +91,6 @@ set name = "Join As Drone" set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone." - if(ticker.current_state < GAME_STATE_PLAYING) src << "The game hasn't started yet!" return @@ -108,17 +108,11 @@ if(jobban_isbanned(src,"Cyborg")) usr << "You are banned from playing synthetics and cannot spawn as a drone." return - + if(!MayRespawn(1)) return var/deathtime = world.time - src.timeofdeath - if(istype(src,/mob/dead/observer)) - var/mob/dead/observer/G = src - if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted) - usr << "Upon using the antagHUD you forfeighted the ability to join the round." - return - var/deathtimeminutes = round(deathtime / 600) var/pluralcheck = "minute" if(deathtimeminutes == 0) diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 70f7282b8e..e0ffc718ff 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -63,13 +63,6 @@ if(!body_color) body_color = pick( list("brown","gray","white") ) - switch(body_color) - if("brown") - holder_type = /obj/item/weapon/holder/mouse/brown - if("gray") - holder_type = /obj/item/weapon/holder/mouse/gray - if("white") - holder_type = /obj/item/weapon/holder/mouse/white icon_state = "mouse_[body_color]" icon_living = "mouse_[body_color]" icon_dead = "mouse_[body_color]_dead" @@ -125,17 +118,14 @@ /mob/living/simple_animal/mouse/white body_color = "white" icon_state = "mouse_white" - holder_type = /obj/item/weapon/holder/mouse/white /mob/living/simple_animal/mouse/gray body_color = "gray" icon_state = "mouse_gray" - holder_type = /obj/item/weapon/holder/mouse/gray /mob/living/simple_animal/mouse/brown body_color = "brown" icon_state = "mouse_brown" - holder_type = /obj/item/weapon/holder/mouse/brown //TOM IS ALIVE! SQUEEEEEEEE~K :) /mob/living/simple_animal/mouse/brown/Tom diff --git a/html/changelogs/Zuhayr-dronehats.yml b/html/changelogs/Zuhayr-dronehats.yml new file mode 100644 index 0000000000..06dc80786d --- /dev/null +++ b/html/changelogs/Zuhayr-dronehats.yml @@ -0,0 +1,4 @@ +author: Zuhayr +delete-after: True +changes: + - rscadd: "Click a hat on a drone with help intent to equip it. Drag the drone onto yourself with grab intent to remove it." diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index 362dcc96ea..171abcf1c0 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ