diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm index 885e06d83b..108e50b07a 100644 --- a/code/citadel/custom_loadout/custom_items.dm +++ b/code/citadel/custom_loadout/custom_items.dm @@ -16,17 +16,20 @@ /obj/item/clothing/neck/cloak/inferno name = "Kiara's Cloak" desc = "The design on this seems a little too familiar." - icon = 'icons/obj/clothing/cloaks.dmi' - icon_state = "infcloak" - item_state = "infcloak" + icon = 'icons/obj/custom.dmi' + icon_state = "infcloak-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "infcloak-w" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS /obj/item/clothing/neck/petcollar/inferno name = "Kiara's Collar" desc = "A soft black collar that seems to stretch to fit whoever wears it." - icon_state = "infcollar" - item_state = "infcollar" + icon = 'icons/obj/custom.dmi' + icon_state = "infcollar-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "infcollar-w" item_color = null tagname = null @@ -43,7 +46,7 @@ /obj/item/lighter/gold name = "\improper Engraved Zippo" desc = "A shiny and relatively expensive zippo lighter. There's a small etched in verse on the bottom that reads, 'No Gods, No Masters, Only Man.'" - icon = 'icons/obj/cigarettes.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "gold_zippo" item_state = "gold_zippo" w_class = WEIGHT_CLASS_TINY @@ -58,16 +61,20 @@ /obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies. name = "A special scarf" - icon_state = "zombscarf" + icon = 'icons/obj/custom.dmi' + icon_state = "zombscarf-i" desc = "A fashionable collar" - item_color = "zombscarf" + icon_override = 'icons/obj/custom.dmi' + item_color = "zombscarf-w" dog_fashion = /datum/dog_fashion/head /obj/item/clothing/suit/toggle/labcoat/mad/red name = "\improper The Mad's labcoat" desc = "An oddly special looking coat." - icon_state = "labred" - item_state = "labred" + icon = 'icons/obj/custom.dmi' + icon_state = "labred-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "labred-w" /*PLACEHOLDER*/ @@ -86,17 +93,17 @@ /obj/item/clothing/neck/cloak/carrot name = "carrot cloak" desc = "A cloak in the shape and color of a carrot!" - icon = 'icons/obj/clothing/cloaks.dmi' - icon_override = 'icons/mob/citadel/suit.dmi' - icon_state = "carrotcloak" - item_state = "carrotcloak" + icon = 'icons/obj/custom.dmi' + icon_override = 'icons/obj/custom.dmi' + icon_state = "carrotcloak-i" + item_state = "carrotcloak-w" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS /obj/item/toy/plush/tree name = "christmass tree plushie" desc = "A festive plush that squeeks when you squeeze it!" - icon = 'icons/obj/plushes.dmi' + icon = 'icons/obj/custom.dmi' icon_state = "pine_c" item_state = "pine_c" w_class = WEIGHT_CLASS_SMALL @@ -107,10 +114,10 @@ /obj/item/clothing/neck/cloak/festive name = "Celebratory Cloak of Morozko" desc = " It probably will protect from snow, charcoal or elves." - icon = 'icons/obj/clothing/cloaks.dmi' - icon_override = 'icons/mob/citadel/suit.dmi' - icon_state = "festivecloak" - item_state = "festiveloak" + icon = 'icons/obj/custom.dmi' + icon_state = "festive-i" + item_state = "festive-w" + icon_override = 'icons/obj/custom.dmi' w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -119,9 +126,10 @@ /obj/item/clothing/mask/luchador/zigfie name = "Alboroto Rosa mask" - icon = 'icons/mob/mask.dmi' - icon_state = "lucharzigfie" - item_state = "lucharzigfie" + icon = 'icons/obj/custom.dmi' + icon_state = "lucharzigfie-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "lucharzigfie-w" /*PLACEHOLDER*/ @@ -159,8 +167,10 @@ /obj/item/clothing/suit/trenchcoat/green name = "Reece's Great Coat" desc = "You would swear this was in your nightmares after eating too many veggies." - icon_state = "hos-g" - item_state = "hos-g" + icon = 'icons/obj/custom.dmi' + icon_state = "hos-g-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "hos-g-w" body_parts_covered = CHEST|GROIN|ARMS|LEGS @@ -170,14 +180,15 @@ desc = "Every good russian spaceman knows it's a good idea to bring along a couple of pints of whiskey wherever they go." icon = 'icons/obj/custom.dmi' icon_state = "russianflask" - item_state = "russianflask" volume = 60 /obj/item/clothing/mask/gas/stalker name = "S.T.A.L.K.E.R. mask" desc = "Smells like reactor four." - item_state = "stalker" - icon_state = "stalker" + icon = 'icons/obj/custom.dmi' + item_state = "stalker-w" + icon_override = 'icons/obj/custom.dmi' + icon_state = "stalker-i" /*Sylas*/ @@ -185,8 +196,9 @@ name = "collar" desc = "It's a collar..." icon = 'icons/obj/custom.dmi' - icon_state = "petcollar-stripe" - item_color = "petcollar-stripe" + icon_state = "petcollar-stripe-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "petcollar-stripe-w" tagname = null @@ -194,17 +206,21 @@ /obj/item/clothing/under/singery/custom name = "bluish performer's outfit" desc = "Just looking at this makes you want to sing." - icon_state = "ssing" - item_state = "ssing" - item_color = "ssing" + icon = 'icons/obj/custom.dmi' + icon_state = "singer-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "singer-w" + item_color = "singer-i" fitted = NO_FEMALE_UNIFORM alternate_worn_layer = ABOVE_SHOES_LAYER can_adjust = 0 /obj/item/clothing/shoes/sneakers/pink - icon_state = "pink" - item_state = "pink" + icon = 'icons/obj/custom.dmi' + icon_state = "pink-i" + icon_override = 'icons/obj/custom.dmi' + item_state = "pink-w" /*Fractious*/ @@ -212,10 +228,8 @@ /obj/item/clothing/suit/vermillion name = "vermillion clothing" desc = "Some clothing." - icon_state = "vermillion-w" - item_state = "vermillion-i" + icon_state = "vermillion-i" + item_state = "vermillion-w" body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS icon = 'icons/obj/custom.dmi' - - - + icon_override = 'icons/obj/custom.dmi' diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index f165717a31..e21db3e094 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -1,326 +1,326 @@ -/datum/component/riding - var/next_vehicle_move = 0 //used for move delays - var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower - var/keytype - - var/slowed = FALSE - var/slowvalue = 1 - - var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. - var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. - var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) - var/list/allowed_turf_typecache - var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. - var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. - var/override_allow_spacemove = FALSE - var/drive_verb = "drive" - var/ride_check_rider_incapacitated = FALSE - var/ride_check_rider_restrained = FALSE - var/ride_check_ridden_incapacitated = FALSE - -/datum/component/riding/Initialize() - if(!ismovableatom(parent)) - . = COMPONENT_INCOMPATIBLE - CRASH("RIDING COMPONENT ASSIGNED TO NON ATOM MOVABLE!") - RegisterSignal(COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) - RegisterSignal(COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) - RegisterSignal(COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) - -/datum/component/riding/proc/vehicle_mob_unbuckle(mob/living/M, force = FALSE) - restore_position(M) - unequip_buckle_inhands(M) - -/datum/component/riding/proc/vehicle_mob_buckle(mob/living/M, force = FALSE) - handle_vehicle_offsets() - -/datum/component/riding/proc/handle_vehicle_layer() - var/atom/movable/AM = parent - var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) - . = defaults["[AM.dir]"] - if(directional_vehicle_layers["[AM.dir]"]) - . = directional_vehicle_layers["[AM.dir]"] - if(isnull(.)) //you can set it to null to not change it. - . = AM.layer - AM.layer = . - -/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) - directional_vehicle_layers["[dir]"] = layer - -/datum/component/riding/proc/vehicle_moved() - var/atom/movable/AM = parent - for(var/i in AM.buckled_mobs) - ride_check(i) - handle_vehicle_offsets() - handle_vehicle_layer() - -/datum/component/riding/proc/ride_check(mob/living/M) - var/atom/movable/AM = parent - var/mob/AMM = AM - if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) - AM.visible_message("[M] falls off of [AM]!") - AM.unbuckle_mob(M) - return TRUE - -/datum/component/riding/proc/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - -/datum/component/riding/proc/handle_vehicle_offsets() - var/atom/movable/AM = parent - var/AM_dir = "[AM.dir]" - var/passindex = 0 - if(AM.has_buckled_mobs()) - for(var/m in AM.buckled_mobs) - passindex++ - var/mob/living/buckled_mob = m - var/list/offsets = get_offsets(passindex) - var/rider_dir = get_rider_dir(passindex) - buckled_mob.setDir(rider_dir) - dir_loop: - for(var/offsetdir in offsets) - if(offsetdir == AM_dir) - var/list/diroffsets = offsets[offsetdir] - buckled_mob.pixel_x = diroffsets[1] - if(diroffsets.len >= 2) - buckled_mob.pixel_y = diroffsets[2] - if(diroffsets.len == 3) - buckled_mob.layer = diroffsets[3] - break dir_loop - var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - var/px = default_vehicle_pixel_offsets[AM_dir] - var/py = default_vehicle_pixel_offsets[AM_dir] - if(directional_vehicle_offsets[AM_dir]) - if(isnull(directional_vehicle_offsets[AM_dir])) - px = AM.pixel_x - py = AM.pixel_y - else - px = directional_vehicle_offsets[AM_dir][1] - py = directional_vehicle_offsets[AM_dir][2] - AM.pixel_x = px - AM.pixel_y = py - -/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) - directional_vehicle_offsets["[dir]"] = list(x, y) - -//Override this to set your vehicle's various pixel offsets -/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) - . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - if(riding_offsets["[pass_index]"]) - . = riding_offsets["[pass_index]"] - else if(riding_offsets["[RIDING_OFFSET_ALL]"]) - . = riding_offsets["[RIDING_OFFSET_ALL]"] - -/datum/component/riding/proc/set_riding_offsets(index, list/offsets) - if(!islist(offsets)) - return FALSE - riding_offsets["[index]"] = offsets - -//Override this to set the passengers/riders dir based on which passenger they are. -//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. -/datum/component/riding/proc/get_rider_dir(pass_index) - var/atom/movable/AM = parent - return AM.dir - -//KEYS -/datum/component/riding/proc/keycheck(mob/user) - return !keytype || user.is_holding_item_of_type(keytype) - -//BUCKLE HOOKS -/datum/component/riding/proc/restore_position(mob/living/buckled_mob) - if(buckled_mob) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - if(buckled_mob.client) - buckled_mob.client.change_view(CONFIG_GET(string/default_view)) - -//MOVEMENT -/datum/component/riding/proc/turf_check(turf/next, turf/current) - if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) - else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) - return TRUE - -/datum/component/riding/proc/handle_ride(mob/user, direction) - var/atom/movable/AM = parent - if(user.incapacitated()) - Unbuckle(user) - return - - if(world.time < next_vehicle_move) - return - next_vehicle_move = world.time + vehicle_move_delay - - if(keycheck(user)) - var/turf/next = get_step(AM, direction) - var/turf/current = get_turf(AM) - if(!istype(next) || !istype(current)) - return //not happening. - if(!turf_check(next, current)) - to_chat(user, "Your \the [AM] can not go onto [next]!") - return - if(!Process_Spacemove(direction) || !isturf(AM.loc)) - return - step(AM, direction) - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") - -/datum/component/riding/proc/Unbuckle(atom/movable/M) - addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) - -/datum/component/riding/proc/Process_Spacemove(direction) - var/atom/movable/AM = parent - return override_allow_spacemove || AM.has_gravity() - -/datum/component/riding/proc/account_limbs(mob/living/M) - if(M.get_num_legs() < 2 && !slowed) - vehicle_move_delay = vehicle_move_delay + slowvalue - slowed = TRUE - else if(slowed) - vehicle_move_delay = vehicle_move_delay - slowvalue - slowed = FALSE - -///////Yes, I said humans. No, this won't end well...////////// -/datum/component/riding/human - -/datum/component/riding/human/Initialize() - . = ..() - RegisterSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) - -/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) - var/mob/living/carbon/human/AM = parent - if(AM.a_intent == INTENT_DISARM && (target in AM.buckled_mobs)) - force_dismount(target) - -/datum/component/riding/human/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/human/force_dismount(mob/living/user) - var/atom/movable/AM = parent - AM.unbuckle_mob(user) - user.Knockdown(60) - user.visible_message("[AM] pushes [user] off of them!") - -/datum/component/riding/cyborg - -/datum/component/riding/cyborg/ride_check(mob/user) - var/atom/movable/AM = parent - if(user.incapacitated()) - var/kick = TRUE - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(R.module && R.module.ride_allow_incapacitated) - kick = FALSE - if(kick) - to_chat(user, "You fall off of [AM]!") - Unbuckle(user) - return - if(iscarbon(user)) - var/mob/living/carbon/carbonuser = user - if(!carbonuser.get_num_arms()) - Unbuckle(user) - to_chat(user, "You can't grab onto [AM] with no hands!") - return - -/datum/component/riding/cyborg/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) - return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) - -/datum/component/riding/cyborg/handle_vehicle_offsets() - var/atom/movable/AM = parent - if(AM.has_buckled_mobs()) - for(var/mob/living/M in AM.buckled_mobs) - M.setDir(AM.dir) - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(istype(R.module)) - M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] - M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] - else - ..() - -/datum/component/riding/cyborg/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - var/turf/target = get_edge_target_turf(AM, AM.dir) - var/turf/targetm = get_step(get_turf(AM), AM.dir) - M.Move(targetm) - M.visible_message("[M] is thrown clear of [AM]!") - M.throw_at(target, 14, 5, AM) - M.Knockdown(60) - -/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1) - var/atom/movable/AM = parent - var/amount_equipped = 0 - for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) - var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user) - inhand.rider = user - inhand.parent = AM - if(user.put_in_hands(inhand, TRUE)) - amount_equipped++ - else - break - if(amount_equipped >= amount_required) - return TRUE - else - unequip_buckle_inhands(user) - return FALSE - -/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) - var/atom/movable/AM = parent - for(var/obj/item/riding_offhand/O in user.contents) - if(O.parent != AM) - CRASH("RIDING OFFHAND ON WRONG MOB") - continue - if(O.selfdeleting) - continue - else - qdel(O) - return TRUE - -/obj/item/riding_offhand - name = "offhand" - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "offhand" - w_class = WEIGHT_CLASS_HUGE - flags_1 = ABSTRACT_1 | DROPDEL_1 | NOBLUDGEON_1 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/mob/living/carbon/rider - var/mob/living/parent - var/selfdeleting = FALSE - -/obj/item/riding_offhand/dropped() - selfdeleting = TRUE - . = ..() - -/obj/item/riding_offhand/equipped() - if(loc != rider) - selfdeleting = TRUE - qdel(src) - . = ..() - -/obj/item/riding_offhand/Destroy() - var/atom/movable/AM = parent - if(selfdeleting) - if(rider in AM.buckled_mobs) - AM.unbuckle_mob(rider) - . = ..() +/datum/component/riding + var/next_vehicle_move = 0 //used for move delays + var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower + var/keytype + + var/slowed = FALSE + var/slowvalue = 1 + + var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. + var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. + var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) + var/list/allowed_turf_typecache + var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. + var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. + var/override_allow_spacemove = FALSE + var/drive_verb = "drive" + var/ride_check_rider_incapacitated = FALSE + var/ride_check_rider_restrained = FALSE + var/ride_check_ridden_incapacitated = FALSE + +/datum/component/riding/Initialize() + if(!ismovableatom(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("RIDING COMPONENT ASSIGNED TO NON ATOM MOVABLE!") + RegisterSignal(COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) + RegisterSignal(COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) + RegisterSignal(COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) + +/datum/component/riding/proc/vehicle_mob_unbuckle(mob/living/M, force = FALSE) + restore_position(M) + unequip_buckle_inhands(M) + +/datum/component/riding/proc/vehicle_mob_buckle(mob/living/M, force = FALSE) + handle_vehicle_offsets() + +/datum/component/riding/proc/handle_vehicle_layer() + var/atom/movable/AM = parent + var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) + . = defaults["[AM.dir]"] + if(directional_vehicle_layers["[AM.dir]"]) + . = directional_vehicle_layers["[AM.dir]"] + if(isnull(.)) //you can set it to null to not change it. + . = AM.layer + AM.layer = . + +/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) + directional_vehicle_layers["[dir]"] = layer + +/datum/component/riding/proc/vehicle_moved() + var/atom/movable/AM = parent + for(var/i in AM.buckled_mobs) + ride_check(i) + handle_vehicle_offsets() + handle_vehicle_layer() + +/datum/component/riding/proc/ride_check(mob/living/M) + var/atom/movable/AM = parent + var/mob/AMM = AM + if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) + AM.visible_message("[M] falls off of [AM]!") + AM.unbuckle_mob(M) + return TRUE + +/datum/component/riding/proc/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + +/datum/component/riding/proc/handle_vehicle_offsets() + var/atom/movable/AM = parent + var/AM_dir = "[AM.dir]" + var/passindex = 0 + if(AM.has_buckled_mobs()) + for(var/m in AM.buckled_mobs) + passindex++ + var/mob/living/buckled_mob = m + var/list/offsets = get_offsets(passindex) + var/rider_dir = get_rider_dir(passindex) + buckled_mob.setDir(rider_dir) + dir_loop: + for(var/offsetdir in offsets) + if(offsetdir == AM_dir) + var/list/diroffsets = offsets[offsetdir] + buckled_mob.pixel_x = diroffsets[1] + if(diroffsets.len >= 2) + buckled_mob.pixel_y = diroffsets[2] + if(diroffsets.len == 3) + buckled_mob.layer = diroffsets[3] + break dir_loop + var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + var/px = default_vehicle_pixel_offsets[AM_dir] + var/py = default_vehicle_pixel_offsets[AM_dir] + if(directional_vehicle_offsets[AM_dir]) + if(isnull(directional_vehicle_offsets[AM_dir])) + px = AM.pixel_x + py = AM.pixel_y + else + px = directional_vehicle_offsets[AM_dir][1] + py = directional_vehicle_offsets[AM_dir][2] + AM.pixel_x = px + AM.pixel_y = py + +/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) + directional_vehicle_offsets["[dir]"] = list(x, y) + +//Override this to set your vehicle's various pixel offsets +/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) + . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + if(riding_offsets["[pass_index]"]) + . = riding_offsets["[pass_index]"] + else if(riding_offsets["[RIDING_OFFSET_ALL]"]) + . = riding_offsets["[RIDING_OFFSET_ALL]"] + +/datum/component/riding/proc/set_riding_offsets(index, list/offsets) + if(!islist(offsets)) + return FALSE + riding_offsets["[index]"] = offsets + +//Override this to set the passengers/riders dir based on which passenger they are. +//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. +/datum/component/riding/proc/get_rider_dir(pass_index) + var/atom/movable/AM = parent + return AM.dir + +//KEYS +/datum/component/riding/proc/keycheck(mob/user) + return !keytype || user.is_holding_item_of_type(keytype) + +//BUCKLE HOOKS +/datum/component/riding/proc/restore_position(mob/living/buckled_mob) + if(buckled_mob) + buckled_mob.pixel_x = 0 + buckled_mob.pixel_y = 0 + if(buckled_mob.client) + buckled_mob.client.change_view(CONFIG_GET(string/default_view)) + +//MOVEMENT +/datum/component/riding/proc/turf_check(turf/next, turf/current) + if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) + else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) + return TRUE + +/datum/component/riding/proc/handle_ride(mob/user, direction) + var/atom/movable/AM = parent + if(user.incapacitated()) + Unbuckle(user) + return + + if(world.time < next_vehicle_move) + return + next_vehicle_move = world.time + vehicle_move_delay + + if(keycheck(user)) + var/turf/next = get_step(AM, direction) + var/turf/current = get_turf(AM) + if(!istype(next) || !istype(current)) + return //not happening. + if(!turf_check(next, current)) + to_chat(user, "Your \the [AM] can not go onto [next]!") + return + if(!Process_Spacemove(direction) || !isturf(AM.loc)) + return + step(AM, direction) + + handle_vehicle_layer() + handle_vehicle_offsets() + else + to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") + +/datum/component/riding/proc/Unbuckle(atom/movable/M) + addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) + +/datum/component/riding/proc/Process_Spacemove(direction) + var/atom/movable/AM = parent + return override_allow_spacemove || AM.has_gravity() + +/datum/component/riding/proc/account_limbs(mob/living/M) + if(M.get_num_legs() < 2 && !slowed) + vehicle_move_delay = vehicle_move_delay + slowvalue + slowed = TRUE + else if(slowed) + vehicle_move_delay = vehicle_move_delay - slowvalue + slowed = FALSE + +///////Yes, I said humans. No, this won't end well...////////// +/datum/component/riding/human + +/datum/component/riding/human/Initialize() + . = ..() + RegisterSignal(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) + +/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) + var/mob/living/carbon/human/AM = parent + if(AM.a_intent == INTENT_DISARM && (target in AM.buckled_mobs)) + force_dismount(target) + +/datum/component/riding/human/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/human/force_dismount(mob/living/user) + var/atom/movable/AM = parent + AM.unbuckle_mob(user) + user.Knockdown(60) + user.visible_message("[AM] pushes [user] off of them!") + +/datum/component/riding/cyborg + +/datum/component/riding/cyborg/ride_check(mob/user) + var/atom/movable/AM = parent + if(user.incapacitated()) + var/kick = TRUE + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(R.module && R.module.ride_allow_incapacitated) + kick = FALSE + if(kick) + to_chat(user, "You fall off of [AM]!") + Unbuckle(user) + return + if(iscarbon(user)) + var/mob/living/carbon/carbonuser = user + if(!carbonuser.get_num_arms()) + Unbuckle(user) + to_chat(user, "You can't grab onto [AM] with no hands!") + return + +/datum/component/riding/cyborg/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) + return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) + +/datum/component/riding/cyborg/handle_vehicle_offsets() + var/atom/movable/AM = parent + if(AM.has_buckled_mobs()) + for(var/mob/living/M in AM.buckled_mobs) + M.setDir(AM.dir) + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(istype(R.module)) + M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] + M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] + else + ..() + +/datum/component/riding/cyborg/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + var/turf/target = get_edge_target_turf(AM, AM.dir) + var/turf/targetm = get_step(get_turf(AM), AM.dir) + M.Move(targetm) + M.visible_message("[M] is thrown clear of [AM]!") + M.throw_at(target, 14, 5, AM) + M.Knockdown(60) + +/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1) + var/atom/movable/AM = parent + var/amount_equipped = 0 + for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) + var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user) + inhand.rider = user + inhand.parent = AM + if(user.put_in_hands(inhand, TRUE)) + amount_equipped++ + else + break + if(amount_equipped >= amount_required) + return TRUE + else + unequip_buckle_inhands(user) + return FALSE + +/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) + var/atom/movable/AM = parent + for(var/obj/item/riding_offhand/O in user.contents) + if(O.parent != AM) + CRASH("RIDING OFFHAND ON WRONG MOB") + continue + if(O.selfdeleting) + continue + else + qdel(O) + return TRUE + +/obj/item/riding_offhand + name = "offhand" + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "offhand" + w_class = WEIGHT_CLASS_HUGE + flags_1 = ABSTRACT_1 | DROPDEL_1 | NOBLUDGEON_1 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + var/mob/living/carbon/rider + var/mob/living/parent + var/selfdeleting = FALSE + +/obj/item/riding_offhand/dropped() + selfdeleting = TRUE + . = ..() + +/obj/item/riding_offhand/equipped() + if(loc != rider) + selfdeleting = TRUE + qdel(src) + . = ..() + +/obj/item/riding_offhand/Destroy() + var/atom/movable/AM = parent + if(selfdeleting) + if(rider in AM.buckled_mobs) + AM.unbuckle_mob(rider) + . = ..() diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 407965aeb9..175ac9469c 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -1,204 +1,204 @@ -GLOBAL_LIST_EMPTY(uplinks) - -/** - * Uplinks - * - * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.' - * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink. - * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it. -**/ -/datum/component/uplink - dupe_mode = COMPONENT_DUPE_UNIQUE - var/name = "syndicate uplink" - var/active = FALSE - var/lockable = TRUE - var/locked = TRUE - var/telecrystals - var/selected_cat - var/owner = null - var/datum/game_mode/gamemode - var/spent_telecrystals = 0 - var/datum/uplink_purchase_log/purchase_log - var/list/uplink_items - var/hidden_crystals = 0 - -/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - GLOB.uplinks += src - uplink_items = get_uplink_items(gamemode) - RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) - RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/interact) - owner = _owner - if(owner) - LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) - if(GLOB.uplink_purchase_logs_by_key[owner]) - purchase_log = GLOB.uplink_purchase_logs_by_key[owner] - else - purchase_log = new(owner, src) - lockable = _lockable - active = _enabled - gamemode = _gamemode - telecrystals = starting_tc - if(!lockable) - active = TRUE - locked = FALSE - -/datum/component/uplink/InheritComponent(datum/component/uplink/U) - lockable |= U.lockable - active |= U.active - if(!gamemode) - gamemode = U.gamemode - telecrystals += U.telecrystals - if(purchase_log && U.purchase_log) - purchase_log.MergeWithAndDel(U.purchase_log) - -/datum/component/uplink/Destroy() - GLOB.uplinks -= src - gamemode = null - return ..() - -/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE) - if(!silent) - to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.") - var/amt = TC.amount - telecrystals += amt - TC.use(amt) - -/datum/component/uplink/proc/set_gamemode(_gamemode) - gamemode = _gamemode - uplink_items = get_uplink_items(gamemode) - -/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user) - if(!active) - return //no hitting everyone/everything just to try to slot tcs in! - if(istype(I, /obj/item/stack/telecrystal)) - LoadTC(user, I) - for(var/item in subtypesof(/datum/uplink_item)) - var/datum/uplink_item/UI = item - var/path = null - if(initial(UI.refund_path)) - path = initial(UI.refund_path) - else - path = initial(UI.item) - var/cost = 0 - if(initial(UI.refund_amount)) - cost = initial(UI.refund_amount) - else - cost = initial(UI.cost) - var/refundable = initial(UI.refundable) - if(I.type == path && refundable && I.check_uplink_validity()) - telecrystals += cost - spent_telecrystals -= cost - to_chat(user, "[I] refunded.") - qdel(I) - return - -/datum/component/uplink/proc/interact(mob/user) - if(locked) - return - active = TRUE - if(user) - ui_interact(user) - -/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) - active = TRUE - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state) - ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. - ui.set_style("syndicate") - ui.open() - -/datum/component/uplink/ui_data(mob/user) - if(!user.mind) - return - var/list/data = list() - data["telecrystals"] = telecrystals - data["lockable"] = lockable - - data["categories"] = list() - for(var/category in uplink_items) - var/list/cat = list( - "name" = category, - "items" = (category == selected_cat ? list() : null)) - if(category == selected_cat) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(I.limited_stock == 0) - continue - if(I.restricted_roles.len) - var/is_inaccessible = 1 - for(var/R in I.restricted_roles) - if(R == user.mind.assigned_role) - is_inaccessible = 0 - if(is_inaccessible) - continue - cat["items"] += list(list( - "name" = I.name, - "cost" = I.cost, - "desc" = I.desc, - )) - data["categories"] += list(cat) - return data - -/datum/component/uplink/ui_act(action, params) - if(!active) - return - - switch(action) - if("buy") - var/item = params["item"] - - var/list/buyable_items = list() - for(var/category in uplink_items) - buyable_items += uplink_items[category] - - if(item in buyable_items) - var/datum/uplink_item/I = buyable_items[item] - MakePurchase(usr, I) - . = TRUE - if("lock") - active = FALSE - locked = TRUE - telecrystals += hidden_crystals - hidden_crystals = 0 - SStgui.close_uis(src) - if("select") - selected_cat = params["category"] - return TRUE - -/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U) - if(!istype(U)) - return - if (!user || user.incapacitated()) - return - - if(telecrystals < U.cost || U.limited_stock == 0) - return - telecrystals -= U.cost - - var/atom/A = U.spawn_item(get_turf(user), src, user) - if(U.purchase_log_vis && purchase_log) - var/obj/item/storage/box/B = A - var/list/atom/logging = list() - if(istype(B) && B.contents.len > 0) - logging |= list(B) - else - logging |= A - for(var/atom/_logging in logging) - purchase_log.LogPurchase(_logging, U.cost) - - if(U.limited_stock > 0) - U.limited_stock -= 1 - - SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]")) - if(ishuman(user) && istype(A, /obj/item)) - var/mob/living/carbon/human/H = user - if(H.put_in_hands(A)) - to_chat(H, "[A] materializes into your hands!") - else - to_chat(H, "\The [A] materializes onto the floor.") - return TRUE - +GLOBAL_LIST_EMPTY(uplinks) + +/** + * Uplinks + * + * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.' + * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink. + * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it. +**/ +/datum/component/uplink + dupe_mode = COMPONENT_DUPE_UNIQUE + var/name = "syndicate uplink" + var/active = FALSE + var/lockable = TRUE + var/locked = TRUE + var/telecrystals + var/selected_cat + var/owner = null + var/datum/game_mode/gamemode + var/spent_telecrystals = 0 + var/datum/uplink_purchase_log/purchase_log + var/list/uplink_items + var/hidden_crystals = 0 + +/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + GLOB.uplinks += src + uplink_items = get_uplink_items(gamemode) + RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) + RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/interact) + owner = _owner + if(owner) + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) + if(GLOB.uplink_purchase_logs_by_key[owner]) + purchase_log = GLOB.uplink_purchase_logs_by_key[owner] + else + purchase_log = new(owner, src) + lockable = _lockable + active = _enabled + gamemode = _gamemode + telecrystals = starting_tc + if(!lockable) + active = TRUE + locked = FALSE + +/datum/component/uplink/InheritComponent(datum/component/uplink/U) + lockable |= U.lockable + active |= U.active + if(!gamemode) + gamemode = U.gamemode + telecrystals += U.telecrystals + if(purchase_log && U.purchase_log) + purchase_log.MergeWithAndDel(U.purchase_log) + +/datum/component/uplink/Destroy() + GLOB.uplinks -= src + gamemode = null + return ..() + +/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE) + if(!silent) + to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.") + var/amt = TC.amount + telecrystals += amt + TC.use(amt) + +/datum/component/uplink/proc/set_gamemode(_gamemode) + gamemode = _gamemode + uplink_items = get_uplink_items(gamemode) + +/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user) + if(!active) + return //no hitting everyone/everything just to try to slot tcs in! + if(istype(I, /obj/item/stack/telecrystal)) + LoadTC(user, I) + for(var/item in subtypesof(/datum/uplink_item)) + var/datum/uplink_item/UI = item + var/path = null + if(initial(UI.refund_path)) + path = initial(UI.refund_path) + else + path = initial(UI.item) + var/cost = 0 + if(initial(UI.refund_amount)) + cost = initial(UI.refund_amount) + else + cost = initial(UI.cost) + var/refundable = initial(UI.refundable) + if(I.type == path && refundable && I.check_uplink_validity()) + telecrystals += cost + spent_telecrystals -= cost + to_chat(user, "[I] refunded.") + qdel(I) + return + +/datum/component/uplink/proc/interact(mob/user) + if(locked) + return + active = TRUE + if(user) + ui_interact(user) + +/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) + active = TRUE + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state) + ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. + ui.set_style("syndicate") + ui.open() + +/datum/component/uplink/ui_data(mob/user) + if(!user.mind) + return + var/list/data = list() + data["telecrystals"] = telecrystals + data["lockable"] = lockable + + data["categories"] = list() + for(var/category in uplink_items) + var/list/cat = list( + "name" = category, + "items" = (category == selected_cat ? list() : null)) + if(category == selected_cat) + for(var/item in uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + if(I.limited_stock == 0) + continue + if(I.restricted_roles.len) + var/is_inaccessible = 1 + for(var/R in I.restricted_roles) + if(R == user.mind.assigned_role) + is_inaccessible = 0 + if(is_inaccessible) + continue + cat["items"] += list(list( + "name" = I.name, + "cost" = I.cost, + "desc" = I.desc, + )) + data["categories"] += list(cat) + return data + +/datum/component/uplink/ui_act(action, params) + if(!active) + return + + switch(action) + if("buy") + var/item = params["item"] + + var/list/buyable_items = list() + for(var/category in uplink_items) + buyable_items += uplink_items[category] + + if(item in buyable_items) + var/datum/uplink_item/I = buyable_items[item] + MakePurchase(usr, I) + . = TRUE + if("lock") + active = FALSE + locked = TRUE + telecrystals += hidden_crystals + hidden_crystals = 0 + SStgui.close_uis(src) + if("select") + selected_cat = params["category"] + return TRUE + +/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U) + if(!istype(U)) + return + if (!user || user.incapacitated()) + return + + if(telecrystals < U.cost || U.limited_stock == 0) + return + telecrystals -= U.cost + + var/atom/A = U.spawn_item(get_turf(user), src, user) + if(U.purchase_log_vis && purchase_log) + var/obj/item/storage/box/B = A + var/list/atom/logging = list() + if(istype(B) && B.contents.len > 0) + logging |= list(B) + else + logging |= A + for(var/atom/_logging in logging) + purchase_log.LogPurchase(_logging, U.cost) + + if(U.limited_stock > 0) + U.limited_stock -= 1 + + SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]")) + if(ishuman(user) && istype(A, /obj/item)) + var/mob/living/carbon/human/H = user + if(H.put_in_hands(A)) + to_chat(H, "[A] materializes into your hands!") + else + to_chat(H, "\The [A] materializes onto the floor.") + return TRUE + diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 1cf172d3a6..b086854ab6 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -897,6 +897,9 @@ to_chat(user,"[src] suddenly vanishes!") qdel(src) +/obj/item/spellbook/oneuse/random + icon_state = "random_book" + /obj/item/spellbook/oneuse/random/Initialize() ..() var/static/banned_spells = list(/obj/item/spellbook/oneuse/mimery_blockade, /obj/item/spellbook/oneuse/mimery_guns) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index e889a5d96f..eb51703642 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -678,6 +678,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/machinery/vending/snack/random name = "\improper Random Snackies" + icon_state = "random_snack" desc = "Uh oh!" /obj/machinery/vending/snack/random/Initialize() @@ -730,6 +731,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/machinery/vending/cola/random name = "\improper Random Drinkies" + icon_state = "random_cola" desc = "Uh oh!" /obj/machinery/vending/cola/random/Initialize() diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 8ec32f088e..a3ad685406 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -25,9 +25,11 @@ /obj/item/lipstick/random name = "lipstick" + icon_state = "random_lipstick" /obj/item/lipstick/random/New() ..() + icon_state = "lipstick" colour = pick("red","purple","lime","black","green","blue","white") name = "[colour] lipstick" diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index fd56c6283f..a7b0eaaf25 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -488,16 +488,14 @@ /obj/item/device/flashlight/glowstick/random name = "random colored glowstick" + icon_state = "random_glowstick" + color = null /obj/item/device/flashlight/glowstick/random/Initialize() - var/list/glowtypes = typesof(/obj/item/device/flashlight/glowstick) - glowtypes -= /obj/item/device/flashlight/glowstick/random - - var/obj/item/device/flashlight/glowstick/glowtype = pick(glowtypes) - - name = initial(glowtype.name) - color = initial(glowtype.color) . = ..() + var/T = pick(typesof(/obj/item/device/flashlight/glowstick) - /obj/item/device/flashlight/glowstick/random) + new T(loc) + return INITIALIZE_HINT_QDEL /obj/item/device/flashlight/spotlight //invisible lighting source name = "disco light" diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 912a083171..69b6e54841 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -289,6 +289,9 @@ fix() //Random colour tapes +/obj/item/device/tape/random + icon_state = "random_tape" + /obj/item/device/tape/random/New() icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]" ..() diff --git a/code/game/objects/items/devices/uplink_devices.dm b/code/game/objects/items/devices/uplink_devices.dm index 3f3970fe51..2541b33e27 100644 --- a/code/game/objects/items/devices/uplink_devices.dm +++ b/code/game/objects/items/devices/uplink_devices.dm @@ -1,31 +1,31 @@ - -// A collection of pre-set uplinks, for admin spawns. -/obj/item/device/radio/uplink/Initialize(mapload, _owner, _tc_amount = 20) - . = ..() - icon_state = "radio" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - LoadComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) - -/obj/item/device/radio/uplink/nuclear/Initialize() - . = ..() - GET_COMPONENT(hidden_uplink, /datum/component/uplink) - hidden_uplink.set_gamemode(/datum/game_mode/nuclear) - -/obj/item/device/multitool/uplink/Initialize(mapload, _owner, _tc_amount = 20) - . = ..() - LoadComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) - -/obj/item/pen/uplink/Initialize(mapload, _owner, _tc_amount = 20) - . = ..() - LoadComponent(/datum/component/uplink) - traitor_unlock_degrees = 360 - -/obj/item/device/radio/uplink/old - name = "dusty radio" - desc = "A dusty looking radio." - -/obj/item/device/radio/uplink/old/Initialize(mapload, _owner, _tc_amount = 10) - . = ..() - GET_COMPONENT(hidden_uplink, /datum/component/uplink) - hidden_uplink.name = "dusty radio" + +// A collection of pre-set uplinks, for admin spawns. +/obj/item/device/radio/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + icon_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + LoadComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) + +/obj/item/device/radio/uplink/nuclear/Initialize() + . = ..() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + hidden_uplink.set_gamemode(/datum/game_mode/nuclear) + +/obj/item/device/multitool/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + LoadComponent(/datum/component/uplink, _owner, FALSE, TRUE, null, _tc_amount) + +/obj/item/pen/uplink/Initialize(mapload, _owner, _tc_amount = 20) + . = ..() + LoadComponent(/datum/component/uplink) + traitor_unlock_degrees = 360 + +/obj/item/device/radio/uplink/old + name = "dusty radio" + desc = "A dusty looking radio." + +/obj/item/device/radio/uplink/old/Initialize(mapload, _owner, _tc_amount = 10) + . = ..() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + hidden_uplink.name = "dusty radio" diff --git a/code/game/objects/items/grenades/clusterbuster.dm b/code/game/objects/items/grenades/clusterbuster.dm index 9f2cb1ab88..167c3114ec 100644 --- a/code/game/objects/items/grenades/clusterbuster.dm +++ b/code/game/objects/items/grenades/clusterbuster.dm @@ -129,6 +129,9 @@ //random clusterbuster spawner +/obj/item/grenade/clusterbuster/random + icon_state = "random_clusterbang" + /obj/item/grenade/clusterbuster/random/New() var/real_type = pick(subtypesof(/obj/item/grenade/clusterbuster)) new real_type(loc) diff --git a/code/game/objects/items/implants/implantuplink.dm b/code/game/objects/items/implants/implantuplink.dm index 5365f71ca7..d1d5adf4b5 100644 --- a/code/game/objects/items/implants/implantuplink.dm +++ b/code/game/objects/items/implants/implantuplink.dm @@ -1,49 +1,49 @@ -/obj/item/implant/uplink - name = "uplink implant" - desc = "Sneeki breeki." - icon = 'icons/obj/radio.dmi' - icon_state = "radio" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - var/starting_tc = 0 - -/obj/item/implant/uplink/Initialize(mapload, _owner) - . = ..() - LoadComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc) - -/obj/item/implant/uplink/implant(mob/living/target, mob/user, silent = 0) - GET_COMPONENT(hidden_uplink, /datum/component/uplink) - if(hidden_uplink) - for(var/X in target.implants) - if(istype(X, type)) - var/obj/item/implant/imp_e = X - GET_COMPONENT_FROM(their_hidden_uplink, /datum/component/uplink, imp_e) - if(their_hidden_uplink) - their_hidden_uplink.telecrystals += hidden_uplink.telecrystals - qdel(src) - return TRUE - else - qdel(imp_e) //INFERIOR AND EMPTY! - - if(..()) - if(hidden_uplink) - hidden_uplink.owner = "[user.key]" - return TRUE - return FALSE - -/obj/item/implant/uplink/activate() - GET_COMPONENT(hidden_uplink, /datum/component/uplink) - if(hidden_uplink) - hidden_uplink.locked = FALSE - hidden_uplink.interact(usr) - -/obj/item/implanter/uplink - name = "implanter (uplink)" - imp_type = /obj/item/implant/uplink - -/obj/item/implanter/uplink/precharged - name = "implanter (precharged uplink)" - imp_type = /obj/item/implant/uplink/precharged - -/obj/item/implant/uplink/precharged - starting_tc = 10 +/obj/item/implant/uplink + name = "uplink implant" + desc = "Sneeki breeki." + icon = 'icons/obj/radio.dmi' + icon_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + var/starting_tc = 0 + +/obj/item/implant/uplink/Initialize(mapload, _owner) + . = ..() + LoadComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc) + +/obj/item/implant/uplink/implant(mob/living/target, mob/user, silent = 0) + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + if(hidden_uplink) + for(var/X in target.implants) + if(istype(X, type)) + var/obj/item/implant/imp_e = X + GET_COMPONENT_FROM(their_hidden_uplink, /datum/component/uplink, imp_e) + if(their_hidden_uplink) + their_hidden_uplink.telecrystals += hidden_uplink.telecrystals + qdel(src) + return TRUE + else + qdel(imp_e) //INFERIOR AND EMPTY! + + if(..()) + if(hidden_uplink) + hidden_uplink.owner = "[user.key]" + return TRUE + return FALSE + +/obj/item/implant/uplink/activate() + GET_COMPONENT(hidden_uplink, /datum/component/uplink) + if(hidden_uplink) + hidden_uplink.locked = FALSE + hidden_uplink.interact(usr) + +/obj/item/implanter/uplink + name = "implanter (uplink)" + imp_type = /obj/item/implant/uplink + +/obj/item/implanter/uplink/precharged + name = "implanter (precharged uplink)" + imp_type = /obj/item/implant/uplink/precharged + +/obj/item/implant/uplink/precharged + starting_tc = 10 diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 7747c3843d..885dbc3830 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -72,6 +72,9 @@ else return ..() +/obj/item/storage/wallet/random + icon_state = "random_wallet" + /obj/item/storage/wallet/random/PopulateContents() var/item1_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500) var/item2_type @@ -86,3 +89,4 @@ new item2_type(src) if(item3_type) new item3_type(src) + update_icon() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 238c83725b..aa9acae22c 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -225,7 +225,7 @@ LINEN BINS /obj/item/bedsheet/random - icon_state = "sheetrainbow" + icon_state = "random_bedsheet" item_color = "rainbow" name = "random bedsheet" desc = "If you're reading this description ingame, something has gone wrong! Honk!" diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 260285aff9..f7071cd0a5 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -285,10 +285,13 @@ user.remove_alt_appearance("sneaking_mission") /obj/item/twohanded/required/kirbyplants/random + icon = 'icons/obj/flora/_flora.dmi' + icon_state = "random_plant" var/list/static/states /obj/item/twohanded/required/kirbyplants/random/Initialize() . = ..() + icon = 'icons/obj/flora/plants.dmi' if(!states) generate_states() icon_state = pick(states) diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index e3a99fdb9a..b2b869edae 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -8,7 +8,8 @@ /obj/item/clothing/glasses/meson/engine name = "engineering scanner goggles" desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode let's you see objects contaminated by radiation." - icon_state = "trayson" + icon_state = "trayson-meson" + item_state = "trayson-meson" actions_types = list(/datum/action/item_action/toggle_mode) origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3" @@ -117,14 +118,22 @@ flick_overlay(pic, list(user.client), 8) /obj/item/clothing/glasses/meson/engine/update_icon() - icon_state = "[initial(icon_state)]-[mode]" - if(istype(loc, /mob/living/carbon/human/)) - var/mob/living/carbon/human/user = loc - if(user.glasses == src) + icon_state = "trayson-[mode]" + update_mob() + +/obj/item/clothing/glasses/meson/engine/proc/update_mob() + item_state = icon_state + if(isliving(loc)) + var/mob/living/user = loc + if(user.get_item_by_slot(slot_glasses) == src) user.update_inv_glasses() + else + user.update_inv_hands() /obj/item/clothing/glasses/meson/engine/tray //atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves name = "optical t-ray scanner" + icon_state = "trayson-t-ray" + item_state = "trayson-t-ray" desc = "Used by engineering staff to see underfloor objects such as cables and pipes." origin_tech = "materials=3;magnets=2;engineering=2" diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 8b714f25dd..257318ce80 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -188,7 +188,7 @@ /obj/item/clothing/gloves/color/random name = "random gloves" desc = "These gloves are supposed to be a random color..." - icon_state = "white" + icon_state = "random_gloves" item_state = "wgloves" item_color = "mime" diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 141336cf5d..4bf76a1a46 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -58,6 +58,7 @@ /obj/structure/beebox/premade/New() ..() + icon_state = "beebox" var/datum/reagent/R = null if(random_reagent) R = pick(subtypesof(/datum/reagent)) @@ -80,6 +81,7 @@ /obj/structure/beebox/premade/random + icon_state = "random_beebox" random_reagent = TRUE diff --git a/code/modules/library/random_books.dm b/code/modules/library/random_books.dm index 769c9ac66b..e101a7143a 100644 --- a/code/modules/library/random_books.dm +++ b/code/modules/library/random_books.dm @@ -1,3 +1,6 @@ +/obj/item/book/manual/random + icon_state = "random_book" + /obj/item/book/manual/random/Initialize() ..() var/static/banned_books = list(/obj/item/book/manual/random, /obj/item/book/manual/nuclear, /obj/item/book/manual/wiki) @@ -6,6 +9,7 @@ return INITIALIZE_HINT_QDEL /obj/item/book/random + icon_state = "random_book" var/amount = 1 var/category = null @@ -20,6 +24,7 @@ /obj/structure/bookcase/random var/category = null var/book_count = 2 + icon_state = "random_bookcase" anchored = TRUE state = 2 diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index a1f0dbf4be..5c24b15267 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -1,21 +1,21 @@ -/mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) - if(ionpulse()) - return 1 - return ..() - -/mob/living/silicon/robot/movement_delay() - . = ..() - var/static/config_robot_delay - if(isnull(config_robot_delay)) - config_robot_delay = CONFIG_GET(number/robot_delay) - . += speed + config_robot_delay - -/mob/living/silicon/robot/mob_negates_gravity() - return magpulse - -/mob/living/silicon/robot/mob_has_gravity() - return ..() || mob_negates_gravity() - -/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) - if(!magpulse) - return ..() +/mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) + if(ionpulse()) + return 1 + return ..() + +/mob/living/silicon/robot/movement_delay() + . = ..() + var/static/config_robot_delay + if(isnull(config_robot_delay)) + config_robot_delay = CONFIG_GET(number/robot_delay) + . += speed + config_robot_delay + +/mob/living/silicon/robot/mob_negates_gravity() + return magpulse + +/mob/living/silicon/robot/mob_has_gravity() + return ..() || mob_negates_gravity() + +/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) + if(!magpulse) + return ..() diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index a4d766539f..bc92521b93 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -40,6 +40,9 @@ if(51 to INFINITY) icon_state = "full" +/obj/item/reagent_containers/blood/random + icon_state = "random_bloodpack" + /obj/item/reagent_containers/blood/random/Initialize() blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L") . = ..() diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index ea3a05470a..32975e1e0f 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -1,76 +1,76 @@ -/obj/vehicle/ridden - name = "ridden vehicle" - can_buckle = TRUE - max_buckled_mobs = 1 - buckle_lying = FALSE - default_driver_move = FALSE - var/legs_required = 2 - var/arms_requires = 0 //why not? - -/obj/vehicle/ridden/Initialize() - . = ..() - LoadComponent(/datum/component/riding) - -/obj/vehicle/ridden/examine(mob/user) - . = ..() - to_chat(user, "Put a key inside it by clicking it with the key. If there's a key inside, you can remove it via Alt-Click!") - -/obj/vehicle/ridden/generate_action_type(actiontype) - var/datum/action/vehicle/ridden/A = ..() - . = A - if(istype(A)) - A.vehicle_ridden_target = src - -/obj/vehicle/ridden/post_unbuckle_mob(mob/living/M) - remove_occupant(M) - return ..() - -/obj/vehicle/ridden/post_buckle_mob(mob/living/M) - add_occupant(M) - return ..() - -/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) - if(key_type && !is_key(inserted_key) && is_key(I)) - if(user.transferItemToLoc(I, src)) - to_chat(user, "You insert \the [I] into \the [src].") - if(inserted_key) //just in case there's an invalid key - inserted_key.forceMove(drop_location()) - inserted_key = I - else - to_chat(user, "[I] seems to be stuck to your hand!") - return - return ..() - -/obj/vehicle/ridden/AltClick(mob/user) - if(user.Adjacent(src) && inserted_key) - if(!is_occupant(user)) - to_chat(user, "You must be riding the [src] to remove [src]'s key!") - return - to_chat(user, "You remove \the [inserted_key] from \the [src].") - inserted_key.forceMove(drop_location()) - user.put_in_hands(inserted_key) - inserted_key = null - return ..() - -/obj/vehicle/ridden/driver_move(mob/user, direction) - if(key_type && !is_key(inserted_key)) - to_chat(user, "[src] has no key inserted!") - return FALSE - var/datum/component/riding/R = GetComponent(/datum/component/riding) - R.handle_ride(user, direction) - return ..() - -/obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) - if(user.incapacitated()) - return - for(var/atom/movable/A in get_turf(src)) - if(A.density) - if(A != src && A != M) - return - M.forceMove(get_turf(src)) - . = ..() - -/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) - if(!force && occupant_amount() >= max_occupants) - return FALSE - return ..() +/obj/vehicle/ridden + name = "ridden vehicle" + can_buckle = TRUE + max_buckled_mobs = 1 + buckle_lying = FALSE + default_driver_move = FALSE + var/legs_required = 2 + var/arms_requires = 0 //why not? + +/obj/vehicle/ridden/Initialize() + . = ..() + LoadComponent(/datum/component/riding) + +/obj/vehicle/ridden/examine(mob/user) + . = ..() + to_chat(user, "Put a key inside it by clicking it with the key. If there's a key inside, you can remove it via Alt-Click!") + +/obj/vehicle/ridden/generate_action_type(actiontype) + var/datum/action/vehicle/ridden/A = ..() + . = A + if(istype(A)) + A.vehicle_ridden_target = src + +/obj/vehicle/ridden/post_unbuckle_mob(mob/living/M) + remove_occupant(M) + return ..() + +/obj/vehicle/ridden/post_buckle_mob(mob/living/M) + add_occupant(M) + return ..() + +/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) + if(key_type && !is_key(inserted_key) && is_key(I)) + if(user.transferItemToLoc(I, src)) + to_chat(user, "You insert \the [I] into \the [src].") + if(inserted_key) //just in case there's an invalid key + inserted_key.forceMove(drop_location()) + inserted_key = I + else + to_chat(user, "[I] seems to be stuck to your hand!") + return + return ..() + +/obj/vehicle/ridden/AltClick(mob/user) + if(user.Adjacent(src) && inserted_key) + if(!is_occupant(user)) + to_chat(user, "You must be riding the [src] to remove [src]'s key!") + return + to_chat(user, "You remove \the [inserted_key] from \the [src].") + inserted_key.forceMove(drop_location()) + user.put_in_hands(inserted_key) + inserted_key = null + return ..() + +/obj/vehicle/ridden/driver_move(mob/user, direction) + if(key_type && !is_key(inserted_key)) + to_chat(user, "[src] has no key inserted!") + return FALSE + var/datum/component/riding/R = GetComponent(/datum/component/riding) + R.handle_ride(user, direction) + return ..() + +/obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) + if(user.incapacitated()) + return + for(var/atom/movable/A in get_turf(src)) + if(A.density) + if(A != src && A != M) + return + M.forceMove(get_turf(src)) + . = ..() + +/obj/vehicle/ridden/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) + if(!force && occupant_amount() >= max_occupants) + return FALSE + return ..() diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm index 79a24c8b11..865834495f 100644 --- a/code/modules/vehicles/vehicle_actions.dm +++ b/code/modules/vehicles/vehicle_actions.dm @@ -1,112 +1,112 @@ -//VEHICLE DEFAULT HANDLING -/obj/vehicle/proc/generate_actions() - return - -/obj/vehicle/proc/generate_action_type(actiontype) - var/datum/action/vehicle/A = new actiontype - if(!istype(A)) - return - A.vehicle_target = src - return A - -/obj/vehicle/proc/initialize_passenger_action_type(actiontype) - autogrant_actions_passenger += actiontype - for(var/i in occupants) - grant_passenger_actions(i) //refresh - -/obj/vehicle/proc/initialize_controller_action_type(actiontype, control_flag) - LAZYINITLIST(autogrant_actions_controller["[control_flag]"]) - autogrant_actions_controller["[control_flag]"] += actiontype - for(var/i in occupants) - grant_controller_actions(i) //refresh - -/obj/vehicle/proc/grant_action_type_to_mob(actiontype, mob/m) - if(!occupants[m] || !actiontype) - return FALSE - LAZYINITLIST(occupant_actions[m]) - if(occupant_actions[m][actiontype]) - return TRUE - var/datum/action/action = generate_action_type(actiontype) - action.Grant(m) - occupant_actions[m][action.type] = action - return TRUE - -/obj/vehicle/proc/remove_action_type_from_mob(actiontype, mob/m) - if(!occupants[m] || !actiontype) - return FALSE - LAZYINITLIST(occupant_actions[m]) - if(occupant_actions[m][actiontype]) - var/datum/action/action = occupant_actions[m][actiontype] - action.Remove(m) - occupant_actions[m] -= actiontype - return TRUE - -/obj/vehicle/proc/grant_passenger_actions(mob/M) - for(var/v in autogrant_actions_passenger) - grant_action_type_to_mob(v, M) - -/obj/vehicle/proc/remove_passenger_actions(mob/M) - for(var/v in autogrant_actions_passenger) - remove_action_type_from_mob(v, M) - -/obj/vehicle/proc/grant_controller_actions(mob/M) - if(!istype(M) || !occupants[M]) - return FALSE - for(var/i in GLOB.bitflags) - if(occupants[M] & i) - grant_controller_actions_by_flag(M, i) - return TRUE - -/obj/vehicle/proc/remove_controller_actions(mob/M) - if(!istype(M) || !occupants[M]) - return FALSE - for(var/i in GLOB.bitflags) - remove_controller_actions_by_flag(M, i) - return TRUE - -/obj/vehicle/proc/grant_controller_actions_by_flag(mob/M, flag) - if(!istype(M) || !autogrant_actions_controller["[flag]"]) - return FALSE - for(var/v in autogrant_actions_controller["[flag]"]) - grant_action_type_to_mob(v, M) - return TRUE - -/obj/vehicle/proc/remove_controller_actions_by_flag(mob/M, flag) - if(!istype(M) || autogrant_actions_controller["[flag]"]) - return FALSE - for(var/v in autogrant_actions_controller["[flag]"]) - remove_action_type_from_mob(v, M) - return TRUE - -/obj/vehicle/proc/cleanup_actions_for_mob(mob/M) - if(!istype(M)) - return FALSE - LAZYINITLIST(occupant_actions[M]) - for(var/path in occupant_actions[M]) - stack_trace("Leftover action type [path] in vehicle type [type] for mob type [M.type] - THIS SHOULD NOT BE HAPPENING!") - var/datum/action/action = occupant_actions[M] - action.Remove(M) - occupant_actions -= M - return TRUE - -//ACTION DATUMS - -/datum/action/vehicle - check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS - icon_icon = 'icons/mob/actions/actions_vehicle.dmi' - button_icon_state = "vehicle_eject" - var/obj/vehicle/vehicle_target - -/datum/action/vehicle/sealed - var/obj/vehicle/sealed/vehicle_entered_target - -/datum/action/vehicle/sealed/climb_out - name = "Climb Out" - desc = "Climb out of your vehicle!" - -/datum/action/vehicle/sealed/climb_out/Trigger() - if(..() && istype(vehicle_entered_target)) - vehicle_entered_target.mob_try_exit(owner, owner) - -/datum/action/vehicle/ridden - var/obj/vehicle/ridden/vehicle_ridden_target +//VEHICLE DEFAULT HANDLING +/obj/vehicle/proc/generate_actions() + return + +/obj/vehicle/proc/generate_action_type(actiontype) + var/datum/action/vehicle/A = new actiontype + if(!istype(A)) + return + A.vehicle_target = src + return A + +/obj/vehicle/proc/initialize_passenger_action_type(actiontype) + autogrant_actions_passenger += actiontype + for(var/i in occupants) + grant_passenger_actions(i) //refresh + +/obj/vehicle/proc/initialize_controller_action_type(actiontype, control_flag) + LAZYINITLIST(autogrant_actions_controller["[control_flag]"]) + autogrant_actions_controller["[control_flag]"] += actiontype + for(var/i in occupants) + grant_controller_actions(i) //refresh + +/obj/vehicle/proc/grant_action_type_to_mob(actiontype, mob/m) + if(!occupants[m] || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + return TRUE + var/datum/action/action = generate_action_type(actiontype) + action.Grant(m) + occupant_actions[m][action.type] = action + return TRUE + +/obj/vehicle/proc/remove_action_type_from_mob(actiontype, mob/m) + if(!occupants[m] || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + var/datum/action/action = occupant_actions[m][actiontype] + action.Remove(m) + occupant_actions[m] -= actiontype + return TRUE + +/obj/vehicle/proc/grant_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + grant_action_type_to_mob(v, M) + +/obj/vehicle/proc/remove_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + remove_action_type_from_mob(v, M) + +/obj/vehicle/proc/grant_controller_actions(mob/M) + if(!istype(M) || !occupants[M]) + return FALSE + for(var/i in GLOB.bitflags) + if(occupants[M] & i) + grant_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/remove_controller_actions(mob/M) + if(!istype(M) || !occupants[M]) + return FALSE + for(var/i in GLOB.bitflags) + remove_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/grant_controller_actions_by_flag(mob/M, flag) + if(!istype(M) || !autogrant_actions_controller["[flag]"]) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + grant_action_type_to_mob(v, M) + return TRUE + +/obj/vehicle/proc/remove_controller_actions_by_flag(mob/M, flag) + if(!istype(M) || autogrant_actions_controller["[flag]"]) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + remove_action_type_from_mob(v, M) + return TRUE + +/obj/vehicle/proc/cleanup_actions_for_mob(mob/M) + if(!istype(M)) + return FALSE + LAZYINITLIST(occupant_actions[M]) + for(var/path in occupant_actions[M]) + stack_trace("Leftover action type [path] in vehicle type [type] for mob type [M.type] - THIS SHOULD NOT BE HAPPENING!") + var/datum/action/action = occupant_actions[M] + action.Remove(M) + occupant_actions -= M + return TRUE + +//ACTION DATUMS + +/datum/action/vehicle + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS + icon_icon = 'icons/mob/actions/actions_vehicle.dmi' + button_icon_state = "vehicle_eject" + var/obj/vehicle/vehicle_target + +/datum/action/vehicle/sealed + var/obj/vehicle/sealed/vehicle_entered_target + +/datum/action/vehicle/sealed/climb_out + name = "Climb Out" + desc = "Climb out of your vehicle!" + +/datum/action/vehicle/sealed/climb_out/Trigger() + if(..() && istype(vehicle_entered_target)) + vehicle_entered_target.mob_try_exit(owner, owner) + +/datum/action/vehicle/ridden + var/obj/vehicle/ridden/vehicle_ridden_target diff --git a/code/modules/vehicles/vehicle_key.dm b/code/modules/vehicles/vehicle_key.dm index 204a10bd17..e34ad9253d 100644 --- a/code/modules/vehicles/vehicle_key.dm +++ b/code/modules/vehicles/vehicle_key.dm @@ -1,15 +1,15 @@ -/obj/item/key - name = "key" - desc = "A small grey key." - icon = 'icons/obj/vehicles.dmi' - icon_state = "key" - w_class = WEIGHT_CLASS_TINY - -/obj/item/key/security - desc = "A keyring with a small steel key, and a rubber stun baton accessory." - icon_state = "keysec" - -/obj/item/key/janitor - desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." - icon_state = "keyjanitor" - +/obj/item/key + name = "key" + desc = "A small grey key." + icon = 'icons/obj/vehicles.dmi' + icon_state = "key" + w_class = WEIGHT_CLASS_TINY + +/obj/item/key/security + desc = "A keyring with a small steel key, and a rubber stun baton accessory." + icon_state = "keysec" + +/obj/item/key/janitor + desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"." + icon_state = "keyjanitor" + diff --git a/icons/effects/vanguard_target.dmi b/icons/effects/vanguard_target.dmi index 73ba014e2d..5220c325e5 100644 Binary files a/icons/effects/vanguard_target.dmi and b/icons/effects/vanguard_target.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index 9d3e0630a7..b0434f431f 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 0255204f60..3a7b0648fd 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/actions/actions_clockcult.dmi b/icons/mob/actions/actions_clockcult.dmi index 19fd68f836..4aad4ba569 100644 Binary files a/icons/mob/actions/actions_clockcult.dmi and b/icons/mob/actions/actions_clockcult.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index de8587dba5..2eab8fa78e 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 89eb9dbcbc..3aa655b574 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 0cdee31ae1..70988dbef5 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index 38c89769d2..76adebdc11 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index c14fbb3fb2..a12053ae1d 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 3854f252eb..e83588d5ed 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi index b5b851a8d5..59635b8c7d 100644 Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi index e9fd4ed401..fc236ac7e2 100644 Binary files a/icons/mob/screen_cyborg.dmi and b/icons/mob/screen_cyborg.dmi differ diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi index 988bf59592..502e9ad3f9 100644 Binary files a/icons/mob/screen_full.dmi and b/icons/mob/screen_full.dmi differ diff --git a/icons/mob/simple_human.dmi b/icons/mob/simple_human.dmi index f3345c0825..597ee94d72 100644 Binary files a/icons/mob/simple_human.dmi and b/icons/mob/simple_human.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index c251b93f2e..241db46d08 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/Cryogenic2.dmi b/icons/obj/Cryogenic2.dmi new file mode 100644 index 0000000000..9d7b7510c5 Binary files /dev/null and b/icons/obj/Cryogenic2.dmi differ diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi index 17dc5b8fb2..d492ae52f6 100644 Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ diff --git a/icons/obj/biogenerator.dmi b/icons/obj/biogenerator.dmi new file mode 100644 index 0000000000..7989d6f355 Binary files /dev/null and b/icons/obj/biogenerator.dmi differ diff --git a/icons/obj/bloodpack.dmi b/icons/obj/bloodpack.dmi index 423b5bb641..ac879aa33c 100644 Binary files a/icons/obj/bloodpack.dmi and b/icons/obj/bloodpack.dmi differ diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi index ed8f37c4da..76ac7bd0a8 100644 Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 561359959b..784c0f55eb 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ diff --git a/icons/obj/cloning.dmi b/icons/obj/cloning.dmi new file mode 100644 index 0000000000..5aa439df6b Binary files /dev/null and b/icons/obj/cloning.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index 4c3c0fe5ce..63c036ce14 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi index 31aab0ae26..dd1ae7d727 100644 Binary files a/icons/obj/clothing/cloaks.dmi and b/icons/obj/clothing/cloaks.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index 48f37887cf..6c193f1044 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 6ec16c836f..2a6d2004b3 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 786a8c7fd0..b1d7a7106d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index c41db68326..0f3668ce10 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 2cf675c571..77b62691d2 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index d0326b1141..f44fc29f7c 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 8fe4c9619b..6c1dabef23 100644 Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index 0669549b02..31e700d23d 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 876f747fc1..88aa6f7985 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/flora/_flora.dmi b/icons/obj/flora/_flora.dmi new file mode 100644 index 0000000000..d3e800576e Binary files /dev/null and b/icons/obj/flora/_flora.dmi differ diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index 7d413895ca..7f4d65e081 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/icons/obj/guns/bayonets.dmi b/icons/obj/guns/bayonets.dmi index 176005b7d7..32b5448b8e 100644 Binary files a/icons/obj/guns/bayonets.dmi and b/icons/obj/guns/bayonets.dmi differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi index ad5f8bc863..3d125d68c7 100644 Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 636d895450..446b093167 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 2048725e56..776bf7a9ec 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/machines/research.dmi b/icons/obj/machines/research.dmi index cd74eed322..a150880d39 100644 Binary files a/icons/obj/machines/research.dmi and b/icons/obj/machines/research.dmi differ diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi index 5404b908c6..241bb46b98 100644 Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi index 7eec51e46e..f0eb817549 100644 Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index f563af642f..dadf843041 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/suitstorage.dmi b/icons/obj/suitstorage.dmi new file mode 100644 index 0000000000..e61f9567c6 Binary files /dev/null and b/icons/obj/suitstorage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 18bbcb3610..d18a1bf262 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index c7b9bbcdc8..a1471e6418 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi index 7f8289a087..a59fdd0f52 100644 Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ