diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index 1ba5ec30b5..76f1f9f780 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -285,3 +285,16 @@ Proc for attack log creation, because really why not
else
. = getCompoundIcon(desired)
cached_character_icons[cachekey] = .
+
+/proc/getviewsize(view)
+ var/viewX
+ var/viewY
+ if(isnum(view))
+ var/totalviewrange = 1 + 2 * view
+ viewX = totalviewrange
+ viewY = totalviewrange
+ else
+ var/list/viewrangelist = splittext(view,"x")
+ viewX = text2num(viewrangelist[1])
+ viewY = text2num(viewrangelist[2])
+ return list(viewX, viewY)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index c994aff121..e18970802e 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -511,3 +511,9 @@
/atom/proc/AllowDrop()
return FALSE
+
+/atom/proc/get_nametag_name(mob/user)
+ return name
+
+/atom/proc/get_nametag_desc(mob/user)
+ return "" //Desc itself is often too long to use
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index 3dc5642a81..0623504203 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -22,6 +22,7 @@
var/adminobs = null
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
+ var/datum/tooltip/tooltips = null
var/adminhelped = 0
diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm
index 09289c1068..6168aa36b0 100644
--- a/code/modules/client/preference_setup/global/01_ui.dm
+++ b/code/modules/client/preference_setup/global/01_ui.dm
@@ -7,24 +7,28 @@
S["UI_style_color"] >> pref.UI_style_color
S["UI_style_alpha"] >> pref.UI_style_alpha
S["ooccolor"] >> pref.ooccolor
+ S["tooltipstyle"] >> pref.tooltipstyle
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
S["UI_style"] << pref.UI_style
S["UI_style_color"] << pref.UI_style_color
S["UI_style_alpha"] << pref.UI_style_alpha
S["ooccolor"] << pref.ooccolor
+ S["tooltipstyle"] >> pref.tooltipstyle
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color))
pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha))
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
+ pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, all_tooltip_styles[1])
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
. = "UI Style: [pref.UI_style]
"
. += "Custom UI (recommended for White UI):
"
. += "-Color: [pref.UI_style_color]
reset
"
. += "-Alpha(transparency): [pref.UI_style_alpha] reset
"
+ . += "Tooltip Style: [pref.tooltipstyle]
"
if(can_select_ooc_color(user))
. += "OOC Color: "
if(pref.ooccolor == initial(pref.ooccolor))
@@ -57,6 +61,12 @@
pref.ooccolor = new_ooccolor
return TOPIC_REFRESH
+ else if(href_list["select_tooltip_style"])
+ var/tooltip_style_new = input(user, "Choose tooltip style.", "Character Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles
+ if(!tooltip_style_new || !CanUseTopic(user)) return TOPIC_NOACTION
+ pref.tooltipstyle = tooltip_style_new
+ return TOPIC_REFRESH
+
else if(href_list["reset"])
switch(href_list["reset"])
if("ui")
diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm
index 222813460b..05d3410467 100644
--- a/code/modules/client/preference_setup/global/setting_datums.dm
+++ b/code/modules/client/preference_setup/global/setting_datums.dm
@@ -122,6 +122,12 @@ var/list/_client_preferences_by_type
enabled_description = "Show"
disabled_description = "Hide"
+/datum/client_preference/mob_tooltips
+ description ="Mob tooltips"
+ key = "MOB_TOOLTIPS"
+ enabled_description = "Show"
+ disabled_description = "Hide"
+
/datum/client_preference/attack_icons
description ="Attack icons"
key = "ATTACK_ICONS"
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 697d850d51..497aa44a35 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -21,6 +21,7 @@ datum/preferences
var/UI_style = "Midnight"
var/UI_style_color = "#ffffff"
var/UI_style_alpha = 255
+ var/tooltipstyle = "Midnight" //Style for popup tooltips
//character preferences
var/real_name //our character's name
diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm
index a350942c58..ca6fae65fd 100644
--- a/code/modules/client/preferences_toggle_procs.dm
+++ b/code/modules/client/preferences_toggle_procs.dm
@@ -207,6 +207,19 @@
feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/verb/toggle_mob_tooltips()
+ set name = "Toggle Mob Tooltips"
+ set category = "Preferences"
+ set desc = "Toggles displaying name/species over mobs when moused over."
+
+ var/pref_path = /datum/client_preference/mob_tooltips
+ toggle_preference(pref_path)
+ prefs.save_preferences()
+
+ src << "You will now [(is_preference_enabled(/datum/client_preference/mob_tooltips)) ? "see" : "not see"] mob tooltips."
+
+ feedback_add_details("admin_verb","TMobTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
//Toggles for Staff
//Developers
diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm
index d8d683d5d3..4a736aec5e 100644
--- a/code/modules/client/ui_style.dm
+++ b/code/modules/client/ui_style.dm
@@ -20,6 +20,15 @@
"Hologram" = 'icons/mob/screen1_robot_minimalist.dmi'
)
+var/global/list/all_tooltip_styles = list(
+ "Midnight", //Default for everyone is the first one,
+ "Plasmafire",
+ "Retro",
+ "Slimecore",
+ "Operative",
+ "Clockwork"
+ )
+
/proc/ui_style2icon(ui_style)
if(ui_style in all_ui_styles)
return all_ui_styles[ui_style]
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 6da16a608d..facc1ac438 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1576,3 +1576,55 @@
if(update_icons)
update_icons()
+
+/mob/living/carbon/human/proc/get_display_species()
+ //Shows species in tooltip
+ if(src.custom_species) //VOREStation Add
+ return custom_species //VOREStation Add
+ //Beepboops get special text if obviously beepboop
+ if(looksSynthetic())
+ if(gender == MALE)
+ return "Android"
+ else if(gender == FEMALE)
+ return "Gynoid"
+ else
+ return "Synthetic"
+ //Else species name
+ if(species)
+ return species.get_examine_name()
+ //Else CRITICAL FAILURE!
+ return ""
+
+/mob/living/carbon/human/get_nametag_name(mob/user)
+ return name //Could do fancy stuff here?
+
+/mob/living/carbon/human/get_nametag_desc(mob/user)
+ var/msg = ""
+ if(hasHUD(user,"security"))
+ //Try to find their name
+ var/perpname
+ if(wear_id)
+ var/obj/item/weapon/card/id/I = wear_id.GetID()
+ if(I)
+ perpname = I.registered_name
+ else
+ perpname = name
+ else
+ perpname = name
+ //Try to find their record
+ var/criminal = "None"
+ if(perpname)
+ var/datum/data/record/G = find_general_record("name", perpname)
+ if(G)
+ var/datum/data/record/S = find_security_record("id", G.fields["id"])
+ if(S)
+ criminal = S.fields["criminal"]
+ //If it's interesting, append
+ if(criminal != "None")
+ msg += "([criminal]) "
+
+ if(hasHUD(user,"medical"))
+ msg += "(Health: [round((health/getMaxHealth())*100)]%) "
+
+ msg += get_display_species()
+ return msg
diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm
index 726c94f143..c51c7c1b36 100644
--- a/code/modules/mob/living/simple_animal/animals/bat.dm
+++ b/code/modules/mob/living/simple_animal/animals/bat.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/scarybat
name = "space bats"
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
+ tt_desc = "Desmodus rotundus" //Common vampire bat
icon = 'icons/mob/bats.dmi'
icon_state = "bat"
icon_living = "bat"
diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm
index 3cb3fa8cbe..55eda3fcca 100644
--- a/code/modules/mob/living/simple_animal/animals/bear.dm
+++ b/code/modules/mob/living/simple_animal/animals/bear.dm
@@ -2,6 +2,7 @@
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "RawrRawr!!"
+ tt_desc = "Ursinae aetherius" //...bearspace? Maybe.
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm
index 4dc4daffda..8b6e01c452 100644
--- a/code/modules/mob/living/simple_animal/animals/carp.dm
+++ b/code/modules/mob/living/simple_animal/animals/carp.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
+ tt_desc = "Cyprinus aetherius" //carpspace? maybe
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm
index 1f0c9c6d26..0eb3516d67 100644
--- a/code/modules/mob/living/simple_animal/animals/cat.dm
+++ b/code/modules/mob/living/simple_animal/animals/cat.dm
@@ -2,6 +2,7 @@
/mob/living/simple_animal/cat
name = "cat"
desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
+ tt_desc = "Felis catus"
intelligence_level = SA_ANIMAL
icon_state = "cat2"
item_state = "cat2"
@@ -155,6 +156,7 @@
/mob/living/simple_animal/cat/fluff/Runtime
name = "Runtime"
desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
+ tt_desc = "Felis medicalis"
gender = FEMALE
icon_state = "cat"
item_state = "cat"
diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm
index a6d0dcd9c0..d5c198ad78 100644
--- a/code/modules/mob/living/simple_animal/animals/corgi.dm
+++ b/code/modules/mob/living/simple_animal/animals/corgi.dm
@@ -3,6 +3,7 @@
name = "corgi"
real_name = "corgi"
desc = "It's a corgi."
+ tt_desc = "Canis familiaris"
intelligence_level = SA_ANIMAL
icon_state = "corgi"
icon_living = "corgi"
@@ -37,6 +38,7 @@
real_name = "Ian" //Intended to hold the name without altering it.
gender = MALE
desc = "It's a corgi."
+ tt_desc = "Canis commandus"
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm
index 0d485d859d..de131b9055 100644
--- a/code/modules/mob/living/simple_animal/animals/crab.dm
+++ b/code/modules/mob/living/simple_animal/animals/crab.dm
@@ -2,6 +2,7 @@
/mob/living/simple_animal/crab
name = "crab"
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
+ tt_desc = "Ranina ranina"
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm
index 213aff73bf..52904786a4 100644
--- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/animals/farm_animals.dm
@@ -2,6 +2,7 @@
/mob/living/simple_animal/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
+ tt_desc = "Oreamnos americanus"
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
@@ -85,6 +86,7 @@
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
+ tt_desc = "Bos taurus"
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
@@ -153,6 +155,7 @@
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
+ tt_desc = "Gallus domesticus"
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
@@ -203,6 +206,7 @@ var/global/chicken_count = 0
/mob/living/simple_animal/chicken
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
+ tt_desc = "Gallus domesticus"
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/fox_vr.dm b/code/modules/mob/living/simple_animal/animals/fox_vr.dm
index 65938cb249..90131fc8b9 100644
--- a/code/modules/mob/living/simple_animal/animals/fox_vr.dm
+++ b/code/modules/mob/living/simple_animal/animals/fox_vr.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/fox
name = "fox"
desc = "It's a fox. I wonder what it says?"
+ tt_desc = "Vulpes vulpes"
icon = 'icons/mob/fox_vr.dmi'
icon_state = "fox2"
icon_living = "fox2"
@@ -183,6 +184,7 @@
/mob/living/simple_animal/fox/fluff/Renault
name = "Renault"
desc = "Renault, the Colony Director's trustworthy fox. I wonder what it says?"
+ tt_desc = "Vulpes nobilis"
befriend_job = "Colony Director"
/mob/living/simple_animal/fox/fluff/Renault/init_belly()
@@ -218,6 +220,7 @@
/mob/living/simple_animal/fox/syndicate
name = "syndi-fox"
desc = "It's a DASTARDLY fox! The horror! Call the shuttle!"
+ tt_desc = "Vulpes malus"
icon = 'icons/mob/fox_vr.dmi'
icon_state = "syndifox"
icon_living = "syndifox"
diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm
index c0b8d75c54..094a3060b0 100644
--- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm
@@ -8,6 +8,7 @@
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes."
+ tt_desc = "Atrax robustus gigantus"
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm
index ce6dbdfda8..67e0bdad81 100644
--- a/code/modules/mob/living/simple_animal/animals/goose.dm
+++ b/code/modules/mob/living/simple_animal/animals/goose.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/goose
name = "space goose"
desc = "That's no duck. That's a space goose. You have a bad feeling about this."
+ tt_desc = "Anser aetherius" //Goose space?!
icon_state = "goose"
icon_living = "goose"
icon_dead = "goose_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm
index 38822faf0d..c4c1487315 100644
--- a/code/modules/mob/living/simple_animal/animals/lizard.dm
+++ b/code/modules/mob/living/simple_animal/animals/lizard.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/lizard
name = "Lizard"
desc = "A cute tiny lizard."
+ tt_desc = "Gekko gecko"
icon = 'icons/mob/critter.dmi'
icon_state = "lizard"
icon_living = "lizard"
diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm
index 87df901527..123e82a611 100644
--- a/code/modules/mob/living/simple_animal/animals/mouse.dm
+++ b/code/modules/mob/living/simple_animal/animals/mouse.dm
@@ -2,6 +2,7 @@
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
+ tt_desc = "Mus musculus"
icon_state = "mouse_gray"
item_state = "mouse_gray"
icon_living = "mouse_gray"
diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm
index e495c0e1c7..f48dace302 100644
--- a/code/modules/mob/living/simple_animal/animals/parrot.dm
+++ b/code/modules/mob/living/simple_animal/animals/parrot.dm
@@ -31,6 +31,7 @@
/mob/living/simple_animal/parrot
name = "parrot"
desc = "The parrot squawks, \"It's a parrot! BAWWK!\""
+ tt_desc = "Poicephalus robustus"
icon = 'icons/mob/animal.dmi'
icon_state = "parrot_fly"
icon_living = "parrot_fly"
diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm
index 4bb985d1ac..8463d9ac39 100644
--- a/code/modules/mob/living/simple_animal/animals/penguin.dm
+++ b/code/modules/mob/living/simple_animal/animals/penguin.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/penguin
name = "space penguin"
desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
+ tt_desc = "Aptenodytes forsteri"
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm
index d3a8b1df0c..8c6ef9cf82 100644
--- a/code/modules/mob/living/simple_animal/animals/slime.dm
+++ b/code/modules/mob/living/simple_animal/animals/slime.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/old_slime
name = "pet slime"
desc = "A lovable, domesticated slime."
+ tt_desc = "Amorphidae proteus"
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
icon_living = "grey baby slime"
diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
index 7ae8edfb7a..83f18c071a 100644
--- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/spiderbot
name = "spider-bot"
desc = "A skittering robotic friend!"
+ tt_desc = "Maintenance Robot"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 5bf254583a..cde93f797d 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -5,6 +5,7 @@
/mob/living/simple_animal
name = "animal"
+ desc = ""
icon = 'icons/mob/animal.dmi'
health = 20
maxHealth = 20
@@ -13,6 +14,8 @@
mob_swap_flags = MONKEY|SLIME|HUMAN
mob_push_flags = MONKEY|SLIME|HUMAN
+ var/tt_desc = "Uncataloged Life Form" //Tooltip description
+
//Settings for played mobs
var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob
var/ai_inactive = 0 // Set to 1 to turn off most AI actions
@@ -1718,3 +1721,6 @@
/mob/living/simple_animal/retaliate
retaliate = 1
destroy_surroundings = 1
+
+/mob/living/simple_animal/get_nametag_desc(mob/user)
+ return "tt_desc"
diff --git a/code/modules/mob/living/simple_animal/vore/awoo.dm b/code/modules/mob/living/simple_animal/vore/awoo.dm
index 95234454af..fbd6d8dac5 100644
--- a/code/modules/mob/living/simple_animal/vore/awoo.dm
+++ b/code/modules/mob/living/simple_animal/vore/awoo.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/retaliate/awoo
name = "wolfgirl"
desc = "AwooOOOOoooo!"
+ tt_desc = "Homo lupus"
icon = 'icons/mob/vore.dmi'
icon_state = "awoo"
icon_living = "awoo"
diff --git a/code/modules/mob/living/simple_animal/vore/catgirl.dm b/code/modules/mob/living/simple_animal/vore/catgirl.dm
index f0c0f8ad25..dc8b5f1d8d 100644
--- a/code/modules/mob/living/simple_animal/vore/catgirl.dm
+++ b/code/modules/mob/living/simple_animal/vore/catgirl.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/catgirl
name = "catgirl"
desc = "Her hobbies are catnaps, knocking things over, and headpats."
+ tt_desc = "Homo felinus"
icon = 'icons/mob/vore.dmi'
icon_state = "catgirl"
diff --git a/code/modules/mob/living/simple_animal/vore/fennec.dm b/code/modules/mob/living/simple_animal/vore/fennec.dm
index e658f8f441..1f7a869a4a 100644
--- a/code/modules/mob/living/simple_animal/vore/fennec.dm
+++ b/code/modules/mob/living/simple_animal/vore/fennec.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/fennec
name = "fennec"
desc = "It's a dusty big-eared sandfox! Adorable!"
+ tt_desc = "Vulpes zerda"
icon = 'icons/mob/vore.dmi'
icon_state = "fennec"
icon_living = "fennec"
diff --git a/code/modules/mob/living/simple_animal/vore/frog.dm b/code/modules/mob/living/simple_animal/vore/frog.dm
index 45f73456e8..ae4389914b 100644
--- a/code/modules/mob/living/simple_animal/vore/frog.dm
+++ b/code/modules/mob/living/simple_animal/vore/frog.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/frog
name = "giant frog"
desc = "You've heard of having a frog in your throat, now get ready for the reverse."
+ tt_desc = "Anura gigantus"
icon = 'icons/mob/vore.dmi'
icon_dead = "frog-dead"
icon_living = "frog"
diff --git a/code/modules/mob/living/simple_animal/vore/gaslamp.dm b/code/modules/mob/living/simple_animal/vore/gaslamp.dm
index 121cc6acfc..8df8d216b4 100644
--- a/code/modules/mob/living/simple_animal/vore/gaslamp.dm
+++ b/code/modules/mob/living/simple_animal/vore/gaslamp.dm
@@ -13,6 +13,7 @@ TODO: Make them light up and heat the air when exposed to oxygen.
/mob/living/simple_animal/retaliate/gaslamp
name = "gaslamp"
desc = "Some sort of floaty alien with a warm glow. This creature is endemic to Virgo-3B."
+ tt_desc = "Semaeostomeae virginus"
icon = 'icons/mob/vore32x64.dmi'
icon_state = "gaslamp"
icon_living = "gaslamp"
diff --git a/code/modules/mob/living/simple_animal/vore/horse.dm b/code/modules/mob/living/simple_animal/vore/horse.dm
index 35d8603094..59bbfa4550 100644
--- a/code/modules/mob/living/simple_animal/vore/horse.dm
+++ b/code/modules/mob/living/simple_animal/vore/horse.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/horse
name = "horse"
desc = "Don't look it in the mouth."
+ tt_desc = "Equus ferus caballus"
icon = 'icons/mob/vore.dmi'
icon_state = "horse"
icon_living = "horse"
diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm
index eb814c5425..184ab76888 100644
--- a/code/modules/mob/living/simple_animal/vore/otie.dm
+++ b/code/modules/mob/living/simple_animal/vore/otie.dm
@@ -6,6 +6,7 @@
/mob/living/simple_animal/otie //Spawn this one only if you're looking for a bad time. Not friendly.
name = "otie"
desc = "The classic bioengineered longdog."
+ tt_desc = "Canis otis"
icon = 'icons/mob/vore64x32.dmi'
icon_state = "otie"
icon_living = "otie"
diff --git a/code/modules/mob/living/simple_animal/vore/panther.dm b/code/modules/mob/living/simple_animal/vore/panther.dm
index f22fd275a1..3e723e68fc 100644
--- a/code/modules/mob/living/simple_animal/vore/panther.dm
+++ b/code/modules/mob/living/simple_animal/vore/panther.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/panther
name = "panther"
desc = "Runtime's larger, less cuddly cousin."
+ tt_desc = "Panthera pardus"
icon = 'icons/mob/vore64x64.dmi'
icon_state = "panther"
icon_living = "panther"
diff --git a/code/modules/mob/living/simple_animal/vore/wah.dm b/code/modules/mob/living/simple_animal/vore/wah.dm
index b0fd4887bf..316441edd7 100644
--- a/code/modules/mob/living/simple_animal/vore/wah.dm
+++ b/code/modules/mob/living/simple_animal/vore/wah.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/wah
name = "red panda"
desc = "It's a wah! Beware of doom pounce!"
+ tt_desc = "Ailurus fulgens"
icon = 'icons/mob/vore.dmi'
icon_state = "wah"
icon_living = "wah"
@@ -39,6 +40,7 @@
/mob/living/simple_animal/wah/fae
name = "dark wah"
desc = "Ominous, but still cute!"
+ tt_desc = "Ailurus brattus"
icon_state = "wah_fae"
icon_living = "wah_fae"
diff --git a/code/modules/mob/living/simple_animal/vore/wolf.dm b/code/modules/mob/living/simple_animal/vore/wolf.dm
index e503847030..fe3a970ac0 100644
--- a/code/modules/mob/living/simple_animal/vore/wolf.dm
+++ b/code/modules/mob/living/simple_animal/vore/wolf.dm
@@ -1,6 +1,7 @@
/mob/living/simple_animal/hostile/wolf
name = "grey wolf"
desc = "My, what big jaws it has!"
+ tt_desc = "Canis lupus"
icon = 'icons/mob/vore.dmi'
icon_dead = "wolf-dead"
icon_living = "wolf"
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index cf50a44f85..9f316ba184 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -58,3 +58,7 @@
//set macro to normal incase it was overriden (like cyborg currently does)
client.set_hotkeys_macro("macro", "hotkeymode")
+
+ if(!client.tooltips)
+ client.tooltips = new(client)
+
\ No newline at end of file
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 2b2600b658..cb3dc7e2ab 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1143,3 +1143,14 @@ mob/proc/yank_out_object()
//Throwing stuff
/mob/proc/throw_item(atom/target)
return
+
+/mob/MouseEntered(location, control, params)
+ if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips))
+ openToolTip(user = usr, tip_src = src, params = params, title = get_nametag_name(usr), content = get_nametag_desc(usr))
+
+ ..()
+
+/mob/MouseExited()
+ closeToolTip(usr) //No reason not to, really
+
+ ..()
diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm
new file mode 100644
index 0000000000..1b03157e83
--- /dev/null
+++ b/code/modules/tooltip/tooltip.dm
@@ -0,0 +1,124 @@
+/*
+Tooltips v1.1 - 22/10/15
+Developed by Wire (#goonstation on irc.synirc.net)
+- Added support for screen_loc pixel offsets. Should work. Maybe.
+- Added init function to more efficiently send base vars
+
+Configuration:
+- Set control to the correct skin element (remember to actually place the skin element)
+- Set file to the correct path for the .html file (remember to actually place the html file)
+- Attach the datum to the user client on login, e.g.
+/client/New()
+ src.tooltips = new /datum/tooltip(src)
+
+Usage:
+- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively:
+/obj/screen/hud
+ MouseEntered(location, control, params)
+ usr.client.tooltip.show(params, title = src.name, content = src.desc)
+
+ MouseExited()
+ usr.client.tooltip.hide()
+
+Customization:
+- Theming can be done by passing the theme var to show() and using css in the html file to change the look
+- For your convenience some pre-made themes are included
+
+Notes:
+- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man.
+- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck!
+ - After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13
+*/
+
+
+/datum/tooltip
+ var/client/owner
+ var/control = "mainwindow.tooltip"
+ var/showing = 0
+ var/queueHide = 0
+ var/init = 0
+
+
+/datum/tooltip/New(client/C)
+ if (C)
+ owner = C
+ owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]")
+ ..()
+
+
+/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none")
+ if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size))
+ return 0
+ if (!init)
+ //Initialize some vars
+ init = 1
+ owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init")
+
+ showing = 1
+
+ if (title && content)
+ title = "[title]
"
+ content = "[content]
"
+ else if (title && !content)
+ title = "[title]
"
+ else if (!title && content)
+ content = "[content]
"
+
+ // Strip macros from item names
+ title = replacetext(title, "\proper", "")
+ title = replacetext(title, "\improper", "")
+
+ //Make our dumb param object
+ if(params[1] != "i") //Byond Bug: http://www.byond.com/forum/?post=2352648
+ params = "icon-x=16;icon-y=16;[params]" //Put in some placeholders
+ params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"}
+
+ //Send stuff to the tooltip
+ var/view_size = getviewsize(owner.view)
+ owner << output(list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update")
+
+ //If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips
+ showing = 0
+ if (queueHide)
+ hide()
+
+ return 1
+
+
+/datum/tooltip/proc/hide()
+ if (queueHide)
+ schedule_task_with_source_in(1, src, .proc/do_hide)
+ else
+ do_hide()
+
+ queueHide = showing ? TRUE : FALSE
+
+ return TRUE
+
+/datum/tooltip/proc/do_hide()
+ winshow(owner, control, FALSE)
+
+/* TG SPECIFIC CODE */
+
+
+//Open a tooltip for user, at a location based on params
+//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc)
+//Includes sanity.checks
+/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "")
+ if(istype(user))
+ if(user.client && user.client.tooltips)
+ if(!theme && user.client.prefs && user.client.prefs.tooltipstyle)
+ theme = lowertext(user.client.prefs.tooltipstyle)
+ if(!theme)
+ theme = "midnight"
+ user.client.tooltips.show(tip_src, params, title, content, theme)
+
+
+//Arbitrarily close a user's tooltip
+//Includes sanity checks.
+/proc/closeToolTip(mob/user)
+ if(istype(user))
+ if(user.client && user.client.tooltips)
+ user.client.tooltips.hide()
+
+
diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html
new file mode 100644
index 0000000000..67fb8a77f1
--- /dev/null
+++ b/code/modules/tooltip/tooltip.html
@@ -0,0 +1,249 @@
+
+
+
+ Tooltip
+
+
+
+
+
+
+
+
+
+
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 0bfc8524ae..ea7d069105 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1940,6 +1940,14 @@ window "mainwindow"
is-checked = false
group = ""
button-type = pushbox
+ elem "tooltip"
+ type = BROWSER
+ pos = 0,0
+ size = 999x999
+ anchor1 = none
+ anchor2 = none
+ is-visible = false
+ saved-params = ""
window "mapwindow"
elem "mapwindow"
diff --git a/vorestation.dme b/vorestation.dme
index e780d3caf8..4a792be2d3 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -2648,6 +2648,7 @@
#include "code\modules\telesci\telepad.dm"
#include "code\modules\telesci\telesci_computer.dm"
#include "code\modules\tension\tension.dm"
+#include "code\modules\tooltip\tooltip.dm"
#include "code\modules\turbolift\_turbolift.dm"
#include "code\modules\turbolift\turbolift.dm"
#include "code\modules\turbolift\turbolift_areas.dm"