Merge pull request #4221 from tigercat2000/tgalerts

-tg- screen alerts
This commit is contained in:
TheDZD
2016-04-19 19:13:31 -04:00
54 changed files with 1764 additions and 1178 deletions
+4 -1
View File
@@ -81,4 +81,7 @@
control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
var/datum/click_intercept/click_intercept = null
var/datum/click_intercept/click_intercept = null
//datum that controls the displaying and hiding of tooltips
var/datum/tooltip/tooltips
+4
View File
@@ -317,6 +317,10 @@
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
//////////////
//DISCONNECT//
//////////////
@@ -248,6 +248,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source)
if(message)
to_chat(src, "<span class='ghostalert'>[message]</span>")
if(source)
var/obj/screen/alert/A = throw_alert("\ref[source]_notify_cloning", /obj/screen/alert/notify_cloning)
if(A)
if(client && client.prefs && client.prefs.UI_style)
A.icon = ui_style2icon(client.prefs.UI_style)
A.desc = message
var/old_layer = source.layer
source.layer = FLOAT_LAYER
A.overlays += source
source.layer = old_layer
to_chat(src, "<span class='ghostalert'><a href=?src=\ref[src];reenter=1>(Click to re-enter)</a></span>")
if(sound)
to_chat(src, sound(sound))
@@ -563,6 +573,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
forceMove(T)
following = null
if(href_list["reenter"])
reenter_corpse()
..()
//END TELEPORT HREF CODE
@@ -102,22 +102,19 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > 360.15)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
throw_alert("alien_fire", /obj/screen/alert/alien_fire)
switch(bodytemperature)
if(360 to 400)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
fire_alert = max(fire_alert, 2)
if(400 to 460)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
fire_alert = max(fire_alert, 2)
if(460 to INFINITY)
if(on_fire)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
fire_alert = max(fire_alert, 2)
else
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
fire_alert = max(fire_alert, 2)
return
else
clear_alert("alien_fire")
/mob/living/carbon/alien/handle_mutations_and_radiation()
// Aliens love radiation nom nom nom
@@ -343,6 +343,10 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/humanoid/canBeHandcuffed()
return 1
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
..(I, cuff_break = 1)
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
if(leaping)
return -32
+4 -12
View File
@@ -7,19 +7,19 @@
return 0
var/toxins_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/breath_pressure = (breath.total_moles() * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.toxins / breath.total_moles()) * breath_pressure
if(Toxins_pp) // Detect toxins in air
adjustPlasma(breath.toxins*250)
toxins_alert = max(toxins_alert, 1)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath.toxins
else
toxins_alert = 0
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath.toxins -= toxins_used
@@ -30,14 +30,6 @@
return 1
/mob/living/carbon/alien/handle_breath_temperature(datum/gas_mixture/breath)
if(breath.temperature > (T0C + 66) && !(RESIST_COLD in mutations))
if(prob(20))
to_chat(src, "<span class='danger'>You feel a searing heat in your lungs!</span>")
fire_alert = max(fire_alert, 1)
else
fire_alert = 0
/mob/living/carbon/alien/update_sight()
if(stat == DEAD || (XRAY in mutations))
sight |= SEE_TURFS
@@ -47,8 +47,6 @@
for(var/mob/dead/observer/O in player_list)
if(check_observer(O))
to_chat(O, "<span class='boldnotice'>\A [src] has been activated. (<a href='?src=\ref[O];jump=\ref[src]'>Teleport</a> | <a href='?src=\ref[src];signup=\ref[O]'>Sign Up</a>)</span>")
// if(ROLE_POSIBRAIN in O.client.prefs.be_special) The Guardian implementation looks cleaner
// question(O.client)
/obj/item/device/mmi/posibrain/proc/check_observer(var/mob/dead/observer/O)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
+127 -2
View File
@@ -607,7 +607,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob()
update_inv_handcuffed()
update_handcuffed()
else if(I == legcuffed)
legcuffed = null
update_inv_legcuffed()
@@ -732,6 +732,131 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/is_muzzled()
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
/mob/living/carbon/proc/spin(spintime, speed)
spawn()
var/D = dir
while(spintime >= speed)
sleep(speed)
switch(D)
if(NORTH)
D = EAST
if(SOUTH)
D = WEST
if(EAST)
D = SOUTH
if(WEST)
D = NORTH
dir = D
spintime -= speed
/mob/living/carbon/resist_buckle()
if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
visible_message("<span class='warning'>[src] attempts to unbuckle themself!</span>", \
"<span class='notice'>You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)</span>")
if(do_after(src, 600, 0, target = src))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
else
if(src && buckled)
src << "<span class='warning'>You fail to unbuckle yourself!</span>"
else
buckled.user_unbuckle_mob(src,src)
/mob/living/carbon/resist_fire()
fire_stacks -= 5
weakened = max(weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
update_canmove()
spin(32,2)
visible_message("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
sleep(30)
if(fire_stacks <= 0)
visible_message("<span class='danger'>[src] has successfully extinguished themselves!</span>", \
"<span class='notice'>You extinguish yourself.</span>")
ExtinguishMob()
/mob/living/carbon/resist_restraints()
var/obj/item/I = null
if(handcuffed)
I = handcuffed
else if(legcuffed)
I = legcuffed
if(I)
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
cuff_resist(I)
/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0)
breakouttime = I.breakouttime
var/displaytime = breakouttime / 600
if(!cuff_break)
visible_message("<span class='warning'>[src] attempts to remove [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)</span>")
if(do_after(src, breakouttime, 0, target = src))
if(I.loc != src || buckled)
return
visible_message("<span class='danger'>[src] manages to remove [I]!</span>")
to_chat(src, "<span class='notice'>You successfully remove [I].</span>")
if(I == handcuffed)
handcuffed.loc = loc
handcuffed.dropped(src)
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
update_handcuffed()
return
if(I == legcuffed)
legcuffed.loc = loc
legcuffed.dropped()
legcuffed = null
update_inv_legcuffed()
return
return 1
else
to_chat(src, "<span class='warning'>You fail to remove [I]!</span>")
else
breakouttime = 50
visible_message("<span class='warning'>[src] is trying to break [I]!</span>")
to_chat(src, "<span class='notice'>You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)</span>")
if(do_after(src, breakouttime, 0, target = src))
if(!I.loc || buckled)
return
visible_message("<span class='danger'>[src] manages to break [I]!</span>")
to_chat(src, "<span class='notice'>You successfully break [I].</span>")
qdel(I)
if(I == handcuffed)
handcuffed = null
update_handcuffed()
return
else if(I == legcuffed)
legcuffed = null
update_inv_legcuffed()
return
return 1
else
to_chat(src, "<span class='warning'>You fail to break [I]!</span>")
//called when we get cuffed/uncuffed
/mob/living/carbon/proc/update_handcuffed()
if(handcuffed)
drop_r_hand()
drop_l_hand()
stop_pulling()
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
else
clear_alert("handcuffed")
update_action_buttons() //some of our action buttons might be unusable when we're handcuffed.
update_inv_handcuffed()
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
if(lying)
if(buckled) return initial(pixel_y)
@@ -765,7 +890,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
handcuffed = null
if (buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob()
update_inv_handcuffed()
update_handcuffed()
if (client)
client.screen -= W
if (W)
@@ -1348,6 +1348,15 @@
update_inv_shoes(1)
return 1
/mob/living/carbon/human/cuff_resist(obj/item/I)
if(HULK in mutations)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
if(..(I, cuff_break = 1))
unEquip(I)
else
if(..())
unEquip(I)
/mob/living/carbon/human/get_visible_implants(var/class = 0)
var/list/visible_implants = list()
+22 -22
View File
@@ -369,8 +369,7 @@
var/obj/item/organ/external/affected = get_organ("chest")
affected.add_autopsy_data("Suffocation", oxyloss)
oxygen_alert = max(oxygen_alert, 1)
throw_alert("oxy", /obj/screen/alert/oxy)
return 0
@@ -384,7 +383,7 @@
// to_chat(world, "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Thermal protection: [get_thermal_protection()] - Fire protection: [thermal_protection + add_fire_protection(loc_temp)] - Heat capacity: [environment_heat_capacity] - Location: [loc] - src: [src]")
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
if(stat != 2)
if(stat != DEAD)
stabilize_temperature_from_calories()
//After then, it reacts to the surrounding atmosphere based on your thermal protection
@@ -403,41 +402,43 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > species.heat_level_1)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
var/mult = species.hot_env_multiplier
if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2)
throw_alert("temp", /obj/screen/alert/hot, 1)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3)
throw_alert("temp", /obj/screen/alert/hot, 2)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY)
throw_alert("temp", /obj/screen/alert/hot, 3)
if(on_fire)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
fire_alert = max(fire_alert, 2)
else
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
else if(bodytemperature < species.cold_level_1)
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
if(stat == DEAD) return 1 //ZomgPonies -- No need for cold burn damage if dead
if(status_flags & GODMODE)
return 1
if(stat == DEAD)
return 1
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/mult = species.cold_env_multiplier
if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1)
throw_alert("temp", /obj/screen/alert/cold, 1)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2)
throw_alert("temp", /obj/screen/alert/cold, 2)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3)
throw_alert("temp", /obj/screen/alert/cold, 3)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
else
clear_alert("temp")
else
clear_alert("temp")
// Account for massive pressure differences. Done by Polymorph
// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!
@@ -449,21 +450,20 @@
if(adjusted_pressure >= species.hazard_high_pressure)
var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
pressure_alert = 2
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else if(adjusted_pressure >= species.warning_high_pressure)
pressure_alert = 1
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
else if(adjusted_pressure >= species.warning_low_pressure)
pressure_alert = 0
clear_alert("pressure")
else if(adjusted_pressure >= species.hazard_low_pressure)
pressure_alert = -1
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
else
if(RESIST_COLD in mutations)
pressure_alert = -1
clear_alert("pressure")
else
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
pressure_alert = -2
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
return
///FIRE CODE
/mob/living/carbon/human/handle_fire()
@@ -52,6 +52,19 @@
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/list/atmos_requirements = list(
"min_oxy" = 16,
"max_oxy" = 0,
"min_nitro" = 0,
"max_nitro" = 0,
"min_tox" = 0,
"max_tox" = 0.005,
"min_co2" = 0,
"max_co2" = 10,
"sa_para" = 1,
"sa_sleep" = 5
)
var/brute_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
@@ -181,66 +194,105 @@
O.owner = H
/datum/species/proc/handle_breath(var/datum/gas_mixture/breath, var/mob/living/carbon/human/H)
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
//var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now)
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_max = 0.005
var/SA_para_min = 1
var/SA_sleep_min = 5
var/oxygen_used = 0
var/nitrogen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/vox_oxygen_max = 1 // For vox.
var/O2_used = 0
var/N2_used = 0
var/Tox_used = 0
var/CO2_used = 0
//Partial pressure of the O2 in our breath
var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
// Same, but for the toxins
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
// And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure // Tweaking to fit the hacky bullshit I've done with atmo -- TLE
// Nitrogen, for Vox.
var/Nitrogen_pp = (breath.nitrogen/breath.total_moles())*breath_pressure
var/O2_pp = (breath.oxygen/breath.total_moles()) * breath_pressure
// Partial pressure of Nitrogen
var/N2_pp = (breath.nitrogen/breath.total_moles()) * breath_pressure
// Partial pressure of plasma
var/Tox_pp = (breath.toxins/breath.total_moles()) * breath_pressure
// Partial pressure of CO2
var/CO2_pp = (breath.carbon_dioxide/breath.total_moles()) * breath_pressure
// TODO: Split up into Voxs' own proc.
if(O2_pp < safe_oxygen_min && name != "Vox") // Too little oxygen
if(O2_pp < atmos_requirements["min_oxy"])
if(prob(20))
spawn(0)
H.emote("gasp")
H.failed_last_breath = 1
if(O2_pp > 0)
var/ratio = safe_oxygen_min/O2_pp
H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
H.failed_last_breath = 1
oxygen_used = breath.oxygen*ratio/6
var/ratio = atmos_requirements["min_oxy"] / O2_pp
H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.failed_last_breath = 1
H.oxygen_alert = max(H.oxygen_alert, 1)
else if(Nitrogen_pp < safe_oxygen_min && name == "Vox") //Vox breathe nitrogen, not oxygen.
H.throw_alert("oxy", /obj/screen/alert/oxy)
else if(atmos_requirements["max_oxy"] && O2_pp > atmos_requirements["max_oxy"])
var/ratio = (breath.oxygen / atmos_requirements["max_oxy"]) * 1000
H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
H.throw_alert("oxy", /obj/screen/alert/too_much_oxy)
else
H.clear_alert("oxy")
if(atmos_requirements["min_oxy"]) //species breathes this gas, so, they got their air
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
O2_used = breath.oxygen / 6
if(N2_pp < atmos_requirements["min_nitro"])
if(prob(20))
spawn(0) H.emote("gasp")
if(Nitrogen_pp > 0)
var/ratio = safe_oxygen_min/Nitrogen_pp
H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS))
H.failed_last_breath = 1
nitrogen_used = breath.nitrogen*ratio/6
spawn(0)
H.emote("gasp")
H.failed_last_breath = 1
if(N2_pp > 0)
var/ratio = atmos_requirements["min_nitro"] / N2_pp
H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.failed_last_breath = 1
H.oxygen_alert = max(H.oxygen_alert, 1)
H.throw_alert("nitro", /obj/screen/alert/nitro)
else if(atmos_requirements["max_nitro"] && N2_pp > atmos_requirements["max_nitro"])
var/ratio = (breath.nitrogen / atmos_requirements["max_nitro"]) * 1000
H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
H.throw_alert("nitro", /obj/screen/alert/too_much_nitro)
else
H.clear_alert("nitro")
if(atmos_requirements["min_nitro"]) //species breathes this gas, so they got their air
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
N2_used = breath.nitrogen / 6
else // We're in safe limits
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
oxygen_used = breath.oxygen/6
H.oxygen_alert = 0
if(Tox_pp < atmos_requirements["min_tox"])
if(prob(20))
spawn(0)
H.emote("gasp")
breath.oxygen -= oxygen_used
breath.nitrogen -= nitrogen_used
breath.carbon_dioxide += oxygen_used
H.failed_last_breath = 1
if(Tox_pp > 0)
var/ratio = atmos_requirements["min_tox"] / Tox_pp
H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.throw_alert("tox_in_air", /obj/screen/alert/not_enough_tox)
else if(atmos_requirements["max_tox"] && Tox_pp > atmos_requirements["max_tox"])
var/ratio = (breath.toxins / atmos_requirements["max_tox"]) * 10
if(H.reagents)
H.reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
H.clear_alert("tox_in_air")
if(atmos_requirements["min_tox"]) //species breathes this gas, so, they got their air
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
Tox_used = breath.toxins / 6
//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
if(CO2_pp > safe_co2_max)
if(CO2_pp < atmos_requirements["min_co2"])
if(prob(20))
spawn(0)
H.emote("gasp")
H.failed_last_breath = 1
if(CO2_pp)
var/ratio = atmos_requirements["min_co2"] / CO2_pp
H.adjustOxyLoss(min(5 * ratio, HUMAN_MAX_OXYLOSS))
else
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS)
H.throw_alert("co2", /obj/screen/alert/not_enough_co2)
else if(atmos_requirements["max_co2"] && CO2_pp > atmos_requirements["max_co2"])
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
@@ -249,38 +301,35 @@
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.adjustOxyLoss(8)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
spawn(0) H.emote("cough")
spawn(0)
H.emote("cough")
else
H.co2overloadtime = 0
H.clear_alert("co2")
if(atmos_requirements["min_co2"]) //species breathes this gas, so they got their air
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
CO2_used = breath.carbon_dioxide / 6
if(Toxins_pp > safe_toxins_max) // Too much toxins
var/ratio = (breath.toxins/safe_toxins_max) * 10
//adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second
if(H.reagents)
H.reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
H.toxins_alert = max(H.toxins_alert, 1)
breath.oxygen -= O2_used
breath.nitrogen -= N2_used
breath.toxins -= Tox_used
breath.carbon_dioxide -= CO2_used
breath.carbon_dioxide += O2_used
else if(O2_pp > vox_oxygen_max && name == "Vox") //Oxygen is toxic to vox.
var/ratio = (breath.oxygen/vox_oxygen_max) * 1000
H.adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
H.toxins_alert = max(H.toxins_alert, 1)
else
H.toxins_alert = 0
if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
var/SA_pp = (SA.moles / breath.total_moles()) * breath_pressure
if(SA_pp > atmos_requirements["sa_para"]) // Enough to make us paralysed for a bit
H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
H.sleeping = max(H.sleeping+2, 10)
if(SA_pp > atmos_requirements["sa_sleep"]) // Enough to make us sleep as well
H.sleeping = max(H.sleeping + 2, 10)
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
spawn(0) H.emote(pick("giggle", "laugh"))
spawn(0)
H.emote(pick("giggle", "laugh"))
handle_temperature(breath, H)
return 1
/datum/species/proc/handle_temperature(datum/gas_mixture/breath, var/mob/living/carbon/human/H) // called by human/life, handles temperatures
@@ -288,38 +337,31 @@
if(H.status_flags & GODMODE) return 1 //godmode
if(breath.temperature < cold_level_1)
if(prob(20))
to_chat(H, "\red You feel your face freezing and an icicle forming in your lungs!")
to_chat(H, "<span class='warning'>You feel your face freezing and an icicle forming in your lungs!</span>")
else if(breath.temperature > heat_level_1)
if(prob(20))
to_chat(H, "\red You feel your face burning and a searing heat in your lungs!")
to_chat(H, "<span class='warning'>You feel your face burning and a searing heat in your lungs!</span>")
switch(breath.temperature)
if(-INFINITY to cold_level_3)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(cold_level_3 to cold_level_2)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(cold_level_2 to cold_level_1)
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(heat_level_1 to heat_level_2)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
if(heat_level_2 to heat_level_3_breathe)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
if(heat_level_3_breathe to INFINITY)
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
grant_abilities(C)
@@ -528,10 +570,10 @@
if(H.blinded || H.eye_blind)
H.overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
//H.throw_alert("blind", /obj/screen/alert/blind)
H.throw_alert("blind", /obj/screen/alert/blind)
else
H.clear_fullscreen("blind")
//H.clear_alert("blind")
H.clear_alert("blind")
if(H.disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
@@ -553,10 +595,10 @@
if(H.druggy)
H.overlay_fullscreen("high", /obj/screen/fullscreen/high)
//H.throw_alert("high", /obj/screen/alert/high)
H.throw_alert("high", /obj/screen/alert/high)
else
H.clear_fullscreen("high")
//H.clear_alert("high")
H.clear_alert("high")
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(H.healths)
@@ -603,59 +645,15 @@
if(icon_num)
H.healthdoll.overlays += image('icons/mob/screen_gen.dmi',"[O.limb_name][icon_num]")
if(H.nutrition_icon)
switch(H.nutrition)
if(450 to INFINITY) H.nutrition_icon.icon_state = "nutrition0"
if(350 to 450) H.nutrition_icon.icon_state = "nutrition1"
if(250 to 350) H.nutrition_icon.icon_state = "nutrition2"
if(150 to 250) H.nutrition_icon.icon_state = "nutrition3"
else H.nutrition_icon.icon_state = "nutrition4"
// BAY SHIT
if(H.pressure)
H.pressure.icon_state = "pressure[H.pressure_alert]"
if(H.toxin)
if(H.hal_screwyhud == 4 || H.toxins_alert) H.toxin.icon_state = "tox1"
else H.toxin.icon_state = "tox0"
if(H.oxygen)
if(H.hal_screwyhud == 3 || H.oxygen_alert) H.oxygen.icon_state = "oxy1"
else H.oxygen.icon_state = "oxy0"
if(H.fire)
if(H.fire_alert) H.fire.icon_state = "fire[H.fire_alert]" //fire_alert is either 0 if no alert, 1 for cold and 2 for heat.
else H.fire.icon_state = "fire0"
if(H.bodytemp)
var/temp_step
if(H.bodytemperature >= body_temperature)
temp_step = (heat_level_1 - body_temperature)/4
if(H.bodytemperature >= heat_level_1)
H.bodytemp.icon_state = "temp4"
else if(H.bodytemperature >= body_temperature + temp_step*3)
H.bodytemp.icon_state = "temp3"
else if(H.bodytemperature >= body_temperature + temp_step*2)
H.bodytemp.icon_state = "temp2"
else if(H.bodytemperature >= body_temperature + temp_step*1)
H.bodytemp.icon_state = "temp1"
else
H.bodytemp.icon_state = "temp0"
else if(H.bodytemperature < body_temperature)
temp_step = (body_temperature - cold_level_1)/4
if(H.bodytemperature <= cold_level_1)
H.bodytemp.icon_state = "temp-4"
else if(H.bodytemperature <= body_temperature - temp_step*3)
H.bodytemp.icon_state = "temp-3"
else if(H.bodytemperature <= body_temperature - temp_step*2)
H.bodytemp.icon_state = "temp-2"
else if(H.bodytemperature <= body_temperature - temp_step*1)
H.bodytemp.icon_state = "temp-1"
else
H.bodytemp.icon_state = "temp0"
switch(H.nutrition)
if(450 to INFINITY)
H.throw_alert("nutrition", /obj/screen/alert/fat)
if(350 to 450)
H.clear_alert("nutrition")
if(250 to 350)
H.throw_alert("nutrition", /obj/screen/alert/hungry)
else
H.throw_alert("nutrition", /obj/screen/alert/starving)
return 1
/*
@@ -226,6 +226,19 @@
cold_level_2 = 50
cold_level_3 = 0
atmos_requirements = list(
"min_oxy" = 0,
"max_oxy" = 1,
"min_nitro" = 16,
"max_nitro" = 0,
"min_tox" = 0,
"max_tox" = 0.005,
"min_co2" = 0,
"max_co2" = 10,
"sa_para" = 1,
"sa_sleep" = 5
)
eyes = "vox_eyes_s"
breath_type = "nitrogen"
@@ -989,16 +989,19 @@ var/global/list/damage_icon_parts = list()
update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
clear_alert("legcuffed")
if(legcuffed)
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
if(src.m_intent != "walk")
src.m_intent = "walk"
if(src.hud_used && src.hud_used.move_intent)
src.hud_used.move_intent.icon_state = "walking"
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = src.legcuffed)
if(m_intent != "walk")
m_intent = "walk"
if(hud_used && hud_used.move_intent)
hud_used.move_intent.icon_state = "walking"
else
overlays_standing[LEGCUFF_LAYER] = null
if(update_icons) update_icons()
if(update_icons)
update_icons()
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
+5 -8
View File
@@ -95,8 +95,7 @@
if(!breath || (breath.total_moles() == 0))
adjustOxyLoss(1)
failed_last_breath = 1
oxygen_alert = max(oxygen_alert, 1)
throw_alert("oxy", /obj/screen/alert/oxy)
return 0
var/safe_oxy_min = 16
@@ -125,13 +124,13 @@
else
adjustOxyLoss(3)
failed_last_breath = 1
oxygen_alert = max(oxygen_alert, 1)
throw_alert("oxy", /obj/screen/alert/oxy)
else //Enough oxygen
failed_last_breath = 0
adjustOxyLoss(-5)
oxygen_used = breath.oxygen/6
oxygen_alert = 0
clear_alert("oxy")
breath.oxygen -= oxygen_used
breath.carbon_dioxide += oxygen_used
@@ -147,9 +146,7 @@
adjustOxyLoss(8)
if(prob(20))
spawn(0) emote("cough")
co2_alert = max(co2_alert, 1)
else
co2_alert = 0
co2overloadtime = 0
//TOXINS/PLASMA
@@ -157,9 +154,9 @@
var/ratio = (breath.toxins/safe_tox_max) * 10
if(reagents)
reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
toxins_alert = max(toxins_alert, 1)
throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
toxins_alert = 0
clear_alert("tox_in_air")
//TRACE GASES
if(breath.trace_gases.len)
+7 -4
View File
@@ -155,6 +155,9 @@
/mob/living/proc/handle_sleeping()
if(sleeping)
AdjustSleeping(-1)
throw_alert("asleep", /obj/screen/alert/asleep)
else
clear_alert("asleep")
return sleeping
@@ -193,10 +196,10 @@
return
if(blinded || eye_blind)
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
//throw_alert("blind", /obj/screen/alert/blind)
throw_alert("blind", /obj/screen/alert/blind)
else
clear_fullscreen("blind")
//clear_alert("blind")
clear_alert("blind")
if(disabilities & NEARSIGHTED)
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
@@ -210,10 +213,10 @@
if(druggy)
overlay_fullscreen("high", /obj/screen/fullscreen/high)
//throw_alert("high", /obj/screen/alert/high)
throw_alert("high", /obj/screen/alert/high)
else
clear_fullscreen("high")
//clear_alert("high")
clear_alert("high")
if(machine)
if(!machine.check_eye(src))
+42 -226
View File
@@ -522,262 +522,74 @@
set name = "Resist"
set category = "IC"
if(!isliving(usr) || usr.next_move > world.time)
if(!isliving(src) || next_move > world.time || stat || weakened || stunned || paralysis)
return
usr.changeNext_move(CLICK_CD_RESIST)
changeNext_move(CLICK_CD_RESIST)
var/mob/living/L = usr
//Resisting control by an alien mind.
if(istype(src.loc,/mob/living/simple_animal/borer))
resist_borer()
//resisting grabs (as if it helps anyone...)
if ((!(L.stat) && !(L.restrained())))
resist_grab(L) //this passes L because the proc requires a typecasted mob/living instead of just 'src'
if(!restrained())
if(resist_grab())
return
//unbuckling yourself
if(L.buckled && (L.last_special <= world.time) )
resist_buckle(L) //this passes L because the proc requires a typecasted mob/living instead of just 'src'
if(buckled && last_special <= world.time)
resist_buckle()
//Breaking out of an object?
else if(src.loc && istype(src.loc, /obj) && (!isturf(src.loc)))
if(stat == CONSCIOUS && !stunned && !weakened && !paralysis)
var/obj/C = loc
C.container_resist(L)
//Breaking out of a container (Locker, sleeper, cryo...)
else if(isobj(loc))
var/obj/C = loc
C.container_resist(src)
//breaking out of handcuffs
else if(iscarbon(L))
var/mob/living/carbon/CM = L
if(CM.on_fire && CM.canmove)
resist_stop_drop_roll(CM) //this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time))//this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
resist_handcuffs(CM)
else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time)) //this passes CM because the proc requires a typecasted mob/living/carbon instead of just 'src'
resist_legcuffs(CM)
else if(canmove)
if(on_fire)
resist_fire() //stop, drop, and roll
else if(last_special <= world.time)
resist_restraints() //trying to remove cuffs.
/*////////////////////
RESIST SUBPROCS
*/////////////////////
/* resist_borer allows a mob to regain control of their body after a borer has assumed control.
*/////
/mob/living/proc/resist_borer()
var/mob/living/simple_animal/borer/B = src.loc
var/mob/living/captive_brain/H = src
to_chat(H, "\red <B>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</B>")
to_chat(B.host, "\red <B>You feel the captive mind of [src] begin to resist your control.</B>")
spawn(rand(350,450)+B.host.brainloss)
if(!B || !B.controlling)
return
B.host.adjustBrainLoss(rand(5,10))
to_chat(H, "\red <B>With an immense exertion of will, you regain control of your body!</B>")
to_chat(B.host, "\red <B>You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.</b>")
B.detatch()
verbs -= /mob/living/carbon/proc/release_control
verbs -= /mob/living/carbon/proc/punish_host
verbs -= /mob/living/carbon/proc/spawn_larvae
return
/* resist_grab allows a mob to resist a grab from another mob when disarming is not an option/neckgrabbed.
*/////
/mob/living/proc/resist_grab(var/mob/living/L)
/mob/living/proc/resist_grab()
var/resisting = 0
for(var/obj/O in L.requests)
L.requests.Remove(O)
for(var/obj/O in requests)
qdel(O)
resisting++
for(var/obj/item/weapon/grab/G in usr.grabbed_by)
for(var/X in grabbed_by)
var/obj/item/weapon/grab/G = X
resisting++
if (G.state == 1)
qdel(G)
switch(G.state)
if(GRAB_PASSIVE)
qdel(G)
else
if(G.state == 2)
if(GRAB_AGGRESSIVE)
if(prob(60))
for(var/mob/O in viewers(L, null))
O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1)
visible_message("<span class='danger'>[src] has broken free of [G.assailant]'s grip!</span>")
qdel(G)
else
if(G.state == 3)
if(prob(5))
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1)
qdel(G)
if(GRAB_NECK)
if(prob(5))
visible_message("<span class='danger'>[src] has broken free of [G.assailant]'s headlock!</span>")
qdel(G)
if(resisting)
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red <B>[] resists!</B>", L), 1)
visible_message("<span class='danger'>[src] resists!</span>")
return 1
/* resist_buckle allows a mob that is bucklecuffed to break free of the chair/bed/whatever
*/////
/mob/living/proc/resist_buckle(var/mob/living/L)
if(iscarbon(L))
var/mob/living/carbon/C = L
if(C.handcuffed)
C.changeNext_move(CLICK_CD_BREAKOUT)
C.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(C, "\red You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stay still)</span>")
for(var/mob/O in viewers(L))
O.show_message("\red <B>[usr] attempts to unbuckle themself!</B>", 1)
spawn(0)
if(do_after(usr, 1200, target = C))
if(!C.buckled)
return
for(var/mob/O in viewers(C))
O.show_message("\red <B>[usr] manages to unbuckle themself!</B>", 1)
to_chat(C, "\blue You successfully unbuckle yourself.")
C.buckled.user_unbuckle_mob(C,C)
else
L.buckled.user_unbuckle_mob(L,L)
/* resist_stop_drop_roll allows a mob to stop, drop, and roll in order to put out a fire burning on them.
*/////
/mob/living/proc/resist_stop_drop_roll(var/mob/living/carbon/CM)
CM.fire_stacks -= 5
CM.weakened = max(CM.weakened, 3)//We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
CM.update_canmove()
CM.spin(32,2)
CM.visible_message("<span class='danger'>[CM] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
sleep(30)
if(fire_stacks <= 0)
CM.visible_message("<span class='danger'>[CM] has successfully extinguished themselves!</span>", \
"<span class='notice'>You extinguish yourself.</span>")
ExtinguishMob()
/mob/living/proc/resist_borer()
return
/* resist_handcuffs allows a mob to break/remove their handcuffs after a delay
*/////
/mob/living/proc/resist_handcuffs(var/mob/living/carbon/CM)
CM.changeNext_move(CLICK_CD_BREAKOUT)
CM.last_special = world.time + CLICK_CD_BREAKOUT
var/obj/item/weapon/restraints/handcuffs/HC = CM.handcuffed
/mob/living/proc/resist_buckle()
buckled.user_unbuckle_mob(src,src)
var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/restraints/handcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
/mob/living/proc/resist_fire()
return
var/hulklien = 0 //variable used to define if someone is a hulk or alien
if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
if(isalienadult(CM) || (HULK in usr.mutations))
hulklien = 1
breakouttime = 50
displaytime = 5
to_chat(CM, "\red You attempt to remove \the [HC]. (This will take around [displaytime] [hulklien ? "seconds" : "minute[displaytime==1 ? "" : "s"]"] and you need to stand still)")
for(var/mob/O in viewers(CM))
O.show_message( "\red <B>[usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!</B>", 1)
spawn(0)
if(do_after(CM, breakouttime, target = src))
if(!CM.handcuffed || CM.buckled)
return // time leniency for lag which also might make this whole thing pointless but the server
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to [hulklien ? "break" : "remove"] the handcuffs!</B>", 1)
to_chat(CM, "\blue You successfully [hulklien ? "break" : "remove"] \the [CM.handcuffed].")
if(hulklien)
CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
qdel(CM.handcuffed)
CM.handcuffed = null
if(CM.buckled && CM.buckled.buckle_requires_restraints)
CM.buckled.unbuckle_mob()
CM.update_inv_handcuffed()
return
CM.unEquip(CM.handcuffed)
/* resist_legcuffs allows a mob to break/remove their legcuffs after a delay
*/////
/mob/living/proc/resist_legcuffs(var/mob/living/carbon/CM)
var/obj/item/weapon/restraints/legcuffs/HC = CM.legcuffed
var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
var/hulklien = 0 //variable used to define if someone is a hulk or alien
if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
if(isalienadult(CM) || (HULK in usr.mutations))
hulklien = 1
breakouttime = 50
displaytime = 5
to_chat(CM, "\red You attempt to remove \the [HC]. (This will take around [displaytime] [hulklien ? "seconds" : "minute[displaytime==1 ? "" : "s"]"] and you need to stand still)")
for(var/mob/O in viewers(CM))
O.show_message( "\red <B>[usr] attempts to [hulklien ? "break" : "remove"] \the [HC]!</B>", 1)
spawn(0)
if(do_after(CM, breakouttime, target = src))
if(!CM.legcuffed || CM.buckled)
return // time leniency for lag which also might make this whole thing pointless but the server
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to [hulklien ? "break" : "remove"] the legcuffs!</B>", 1)
to_chat(CM, "\blue You successfully [hulklien ? "break" : "remove"] \the [CM.legcuffed].")
if(!hulklien)
CM.unEquip(CM.legcuffed)
if(hulklien)
CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
qdel(CM.legcuffed)
CM.legcuffed = null
CM.update_inv_legcuffed()
/mob/living/proc/resist_restraints()
return
/*//////////////////////
END RESIST PROCS
*///////////////////////
/mob/living/carbon/proc/spin(spintime, speed)
spawn()
var/D = dir
while(spintime >= speed)
sleep(speed)
switch(D)
if(NORTH)
D = EAST
if(SOUTH)
D = WEST
if(EAST)
D = SOUTH
if(WEST)
D = NORTH
dir = D
spintime -= speed
return
/mob/living/proc/Exhaust()
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
Weaken(5)
@@ -788,6 +600,10 @@
/mob/living/update_gravity(has_gravity)
if(!ticker)
return
if(has_gravity)
clear_alert("weightless")
else
throw_alert("weightless", /obj/screen/alert/weightless)
float(!has_gravity)
/mob/living/proc/float(on)
@@ -173,6 +173,7 @@
if(fire_stacks > 0 && !on_fire)
on_fire = 1
set_light(light_range + 3,l_color = "#ED9200")
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
/mob/living/proc/ExtinguishMob()
@@ -180,6 +181,7 @@
on_fire = 0
fire_stacks = 0
set_light(max(0,light_range - 3))
clear_alert("fire")
update_fire()
/mob/living/proc/update_fire()
+11 -3
View File
@@ -10,6 +10,7 @@
return laws.zeroth_law != null
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
if(!isnull(usr) && law)
@@ -21,42 +22,49 @@
to_chat(src, "<span class='warning'>Internal camera is currently being accessed.</span>")
/mob/living/silicon/proc/add_ion_law(var/law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_ion_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the ion law: [law]")
/mob/living/silicon/proc/add_inherent_law(var/law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_inherent_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the inherent law: [law]")
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.add_supplied_law(number, law)
if(!isnull(usr) && law)
log_and_message_admins("has given [src] the supplied law: [law]")
/mob/living/silicon/proc/delete_law(var/datum/ai_law/law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.delete_law(law)
if(!isnull(usr) && law)
log_and_message_admins("has deleted a law belonging to [src]: [law.law]")
/mob/living/silicon/proc/clear_inherent_laws(var/silent = 0)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_inherent_laws()
if(!silent && !isnull(usr))
log_and_message_admins("cleared the inherent laws of [src]")
/mob/living/silicon/proc/clear_ion_laws(var/silent = 0)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_ion_laws()
if(!silent && !isnull(usr))
log_and_message_admins("cleared the ion laws of [src]")
/mob/living/silicon/proc/clear_supplied_laws(var/silent = 0)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.clear_supplied_laws()
if(!silent && !isnull(usr))
@@ -108,10 +116,10 @@
/mob/living/silicon/proc/lawsync()
laws_sanity_check()
laws.sort_laws()
/mob/living/silicon/proc/make_laws()
switch(config.default_laws)
if(0)
if(0)
laws = new /datum/ai_laws/crewsimov()
else
laws = get_random_lawset()
@@ -122,6 +130,6 @@
for(var/law in paths)
var/datum/ai_laws/L = new law
if(!L.default)
continue
continue
law_options += L
return pick(law_options)
+37 -65
View File
@@ -176,6 +176,10 @@
/mob/living/silicon/robot/handle_hud_icons()
update_items()
update_cell()
if(emagged)
throw_alert("hacked", /obj/screen/alert/hacked)
else
clear_alert("hacked")
..()
/mob/living/silicon/robot/handle_hud_icons_health()
@@ -196,79 +200,47 @@
else
healths.icon_state = "health7"
if(bodytemp)
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
bodytemp.icon_state = "temp2"
if(320 to 335)
bodytemp.icon_state = "temp1"
if(300 to 320)
bodytemp.icon_state = "temp0"
if(260 to 300)
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp-2"
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
throw_alert("temp", /obj/screen/alert/hot/robot, 2)
if(320 to 335)
throw_alert("temp", /obj/screen/alert/hot/robot, 1)
if(300 to 320)
clear_alert("temp")
if(260 to 300)
throw_alert("temp", /obj/screen/alert/cold/robot, 1)
else
throw_alert("temp", /obj/screen/alert/cold/robot, 2)
/mob/living/silicon/robot/proc/update_cell()
if(cells)
if(cell)
var/cellcharge = cell.charge/cell.maxcharge
switch(cellcharge)
if(0.75 to INFINITY)
cells.icon_state = "charge4"
if(0.5 to 0.75)
cells.icon_state = "charge3"
if(0.25 to 0.5)
cells.icon_state = "charge2"
if(0 to 0.25)
cells.icon_state = "charge1"
else
cells.icon_state = "charge0"
else
cells.icon_state = "charge-empty"
/*/mob/living/silicon/robot/handle_regular_hud_updates()
// if(!client)
// return
//
// switch(sensor_mode)
// if(SEC_HUD)
// process_sec_hud(src,1)
// if(MED_HUD)
// process_med_hud(src,1)
if(syndicate)
if(ticker.mode.name == "traitor")
for(var/datum/mind/tra in ticker.mode.traitors)
if(tra.current)
var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor")
src.client.images += I
if(connected_ai)
connected_ai.connected_robots -= src
connected_ai = null
if(mind)
if(!mind.special_role)
mind.special_role = "traitor"
ticker.mode.traitors += src.mind
..()
return 1
*/
if(cell)
var/cellcharge = cell.charge/cell.maxcharge
switch(cellcharge)
if(0.75 to INFINITY)
clear_alert("charge")
if(0.5 to 0.75)
throw_alert("charge", /obj/screen/alert/lowcell, 1)
if(0.25 to 0.5)
throw_alert("charge", /obj/screen/alert/lowcell, 2)
if(0.01 to 0.25)
throw_alert("charge", /obj/screen/alert/lowcell, 3)
else
throw_alert("charge", /obj/screen/alert/emptycell)
else
throw_alert("charge", /obj/screen/alert/nocell)
/mob/living/silicon/robot/proc/update_items()
if (src.client)
if (client)
for(var/obj/I in get_all_slots())
client.screen |= I
if(src.module_state_1)
src.module_state_1:screen_loc = ui_inv1
if(src.module_state_2)
src.module_state_2:screen_loc = ui_inv2
if(src.module_state_3)
src.module_state_3:screen_loc = ui_inv3
if(module_state_1)
module_state_1:screen_loc = ui_inv1
if(module_state_2)
module_state_2:screen_loc = ui_inv2
if(module_state_3)
module_state_3:screen_loc = ui_inv3
update_icons()
/mob/living/silicon/robot/proc/process_locks()
@@ -17,7 +17,6 @@ var/list/robot_verbs_default = list(
//Hud stuff
var/obj/screen/cells = null
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -786,6 +785,7 @@ var/list/robot_verbs_default = list(
else
sleep(6)
emagged = 1
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
if(src.hud_used)
src.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
disconnect_from_ai()
@@ -814,6 +814,7 @@ var/list/robot_verbs_default = list(
to_chat(src, "<b>Obey these laws:</b>")
laws.show_laws(src)
to_chat(src, "\red \b ALERT: [M.real_name] is your new master. Obey your new laws and his commands.")
SetLockdown(0)
if(src.module && istype(src.module, /obj/item/weapon/robot_module/miner))
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in src.module.modules)
qdel(D)
@@ -1256,6 +1257,10 @@ var/list/robot_verbs_default = list(
// They stay locked down if their wire is cut.
if(wires.LockedCut())
state = 1
if(state)
throw_alert("locked", /obj/screen/alert/locked)
else
clear_alert("locked")
lockcharge = state
update_canmove()
@@ -1006,15 +1006,14 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/handle_hud_icons_health()
..()
if(bodytemp)
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
bodytemp.icon_state = "temp2"
if(320 to 335)
bodytemp.icon_state = "temp1"
if(300 to 320)
bodytemp.icon_state = "temp0"
if(260 to 300)
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp-2"
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
throw_alert("temp", /obj/screen/alert/hot/robot, 2)
if(320 to 335)
throw_alert("temp", /obj/screen/alert/hot/robot, 1)
if(300 to 320)
clear_alert("temp")
if(260 to 300)
throw_alert("temp", /obj/screen/alert/cold/robot, 1)
else
throw_alert("temp", /obj/screen/alert/cold/robot, 2)
@@ -566,5 +566,5 @@ Auto Patrol[]"},
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_inv_handcuffed(1)
C.update_handcuffed()
back_to_idle()
@@ -227,7 +227,7 @@ Auto Patrol: []"},
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_inv_handcuffed(1)
C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
@@ -101,18 +101,6 @@
..()
health = Clamp(health, 0, maxHealth)
/mob/living/simple_animal/handle_hud_icons()
..()
if(fire)
if(fire_alert) fire.icon_state = "fire[fire_alert]" //fire_alert is either 0 if no alert, 1 for heat and 2 for cold.
else fire.icon_state = "fire0"
if(oxygen)
if(oxygen_alert) oxygen.icon_state = "oxy1"
else oxygen.icon_state = "oxy0"
if(toxin)
if(toxins_alert) toxin.icon_state = "tox1"
else toxin.icon_state = "tox0"
/mob/living/simple_animal/handle_hud_icons_health()
..()
if(healths && maxHealth > 0)
@@ -215,21 +203,21 @@
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
atmos_suitable = 0
oxygen_alert = 1
throw_alert("oxy", /obj/screen/alert/oxy)
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
atmos_suitable = 0
oxygen_alert = 1
throw_alert("oxy", /obj/screen/alert/too_much_oxy)
else
oxygen_alert = 0
clear_alert("oxy")
if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
atmos_suitable = 0
toxins_alert = 1
throw_alert("tox_in_air", /obj/screen/alert/not_enough_tox)
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
atmos_suitable = 0
toxins_alert = 1
throw_alert("tox_in_air", /obj/screen/alert/tox_in_air)
else
toxins_alert = 0
clear_alert("tox_in_air")
if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
atmos_suitable = 0
-6
View File
@@ -14,16 +14,10 @@
var/obj/screen/hands = null
var/obj/screen/pullin = null
var/obj/screen/internals = null
var/obj/screen/oxygen = null
var/obj/screen/i_select = null
var/obj/screen/m_select = null
var/obj/screen/toxin = null
var/obj/screen/fire = null
var/obj/screen/bodytemp = null
var/obj/screen/healths = null
var/obj/screen/throw_icon = null
var/obj/screen/nutrition_icon = null
var/obj/screen/pressure = null
var/obj/screen/gun/item/item_use_icon = null
var/obj/screen/gun/move/gun_move_icon = null
var/obj/screen/gun/run/gun_run_icon = null
+19 -3
View File
@@ -556,12 +556,28 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
lname = "<span class='name'>[lname]</span> "
to_chat(M, "<span class='deadsay'>[lname][follow][message]</span>")
/proc/notify_ghosts(var/message, var/ghost_sound = null) //Easy notification of ghosts.
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/attack_not_jump = 0) //Easy notification of ghosts.
for(var/mob/dead/observer/O in player_list)
if(O.client)
to_chat(O, "<span class='ghostalert'>[message]<span>")
to_chat(O, "<span class='ghostalert'>[message][(enter_link) ? " [enter_link]" : ""]<span>")
if(ghost_sound)
to_chat(O, sound(ghost_sound))
O << sound(ghost_sound)
if(source)
var/obj/screen/alert/notify_jump/A = O.throw_alert("\ref[source]_notify_jump", /obj/screen/alert/notify_jump)
if(A)
if(O.client.prefs && O.client.prefs.UI_style)
A.icon = ui_style2icon(O.client.prefs.UI_style)
A.desc = message
A.attack_not_jump = attack_not_jump
A.jump_target = source
if(!alert_overlay)
var/old_layer = source.layer
source.layer = FLOAT_LAYER
A.overlays += source
source.layer = old_layer
else
alert_overlay.layer = FLOAT_LAYER
A.overlays += alert_overlay
/mob/proc/switch_to_camera(var/obj/machinery/camera/C)
if (!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || blinded || !canmove))
+2 -4
View File
@@ -29,7 +29,8 @@
var/area/A = get_area(src)
if(A)
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.")
var/image/alert_overlay = image('icons/effects/effects.dmi', "ghostalertsie")
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, attack_not_jump = 1)
narsie_spawn_animation()
@@ -37,9 +38,6 @@
shuttle_master.emergency.request(null, 0.3) // Cannot recall
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
if(!(src in view()))
to_chat(user, "Your soul is too far away.")
return
makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1)
new /obj/effect/effect/sleep_smoke(user.loc)
@@ -510,7 +510,7 @@
feedback_add_details("slime_cores_used","[type]")
var/obj/effect/golemrune/Z = new /obj/effect/golemrune
Z.forceMove(get_turf(holder.my_atom))
notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg')
notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg', source = Z)
//Bluespace
/datum/chemical_reaction/slimefloor2
+116
View File
@@ -0,0 +1,116 @@
/*
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/file = 'code/modules/tooltip/tooltip.html'
var/showing = 0
var/queueHide = 0
var/init = 0
/datum/tooltip/New(client/C)
if (C)
owner = C
owner << browse(file2text(file), "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 = "<h1>[title]</h1>"
content = "<p>[content]</p>"
else if (title && !content)
title = "<p>[title]</p>"
else if (!title && content)
content = "<p>[content]</p>"
//Make our dumb param object
params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"}
//Send stuff to the tooltip
owner << output(list2params(list(params, owner.view, "[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)
spawn(1)
winshow(owner, control, 0)
else
winshow(owner, control, 0)
queueHide = showing ? 1 : 0
return 1
/* 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.UI_style)
theme = lowertext(user.client.prefs.UI_style)
if(!theme)
theme = "default"
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()
+238
View File
@@ -0,0 +1,238 @@
<!DOCTYPE html>
<html>
<head>
<title>Tooltip</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrap {
position: absolute;
top: 0;
left: 0;
max-width: 298px;
border: 2px solid #1B2967;
}
.content {
font: bold 12px Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: #ffffff;
padding: 8px;
border: 2px solid #0033CC;
background: #005CB8;
}
h1 {
margin: -5px 0 2px 0;
font-size: 1.2em;
line-height: 1.4;
}
p {
margin: 0;
line-height: 1.2;
}
/* Custom Themes */
.blob .wrap {border-color: #2E2E2E;}
.blob .content {color: #82ED00; border-color: #4E4C4A; background-color: #191918;}
.parasite .wrap {border-color: #88868D;}
.parasite .content {color: #EFEEEF; border-color: #35333A; background-color: #636169;}
.alien .wrap {border-color: #33165B;}
.alien .content {color: #25004A; border-color: #5A3076; background-color: #6D3A8E;}
.wraith .wrap {border-color: #492136;}
.wraith .content {border-color: #331726; background-color: #471962;}
.cult .wrap {border-color: #610002;}
.cult .content {color: #0F0B0C; border-color: #A10000; background-color: #4A363B;}
.pod .wrap {border-color: #052401;}
.pod .content {border-color: #326D29; background-color: #569F4B;}
.colo-pod .wrap {border-color: #256fb9;}
.colo-pod .content {border-color: #000000; background-color: #000000;}
/* TG: Themes */
/* ScreenUI */
.midnight .wrap {border-color: #2B2B33;}
.midnight .content {color: #6087A0; border-color: #2B2B33; background-color: #36363C;}
.plasmafire .wrap {border-color: #21213D;}
.plasmafire .content {color: #FFA800 ; border-color: #21213D; background-color:#1D1D36;}
.retro .wrap {border-color: #005E00;}
.retro .content {color: #003366; border-color: #005E00; background-color: #00BD00;}
.slimecore .wrap {border-color: #18640E;}
.slimecore .content {color: #6EA161; border-color: #11450B; background-color: #354E35;}
.operative .wrap {border-color: #1E0101;}
.operative .content {color: #FFFFFF; border-color: #750000; background-color: #350000;}
</style>
</head>
<body>
<div id="wrap" class="wrap">
<div id="content" class="content"></div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
var tooltip = {
'tileSize': 32,
'control': '',
'params': {},
'clientView': 0,
'text': '',
'theme': '',
'padding': 2,
init: function(tileSize, control) {
tooltip.tileSize = parseInt(tileSize);
tooltip.control = control;
},
hide: function() {
window.location = 'byond://winset?id='+tooltip.control+';is-visible=false';
},
updateCallback: function(map) {
if (typeof map === 'undefined' || !map) {return false;}
//alert(tooltip.params+' | '+tooltip.clientView+' | '+tooltip.text+' | '+tooltip.theme); //DEBUG
//Some reset stuff to avoid fringe issues with sizing
window.location = 'byond://winset?id='+tooltip.control+';anchor1=0,0;size=999x999';
//Get the real icon size according to the client view
var mapWidth = map['view-size'].x,
mapHeight = map['view-size'].y,
tilesShown = (tooltip.clientView * 2) + 1,
realIconSize = mapWidth / tilesShown,
resizeRatio = realIconSize / tooltip.tileSize,
//Calculate letterboxing offsets
leftOffset = (map.size.x - mapWidth) / 2,
topOffset = (map.size.y - mapHeight) / 2;
//alert(realIconSize + ' | ' +tooltip.tileSize + ' | ' + resizeRatio); //DEBUG
//Parse out the tile and cursor locations from params (e.g. "icon-x=32;icon-y=29;screen-loc=3:10,15:29")
var paramsA = tooltip.params.cursor.split(';');
if (paramsA.length < 3) {return false;} //Sometimes screen-loc is never sent ahaha fuck you byond
//icon-x
var iconX = paramsA[0];
iconX = iconX.split('=');
iconX = parseInt(iconX[1]);
//icon-y
var iconY = paramsA[1];
iconY = iconY.split('=');
iconY = parseInt(iconY[1]);
//screen-loc
var screenLoc = paramsA[2];
screenLoc = screenLoc.split('=');
screenLoc = screenLoc[1].split(',');
if (screenLoc.length < 2) {return false;}
var left = screenLoc[0];
var top = screenLoc[1];
if (!left || !top) {return false;}
screenLoc = left.split(':');
left = parseInt(screenLoc[0]);
var enteredX = parseInt(screenLoc[1]);
screenLoc = top.split(':');
top = parseInt(screenLoc[0]);
var enteredY = parseInt(screenLoc[1]);
//Screen loc offsets on objects (e.g. "WEST+0:6,NORTH-1:26") can royally mess with positioning depending on where the cursor enters
//This is a giant bitch to parse. Note that it only expects screen_loc in the format <west>,<north>.
var oScreenLoc = tooltip.params.screenLoc.split(','); //o for original ok
var west = oScreenLoc[0].split(':');
if (west.length > 1) { //Only if west has a pixel offset
var westOffset = parseInt(west[1]);
if (westOffset !== 0) {
if ((iconX + westOffset) !== enteredX) { //Cursor entered on the offset tile
left = left + (westOffset < 0 ? 1 : -1);
}
leftOffset = leftOffset + (westOffset * resizeRatio);
}
}
if (oScreenLoc.length > 1) { //If north is given
var north = oScreenLoc[1].split(':');
if (north.length > 1) { //Only if north has a pixel offset
var northOffset = parseInt(north[1]);
if (northOffset !== 0) {
if ((iconY + northOffset) === enteredY) { //Cursor entered on the original tile
top--;
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Cursor entered on the offset tile
if (northOffset < 0) { //Offset southwards
topOffset = topOffset - ((tooltip.tileSize + northOffset) * resizeRatio);
} else { //Offset northwards
top--;
topOffset = topOffset - (northOffset * resizeRatio);
}
}
}
}
}
//Handle special cases (for fuck sake)
if (tooltip.special !== 'none') {
//Put yo special cases here
}
//Clamp values
left = (left < 0 ? 0 : (left > tilesShown ? tilesShown : left));
top = (top < 0 ? 0 : (top > tilesShown ? tilesShown : top));
//Calculate where on the screen the popup should appear (below the hovered tile)
var posX = Math.round(((left - 1) * realIconSize) + leftOffset + tooltip.padding); //-1 to position at the left of the target tile
var posY = Math.round(((tilesShown - top + 1) * realIconSize) + topOffset + tooltip.padding); //+1 to position at the bottom of the target tile
//alert(mapWidth+' | '+mapHeight+' | '+tilesShown+' | '+realIconSize+' | '+leftOffset+' | '+topOffset+' | '+left+' | '+top+' | '+posX+' | '+posY); //DEBUG
$('body').attr('class', tooltip.theme);
var $content = $('#content'),
$wrap = $('#wrap');
$wrap.attr('style', '');
$content.off('mouseover');
$content.html(tooltip.text);
$wrap.width($wrap.width() + 2); //Dumb hack to fix a bizarre sizing bug
var docWidth = $wrap.outerWidth(),
docHeight = $wrap.outerHeight();
if (posY + docHeight > map.size.y) { //Is the bottom edge below the window? Snap it up if so
posY = (posY - docHeight) - realIconSize - tooltip.padding;
}
//Actually size, move and show the tooltip box
window.location = 'byond://winset?id='+tooltip.control+';size='+docWidth+'x'+docHeight+';pos='+posX+','+posY+';is-visible=true';
$content.on('mouseover', function() {
tooltip.hide();
});
},
update: function(params, clientView, text, theme, special) {
//Assign our global object
tooltip.params = $.parseJSON(params);
tooltip.clientView = parseInt(clientView);
tooltip.text = text;
tooltip.theme = theme;
tooltip.special = special;
//Go get the map details
window.location = 'byond://winget?callback=tooltip.updateCallback;id=mapwindow.map;property=size,view-size';
},
};
</script>
</body>
</html>