/obj/item/reagent_containers/hypospray name = "hypospray" desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." icon = 'icons/obj/syringe.dmi' item_state = "hypo" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' icon_state = "hypo" amount_per_transfer_from_this = 5 volume = 30 possible_transfer_amounts = list() resistance_flags = ACID_PROOF reagent_flags = OPENCONTAINER slot_flags = ITEM_SLOT_BELT var/ignore_flags = 0 var/infinite = FALSE /obj/item/reagent_containers/hypospray/attack_paw(mob/user) return attack_hand(user) /obj/item/reagent_containers/hypospray/attack(mob/living/M, mob/user) if(!reagents.total_volume) to_chat(user, "[src] is empty!") return if(!iscarbon(M)) return //Always log attemped injects for admins var/list/injected = list() for(var/datum/reagent/R in reagents.reagent_list) injected += R.name var/contained = english_list(injected) log_combat(user, M, "attempted to inject", src, "([contained])") if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) // Ignore flag should be checked first or there will be an error message. to_chat(M, "You feel a tiny prick!") to_chat(user, "You inject [M] with [src].") var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) reagents.reaction(M, INJECT, fraction) if(M.reagents) var/trans = 0 if(!infinite) trans = reagents.trans_to(M, amount_per_transfer_from_this) else trans = reagents.copy_to(M, amount_per_transfer_from_this) to_chat(user, "[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src].") log_combat(user, M, "injected", src, "([contained])") /obj/item/reagent_containers/hypospray/CMO list_reagents = list(/datum/reagent/medicine/omnizine = 30) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/reagent_containers/hypospray/combat name = "combat stimulant injector" desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat." amount_per_transfer_from_this = 10 icon_state = "combat_hypo" volume = 90 ignore_flags = 1 // So they can heal their comrades. list_reagents = list(/datum/reagent/medicine/epinephrine = 30, /datum/reagent/medicine/omnizine = 30, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/atropine = 15) /obj/item/reagent_containers/hypospray/combat/nanites desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with experimental medical compounds for rapid healing." volume = 100 list_reagents = list(/datum/reagent/medicine/adminordrazine/quantum_heal = 80, /datum/reagent/medicine/synaptizine = 20) /obj/item/reagent_containers/hypospray/magillitis name = "experimental autoinjector" desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum." icon_state = "combat_hypo" volume = 5 reagent_flags = NONE list_reagents = list(/datum/reagent/magillitis = 5) //MediPens /obj/item/reagent_containers/hypospray/medipen name = "epinephrine medipen" desc = "A rapid and safe way to stabilize patients in critical condition for personnel without advanced medical knowledge. Also useful for preventing organ decay in the deceased." icon_state = "medipen" item_state = "medipen" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' amount_per_transfer_from_this = 11 volume = 11 ignore_flags = 1 //so you can medipen through hardsuits reagent_flags = DRAWABLE flags_1 = null list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/toxin/formaldehyde = 1) /obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to choke on \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") return OXYLOSS//ironic. he could save others from oxyloss, but not himself. /obj/item/reagent_containers/hypospray/medipen/attack(mob/M, mob/user) if(!reagents.total_volume) to_chat(user, "[src] is empty!") return ..() if(!iscyborg(user)) reagents.maximum_volume = 0 //Makes them useless afterwards reagent_flags = NONE update_icon() addtimer(CALLBACK(src, .proc/cyborg_recharge, user), 80) /obj/item/reagent_containers/hypospray/medipen/proc/cyborg_recharge(mob/living/silicon/robot/user) if(!reagents.total_volume && iscyborg(user)) var/mob/living/silicon/robot/R = user if(R.cell.use(100)) reagents.add_reagent_list(list_reagents) update_icon() /obj/item/reagent_containers/hypospray/medipen/update_icon() if(reagents.total_volume > 0) icon_state = initial(icon_state) else icon_state = "[initial(icon_state)]0" /obj/item/reagent_containers/hypospray/medipen/examine() . = ..() if(reagents && reagents.reagent_list.len) . += "It is currently loaded." else . += "It is spent." /obj/item/reagent_containers/hypospray/medipen/stimulants name = "illegal stimpack medipen" desc = "A highly illegal medipen due to its load and small injections, allow for five uses before being drained" volume = 50 amount_per_transfer_from_this = 10 list_reagents = list(/datum/reagent/medicine/stimulants = 50) /obj/item/reagent_containers/hypospray/medipen/stimulants/baseball name = "the reason the syndicate major league team wins." desc = "They say drugs never win, but look where you are now, then where they are." icon_state = "baseballstim" volume = 50 amount_per_transfer_from_this = 50 list_reagents = list(/datum/reagent/medicine/stimulants = 50) /obj/item/reagent_containers/hypospray/medipen/stimpack //goliath kiting name = "stimpack medipen" desc = "A rapid way to stimulate your body's adrenaline, allowing for freer movement in restrictive armor." icon_state = "stimpen" volume = 20 amount_per_transfer_from_this = 20 list_reagents = list(/datum/reagent/medicine/ephedrine = 10, /datum/reagent/consumable/coffee = 10) /obj/item/reagent_containers/hypospray/medipen/stimpack/traitor desc = "A modified stimulants autoinjector for use in combat situations. Has a mild healing effect." list_reagents = list(/datum/reagent/medicine/stimulants = 10, /datum/reagent/medicine/omnizine = 10) /obj/item/reagent_containers/hypospray/medipen/morphine name = "morphine medipen" desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though." list_reagents = list(/datum/reagent/medicine/morphine = 10) /obj/item/reagent_containers/hypospray/medipen/tuberculosiscure name = "BVAK autoinjector" desc = "Bio Virus Antidote Kit autoinjector. Has a two use system for yourself, and someone else. Inject when infected." icon_state = "stimpen" volume = 60 amount_per_transfer_from_this = 30 list_reagents = list(/datum/reagent/medicine/atropine = 10, /datum/reagent/medicine/epinephrine = 10, /datum/reagent/medicine/salbutamol = 20, /datum/reagent/medicine/spaceacillin = 20) /obj/item/reagent_containers/hypospray/medipen/survival name = "survival medipen" desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards. WARNING: Do not inject more than one pen in quick succession." icon_state = "stimpen" volume = 52 amount_per_transfer_from_this = 52 list_reagents = list(/datum/reagent/medicine/salbutamol = 10, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/neo_jelly = 15, /datum/reagent/medicine/epinephrine = 10, /datum/reagent/medicine/lavaland_extract = 2) /obj/item/reagent_containers/hypospray/medipen/firelocker name = "fire treatment medipen" desc = "A medipen that has been fulled with burn healing chemicals for personnel without advanced medical knowledge." volume = 15 amount_per_transfer_from_this = 15 list_reagents = list(/datum/reagent/medicine/oxandrolone = 5, /datum/reagent/medicine/kelotane = 10) /obj/item/reagent_containers/hypospray/combat/heresypurge name = "holy water autoinjector" desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with 5 doses of a holy water mixture." volume = 250 list_reagents = list(/datum/reagent/water/holywater = 150, /datum/reagent/peaceborg_tire = 50, /datum/reagent/peaceborg_confuse = 50) amount_per_transfer_from_this = 50 #define HYPO_SPRAY 0 #define HYPO_INJECT 1 #define WAIT_SPRAY 25 #define WAIT_INJECT 25 #define SELF_SPRAY 15 #define SELF_INJECT 15 #define DELUXE_WAIT_SPRAY 20 #define DELUXE_WAIT_INJECT 20 #define DELUXE_SELF_SPRAY 10 #define DELUXE_SELF_INJECT 10 #define COMBAT_WAIT_SPRAY 0 #define COMBAT_WAIT_INJECT 0 #define COMBAT_SELF_SPRAY 0 #define COMBAT_SELF_INJECT 0 //A vial-loaded hypospray. Cartridge-based! /obj/item/hypospray/mkii name = "hypospray mk.II" icon_state = "hypo2" icon = 'icons/obj/syringe.dmi' desc = "A new development from DeForest Medical, this hypospray takes 30-unit vials as the drug supply for easy swapping." w_class = WEIGHT_CLASS_TINY var/list/allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small) var/mode = HYPO_INJECT var/obj/item/reagent_containers/glass/bottle/vial/vial var/start_vial = /obj/item/reagent_containers/glass/bottle/vial/small var/spawnwithvial = TRUE var/inject_wait = WAIT_INJECT var/spray_wait = WAIT_SPRAY var/spray_self = SELF_SPRAY var/inject_self = SELF_INJECT var/quickload = FALSE var/penetrates = FALSE var/reloadable = TRUE /obj/item/hypospray/mkii/brute start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/bicaridine /obj/item/hypospray/mkii/toxin start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/antitoxin /obj/item/hypospray/mkii/oxygen start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/dexalin /obj/item/hypospray/mkii/burn start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/kelotane /obj/item/hypospray/mkii/tricord start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/tricord /obj/item/hypospray/mkii/enlarge spawnwithvial = FALSE //A vial-loaded hypospray. Cartridge-based! /obj/item/hypospray/mkii/disposable name = "disposable hypospray mk.II" icon_state = "hypo2" desc = "A cheaply made knock off verson of the MKII hypospray. You cannot remove a hypovial from it making it nonreusable." w_class = WEIGHT_CLASS_TINY spawnwithvial = FALSE reloadable = FALSE /obj/item/hypospray/mkii/CMO name = "hypospray mk.II deluxe" allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small, /obj/item/reagent_containers/glass/bottle/vial/large) icon_state = "cmo2" desc = "The Deluxe Hypospray can take larger-size vials. It also acts faster and delivers more reagents per spray." resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/CMO inject_wait = DELUXE_WAIT_INJECT spray_wait = DELUXE_WAIT_SPRAY spray_self = DELUXE_SELF_SPRAY inject_self = DELUXE_SELF_INJECT /obj/item/hypospray/mkii/CMO/combat name = "combat hypospray mk.II" desc = "A combat-ready deluxe hypospray that acts almost instantly. It can be tactically reloaded by using a vial on it." icon_state = "combat2" start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/combat inject_wait = COMBAT_WAIT_INJECT spray_wait = COMBAT_WAIT_SPRAY spray_self = COMBAT_SELF_SPRAY inject_self = COMBAT_SELF_INJECT quickload = TRUE penetrates = TRUE /obj/item/hypospray/mkii/Initialize() . = ..() if(!spawnwithvial) update_icon() return if(start_vial) vial = new start_vial update_icon() /obj/item/hypospray/mkii/update_icon() ..() icon_state = "[initial(icon_state)][vial ? "" : "-e"]" if(ismob(loc)) var/mob/M = loc M.update_inv_hands() return /obj/item/hypospray/mkii/examine(mob/user) . = ..() if(vial) . += "[vial] has [vial.reagents.total_volume]u remaining." else . += "It has no vial loaded in." . += "[src] is set to [mode ? "Inject" : "Spray"] contents on application." /obj/item/hypospray/mkii/proc/unload_hypo(obj/item/I, mob/user) if (reloadable == TRUE) if((istype(I, /obj/item/reagent_containers/glass/bottle/vial))) var/obj/item/reagent_containers/glass/bottle/vial/V = I V.forceMove(user.loc) user.put_in_hands(V) to_chat(user, "You remove [vial] from [src].") vial = null update_icon() playsound(loc, 'sound/weapons/empty.ogg', 50, 1) else to_chat(user, "This hypo isn't loaded!") return else if((istype(I, /obj/item/reagent_containers/glass/bottle/vial))) to_chat(user, "You cannot remove [vial] from [src] without destroying both.") /obj/item/hypospray/mkii/attackby(obj/item/I, mob/living/user) if((istype(I, /obj/item/reagent_containers/glass/bottle/vial) && vial != null)) if(!quickload) to_chat(user, "[src] can not hold more than one vial!") return FALSE unload_hypo(vial, user) if((istype(I, /obj/item/reagent_containers/glass/bottle/vial))) var/obj/item/reagent_containers/glass/bottle/vial/V = I if(!is_type_in_list(V, allowed_containers)) to_chat(user, "[src] doesn't accept this type of vial.") return FALSE if(!user.transferItemToLoc(V,src)) return FALSE vial = V user.visible_message("[user] has loaded a vial into [src].","You have loaded [vial] into [src].") update_icon() playsound(loc, 'sound/weapons/autoguninsert.ogg', 35, 1) return TRUE else to_chat(user, "This doesn't fit in [src].") return FALSE return FALSE /obj/item/hypospray/mkii/AltClick(mob/user) . = ..() if(vial) vial.attack_self(user) return TRUE // Gunna allow this for now, still really don't approve - Pooj /obj/item/hypospray/mkii/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) to_chat(user, "[src] happens to be already overcharged.") return inject_wait = COMBAT_WAIT_INJECT spray_wait = COMBAT_WAIT_SPRAY spray_self = COMBAT_SELF_INJECT inject_self = COMBAT_SELF_SPRAY penetrates = TRUE to_chat(user, "You overcharge [src]'s control circuit.") obj_flags |= EMAGGED return TRUE /obj/item/hypospray/mkii/attack_hand(mob/user) . = ..() //Don't bother changing this or removing it from containers will break. /obj/item/hypospray/mkii/attack(obj/item/I, mob/user, params) return /obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity) if(!vial) return if(!proximity) return if(!ismob(target)) return var/mob/living/L if(isliving(target)) L = target if(!penetrates && !L.can_inject(user, 1)) //This check appears another four times, since otherwise the penetrating sprays will break in do_mob. return if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles to_chat(user, "You cannot directly fill [target]!") return if(target.reagents.total_volume >= target.reagents.maximum_volume) to_chat(user, "[target] is full.") return if(ishuman(L)) var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected)) if(!affecting) to_chat(user, "The limb is missing!") return if(affecting.status != BODYPART_ORGANIC) to_chat(user, "Medicine won't work on a robotic limb!") return var/contained = vial.reagents.log_list() log_combat(user, L, "attemped to inject", src, addition="which had [contained]") //Always log attemped injections for admins if(vial != null) switch(mode) if(HYPO_INJECT) if(L) //living mob if(L != user) L.visible_message("[user] is trying to inject [L] with [src]!", \ "[user] is trying to inject [L] with [src]!") if(!do_mob(user, L, inject_wait)) return if(!penetrates && !L.can_inject(user, 1)) return if(!vial.reagents.total_volume) return if(L.reagents.total_volume >= L.reagents.maximum_volume) return L.visible_message("[user] uses the [src] on [L]!", \ "[user] uses the [src] on [L]!") else if(!do_mob(user, L, inject_self)) return if(!penetrates && !L.can_inject(user, 1)) return if(!vial.reagents.total_volume) return if(L.reagents.total_volume >= L.reagents.maximum_volume) return log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])") L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG) var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1) vial.reagents.reaction(L, INJECT, fraction) vial.reagents.trans_to(target, vial.amount_per_transfer_from_this) if(vial.amount_per_transfer_from_this >= 15) playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1) if(vial.amount_per_transfer_from_this < 15) playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1) to_chat(user, "You inject [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.") if(HYPO_SPRAY) if(L) //living mob if(L != user) L.visible_message("[user] is trying to spray [L] with [src]!", \ "[user] is trying to spray [L] with [src]!") if(!do_mob(user, L, spray_wait)) return if(!penetrates && !L.can_inject(user, 1)) return if(!vial.reagents.total_volume) return if(L.reagents.total_volume >= L.reagents.maximum_volume) return L.visible_message("[user] uses the [src] on [L]!", \ "[user] uses the [src] on [L]!") else if(!do_mob(user, L, spray_self)) return if(!penetrates && !L.can_inject(user, 1)) return if(!vial.reagents.total_volume) return if(L.reagents.total_volume >= L.reagents.maximum_volume) return log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])") L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG) var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1) vial.reagents.reaction(L, PATCH, fraction) vial.reagents.trans_to(target, vial.amount_per_transfer_from_this) if(vial.amount_per_transfer_from_this >= 15) playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1) if(vial.amount_per_transfer_from_this < 15) playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1) to_chat(user, "You spray [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.") else to_chat(user, "[src] doesn't work here!") return /obj/item/hypospray/mkii/attack_self(mob/living/user) if(user) if(user.incapacitated()) return else if(!vial) to_chat(user, "This Hypo needs to be loaded first!") return else unload_hypo(vial,user) /obj/item/hypospray/mkii/verb/modes() set name = "Toggle Application Mode" set category = "Object" set src in usr var/mob/M = usr switch(mode) if(HYPO_SPRAY) mode = HYPO_INJECT to_chat(M, "[src] is now set to inject contents on application.") if(HYPO_INJECT) mode = HYPO_SPRAY to_chat(M, "[src] is now set to spray contents on application.") #undef HYPO_SPRAY #undef HYPO_INJECT #undef WAIT_SPRAY #undef WAIT_INJECT #undef SELF_SPRAY #undef SELF_INJECT #undef DELUXE_WAIT_SPRAY #undef DELUXE_WAIT_INJECT #undef DELUXE_SELF_SPRAY #undef DELUXE_SELF_INJECT #undef COMBAT_WAIT_SPRAY #undef COMBAT_WAIT_INJECT #undef COMBAT_SELF_SPRAY #undef COMBAT_SELF_INJECT //Chemlight was here. /obj/item/reagent_containers/hypospray/debug name = "retractable hypospray syringe" desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment." icon = 'icons/obj/syringe.dmi' item_state = "hypo" icon_state = "borghypo" amount_per_transfer_from_this = 5 volume = 200 possible_transfer_amounts = list() resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF reagent_flags = OPENCONTAINER | NO_REACT slot_flags = ITEM_SLOT_BELT infinite = TRUE var/list/fun_ids = list(/datum/reagent/growthchem, /datum/reagent/shrinkchem, /datum/reagent/drug/aphrodisiac, /datum/reagent/drug/aphrodisiacplus, /datum/reagent/fermi/penis_enlarger, /datum/reagent/fermi/breast_enlarger, /datum/reagent/drug/space_drugs, /datum/reagent/lithium) /obj/item/reagent_containers/hypospray/debug/attack_self(mob/user) var/chosen_reagent var/quick_select = input(user, "Select an option", "Press start") in list("Quick menu", "Debug", "Cancel") switch (quick_select) if("Quick menu") var/list_selection = input(user, "Choose an catagory", "List Choice") in list("Emergency Meds", "Fun Chemicals", "Self Defense", "Cancel") switch(list_selection) if("Emergency Meds") reagents.clear_reagents() amount_per_transfer_from_this = 10 reagents.add_reagent_list(list(/datum/reagent/medicine/atropine = 10, /datum/reagent/medicine/oxandrolone = 20, /datum/reagent/medicine/sal_acid = 20, /datum/reagent/medicine/salbutamol = 10)) if("Self Defense") reagents.clear_reagents() amount_per_transfer_from_this = 10 reagents.add_reagent_list(list(/datum/reagent/toxin/staminatoxin = 14, /datum/reagent/peaceborg_tire = 21, /datum/reagent/toxin/bonehurtingjuice = 14,)) // OOF if("Fun Chemicals") reagents.clear_reagents() amount_per_transfer_from_this = 5 chosen_reagent = input(user, "What reagent do you want to dispense?") as null|anything in fun_ids if(chosen_reagent) reagents.add_reagent(chosen_reagent, 20, null) if("Debug") var/operation_selection = input(user, "Select an option", "Reagent fabricator", "cancel") in list("Select reagent", "Clear reagents", "Select transfer amount", "Cancel") switch(operation_selection) if("Select reagent") switch(alert(usr, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) if("Search") var/valid_id while(!valid_id) chosen_reagent = input(usr, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text if(isnull(chosen_reagent)) //Get me out of here! break if(!ispath(text2path(chosen_reagent))) chosen_reagent = pick_closest_path(chosen_reagent, make_types_fancy(subtypesof(/datum/reagent))) if(ispath(chosen_reagent)) valid_id = TRUE else valid_id = TRUE if(!valid_id) to_chat(usr, "A reagent with that ID doesn't exist!") if("Choose from a list") chosen_reagent = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) if("I'm feeling lucky") chosen_reagent = pick(subtypesof(/datum/reagent)) if(chosen_reagent) reagents.add_reagent(chosen_reagent, 20, null) if("Clear reagents") reagents.clear_reagents() if("Select transfer amount") var/transfer_select = input(user, "Select the amount of reagents you'd like to inject.", "Transfer amount") as num|null if(transfer_select) amount_per_transfer_from_this = max(min(round(text2num(transfer_select)),20),1) else return