Files
Bubberstation/code/modules/mob/mob_helpers.dm
duncathan f7363fc737 Squashed commit of the following:
commit 5ab47a85f7
Author: duncathan <dunc2403@dunc2403.com>
Date:   Sat Aug 29 03:29:23 2015 -0600

    disables TESTING; it should not be enabled by default

commit 2cc7226ea8
Author: duncathan <dunc2403@dunc2403.com>
Date:   Sat Aug 29 03:27:55 2015 -0600

    adds ways to check references while qdel'ing; removes redundant compile option

commit 4409db7f0b
Author: duncathan <dunc2403@dunc2403.com>
Date:   Sat Aug 29 00:19:25 2015 -0600

    makes the game compile if TESTING is defined in compile options

commit e11befbbfa
Merge: 22ffbca 20ba307
Author: Cheridan <derpheim@yahoo.com>
Date:   Fri Aug 28 07:20:03 2015 -0500

    Merge pull request #11356 from Aranclanos/listnull

    Fixes the brand intelligence event not triggering the uprising under …

commit 22ffbca5a2
Author: sybil-tgstation13 <sybil@tgstation13.org>
Date:   Fri Aug 28 05:43:08 2015 +0000

    Automatic changelog compile

commit d824f7b35f
Merge: 7f0f74f 3737234
Author: Cheridan <derpheim@yahoo.com>
Date:   Fri Aug 28 00:21:23 2015 -0500

    Merge pull request #11382 from Ergovisavi/bot_swarm

    Adds "Swarmers" - Simple mob side antagonist

commit 3737234b9c
Merge: 9572bd6 ba1a268
Author: Ergovisavi <rtothev@gmail.com>
Date:   Tue Aug 25 05:48:37 2015 -0700

    -Adds swarmer as a language, makes them only able to speak to each other
    -Fixes a few structures/machines taking non brute/burn damage from attack_animal
    -Adjusts girders to be a little less resistant to explosions
    -Span classes all the swarmer messages, bumps their health up to 40
    -Adds ability for swarmers to dismantle machines and disable cameras. Some are obviously protected.

commit 7f0f74f100
Merge: d8f8f89 6ab2443
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 23:53:58 2015 -0500

    Merge pull request #11380 from bgobandit/salicyclicassblastusa

    Fixes burn kits containing salicyclic acid pills. Adds new burn medication.

commit d8f8f89203
Merge: 68002be 460c2c2
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 23:46:57 2015 -0500

    Merge pull request #11386 from Aranclanos/rapiddupe

    Fixes the admin message not appearing under certain conditions when t…

commit 68002bed99
Merge: eebbed3 d27a736
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 16:50:33 2015 -0500

    Merge pull request #11315 from CorruptComputer/why

    Removes dmm2tgm from map merger

commit eebbed3a6b
Merge: 1769bc2 3749dca
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 12:10:40 2015 -0500

    Merge pull request #11405 from Aranclanos/floortilesfirst

    Floor re-organization step 1

commit 1769bc2f8d
Merge: d7eca4f 20023f7
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 12:06:28 2015 -0500

    Merge pull request #11104 from phil235/BuckleMulebot

    Mob buckled to mulebots

commit d7eca4f327
Merge: be6cc6a 90f54ba
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 01:00:01 2015 -0500

    Merge pull request #11340 from phil235/CoinFlipThrowFix

    Fixes the do_after progress bar appearing on a coin when flipping+throwing it

commit be6cc6adf9
Merge: 9c9bf4a d211992
Author: Cheridan <derpheim@yahoo.com>
Date:   Thu Aug 27 00:48:54 2015 -0500

    Merge pull request #11392 from phil235/SinguloCableNetRebuildFix

    An attempt to reduce singulo lag from power wires destruction. 2nd attempt.

commit 9c9bf4a858
Merge: 3278a39 6277a80
Author: Aranclanos <aranclanos@hotmail.com>
Date:   Thu Aug 27 01:06:03 2015 -0300

    Merge pull request #11393 from Ergovisavi/has_wumbo_gone_too_far

    Fixes infinite wumbo-ing

commit 3278a3926b
Merge: 38e6a09 1f37141
Author: Cheridan <derpheim@yahoo.com>
Date:   Wed Aug 26 07:52:31 2015 -0500

    Merge pull request #11358 from phil235/XenoFeatures1

    Facehugger inhands, xeno tweaks, and monkey bugfixes

commit 3749dcacb3
Author: Aranclanos <aranclanos@hotmail.com>
Date:   Wed Aug 26 06:47:27 2015 -0300

    Creates type paths for all types of floors in floor.dmi, first step for the floor organization.

commit 38e6a09cf9
Merge: 4f1a3df 9cfb246
Author: Aranclanos <aranclanos@hotmail.com>
Date:   Wed Aug 26 06:27:31 2015 -0300

    Merge pull request #11351 from Core0verload/nodirt

    Removes dirt from walking on tiles

commit 6277a80cdb
Author: Ergovisavi <rtothev@gmail.com>
Date:   Tue Aug 25 14:02:48 2015 -0700

    -Fixes infinite wumbo-ing

commit d211992ddc
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Tue Aug 25 20:22:30 2015 +0200

    Make it so the code doesn't rebuild (propagate_network()) the wire network X times when singulo/explosion destroys a line of X cables at once.

commit 6ab2443255
Author: bgobandit <bandit@mailinator.com>
Date:   Tue Aug 25 13:46:05 2015 -0400

    Adds oxandrolone, a new burn medication designed to work upon ingestion. Adds oxandrolone to burn kits. Adds changelog.

commit 9572bd6aa6
Author: Ergovisavi <rtothev@gmail.com>
Date:   Tue Aug 25 03:24:34 2015 -0700

    -First revision of Swarmer mob, hud, icons, etc
    -Adds functionality of ignored damage types to simple mobs
    -Adds functionality of melee damage types to simple mobs

commit 460c2c290c
Author: Aranclanos <aranclanos@hotmail.com>
Date:   Tue Aug 25 05:31:02 2015 -0300

    Fixes the admin message not appearing under certain conditions when the rapid dupe experimentator relic is used.
    All objects from said relic will spawn at the same time now.

commit 2c56462e97
Author: bgobandit <bandit@mailinator.com>
Date:   Mon Aug 24 22:45:37 2015 -0400

    I sure do love me some copypasta

commit 132adf3f00
Author: bgobandit <bandit@mailinator.com>
Date:   Mon Aug 24 21:45:18 2015 -0400

    adds silver sulf syringes instead of kelotane pills

commit ce8722b868
Author: bgobandit <bandit@mailinator.com>
Date:   Mon Aug 24 21:36:50 2015 -0400

    Fixes burn kits containing salicyclic acid pills.

commit 1f37141b8b
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Mon Aug 24 22:53:45 2015 +0200

    Alien humanoids and monkeys can now use "me".
    Alien hivemind chat now uses <span class='alien'> (dark purple). Also the alien queen name now appears bigger in the hivemind chat.

commit 5cecd7e9fe
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Mon Aug 24 19:54:51 2015 +0200

    Simplifies plasmavessel/on_life() a bit, and make xeno on weeds also heal clone damage.

commit cb1cd5b1e7
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Mon Aug 24 17:07:09 2015 +0200

    Monkey and aliens now all use carbon/examine().
    Fixes monkeys being able to strip and uncuff people while handcuffed themselves.
    Add an inhand sprite for facehuggers (taken from Xhuis) (but they don't appear for large queens, it'd look ugly).
    Xenos now regenerate plasma on alien weed even when injured but at half the normal rate.
    Moved queen/large/update_icons() to humanoid/update_icons.dm

commit 20ba3071ed
Author: Aranclanos <aranclanos@hotmail.com>
Date:   Mon Aug 24 07:52:54 2015 -0300

    Fixes the brand intelligence event not triggering the uprising under certain conditions.
    Adds a new proc for the list helpers, removeNullsFromList() It does what it says.

commit 9cfb246e4f
Author: c0 <Core0verload@users.noreply.github.com>
Date:   Mon Aug 24 11:33:52 2015 +0300

    Removes dirt from walking on tiles

commit 20023f79d7
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Sun Aug 23 21:39:22 2015 +0200

    Mobs buckled to mulebots now pass through plastic flaps.
    All ventcrawler and tiny sized mobs also pass through them now.

commit 27b7e3b6f6
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Sun Aug 23 20:55:41 2015 +0200

    Beds no longer use this trick in Move() so neither should the mulebot.

commit 90f54ba95c
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Sun Aug 23 19:34:09 2015 +0200

    Fixes the do_after progress bar appearing on a coin when flipping+throwing it.

commit d27a736f7e
Author: CorruptComputer <NGupton98@gmail.com>
Date:   Fri Aug 21 16:57:27 2015 -0500

    Fixes #11301

commit e16c03f010
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Sat Aug 8 22:10:25 2015 +0200

    woops, now buckling succeeds if you are on the mulebot's turf.

commit 1c51550559
Author: phil235 <antoine_hernandez62@hotmail.fr>
Date:   Sat Aug 8 21:43:30 2015 +0200

    Changes how mulebots handle loading mobs. It now buckles them to the bot.

    You can no longer load objects containing mobs or with mobs buckled to them.

    You can no longer pass through plastic flaps by getting on a mulebot.

    Some simplification in mulebot code (buzzing sound code)

    Loading is now instantaneous and the mode BOT_LOADING is removed.

    The mulebot can no longer do certain stuff while off.

    Removing unneeded comments.

    Fixes mulebot loading/unloading being possible through border windows.

    Fixes mulebot not dropping its loaded cargo when qdel'd (wasn't a problem for explosion but for alien acid for example)
2015-08-29 13:19:15 -06:00

496 lines
13 KiB
Plaintext

// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
/proc/ishuman(A)
if(istype(A, /mob/living/carbon/human))
return 1
return 0
/proc/ismonkey(A)
if(A && istype(A, /mob/living/carbon/monkey))
return 1
return 0
/proc/isbrain(A)
if(A && istype(A, /mob/living/carbon/brain))
return 1
return 0
/proc/isalien(A)
if(istype(A, /mob/living/carbon/alien))
return 1
return 0
/proc/isalienadult(A)
if(istype(A, /mob/living/carbon/alien/humanoid))
return 1
return 0
/proc/islarva(A)
if(istype(A, /mob/living/carbon/alien/larva))
return 1
return 0
/proc/isslime(A)
if(istype(A, /mob/living/simple_animal/slime))
return 1
return 0
/proc/isrobot(A)
if(istype(A, /mob/living/silicon/robot))
return 1
return 0
/proc/isanimal(A)
if(istype(A, /mob/living/simple_animal))
return 1
return 0
/proc/iscorgi(A)
if(istype(A, /mob/living/simple_animal/pet/dog/corgi))
return 1
return 0
/proc/iscrab(A)
if(istype(A, /mob/living/simple_animal/crab))
return 1
return 0
/proc/iscat(A)
if(istype(A, /mob/living/simple_animal/pet/cat))
return 1
return 0
/proc/ismouse(A)
if(istype(A, /mob/living/simple_animal/mouse))
return 1
return 0
/proc/isbear(A)
if(istype(A, /mob/living/simple_animal/hostile/bear))
return 1
return 0
/proc/iscarp(A)
if(istype(A, /mob/living/simple_animal/hostile/carp))
return 1
return 0
/proc/isclown(A)
if(istype(A, /mob/living/simple_animal/hostile/retaliate/clown))
return 1
return 0
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
return 0
/proc/ispAI(A)
if(istype(A, /mob/living/silicon/pai))
return 1
return 0
/proc/iscarbon(A)
if(istype(A, /mob/living/carbon))
return 1
return 0
/proc/issilicon(A)
if(istype(A, /mob/living/silicon))
return 1
return 0
/proc/isliving(A)
if(istype(A, /mob/living))
return 1
return 0
/proc/isobserver(A)
if(istype(A, /mob/dead/observer))
return 1
return 0
/proc/isnewplayer(A)
if(istype(A, /mob/new_player))
return 1
return 0
/proc/isovermind(A)
if(istype(A, /mob/camera/blob))
return 1
return 0
/proc/isdrone(A)
if(istype(A, /mob/living/simple_animal/drone))
return 1
return 0
/proc/isswarmer(A)
if(istype(A, /mob/living/simple_animal/hostile/swarmer))
return 1
return 0
/proc/islimb(A)
if(istype(A, /obj/item/organ/limb))
return 1
return 0
/proc/isloyal(A) //Checks to see if the person contains a loyalty implant, then checks that the implant is actually inside of them
for(var/obj/item/weapon/implant/loyalty/L in A)
if(L && L.implanted)
return 1
return 0
/proc/check_zone(zone)
if(!zone) return "chest"
switch(zone)
if("eyes")
zone = "head"
if("mouth")
zone = "head"
if("l_hand")
zone = "l_arm"
if("r_hand")
zone = "r_arm"
if("l_foot")
zone = "l_leg"
if("r_foot")
zone = "r_leg"
if("groin")
zone = "chest"
return zone
/proc/ran_zone(zone, probability = 80)
zone = check_zone(zone)
if(prob(probability))
return zone
var/t = rand(1, 18) // randomly pick a different zone, or maybe the same one
switch(t)
if(1) return "head"
if(2) return "chest"
if(3 to 6) return "l_arm"
if(7 to 10) return "r_arm"
if(11 to 14) return "l_leg"
if(15 to 18) return "r_leg"
return zone
/proc/above_neck(zone)
var/list/zones = list("head", "mouth", "eyes")
if(zones.Find(zone))
return 1
else
return 0
/proc/stars(n, pr)
n = html_encode(n)
if (pr == null)
pr = 25
if (pr <= 0)
return null
else
if (pr >= 100)
return n
var/te = n
var/t = ""
n = length(n)
var/p = null
p = 1
while(p <= n)
if ((copytext(te, p, p + 1) == " " || prob(pr)))
t = text("[][]", t, copytext(te, p, p + 1))
else
t = text("[]*", t)
p++
return sanitize(t)
/proc/slur(n)
var/phrase = html_decode(n)
var/leng = lentext(phrase)
var/counter=lentext(phrase)
var/newphrase=""
var/newletter=""
while(counter>=1)
newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2)
if(rand(1,3)==3)
if(lowertext(newletter)=="o") newletter="u"
if(lowertext(newletter)=="s") newletter="ch"
if(lowertext(newletter)=="a") newletter="ah"
if(lowertext(newletter)=="u") newletter="oo"
if(lowertext(newletter)=="c") newletter="k"
if(rand(1,20)==20)
if(newletter==" ") newletter="...huuuhhh..."
if(newletter==".") newletter=" *BURP*."
switch(rand(1,20))
if(1) newletter+="'"
if(10) newletter+="[newletter]"
if(20) newletter+="[newletter][newletter]"
newphrase+="[newletter]";counter-=1
return newphrase
/proc/stutter(n)
var/te = html_decode(n)
var/t = ""//placed before the message. Not really sure what it's for.
n = length(n)//length of the entire word
var/p = null
p = 1//1 is the start of any word
while(p <= n)//while P, which starts at 1 is less or equal to N which is the length.
var/n_letter = copytext(te, p, p + 1)//copies text from a certain distance. In this case, only one letter at a time.
if (prob(80) && (ckey(n_letter) in list("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z")))
if (prob(10))
n_letter = text("[n_letter]-[n_letter]-[n_letter]-[n_letter]")//replaces the current letter with this instead.
else
if (prob(20))
n_letter = text("[n_letter]-[n_letter]-[n_letter]")
else
if (prob(5))
n_letter = null
else
n_letter = text("[n_letter]-[n_letter]")
t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word.
p++//for each letter p is increased to find where the next letter will be.
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
/proc/derpspeech(message, stuttering)
message = replacetext(message, " am ", " ")
message = replacetext(message, " is ", " ")
message = replacetext(message, " are ", " ")
message = replacetext(message, "you", "u")
message = replacetext(message, "help", "halp")
message = replacetext(message, "grief", "grife")
message = replacetext(message, "space", "spess")
message = replacetext(message, "carp", "crap")
message = replacetext(message, "reason", "raisin")
if(prob(50))
message = uppertext(message)
message += "[stutter(pick("!", "!!", "!!!"))]"
if(!stuttering && prob(15))
message = stutter(message)
return message
/proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
/* Turn text into complete gibberish! */
var/returntext = ""
for(var/i = 1, i <= length(t), i++)
var/letter = copytext(t, i, i+1)
if(prob(50))
if(p >= 70)
letter = ""
for(var/j = 1, j <= rand(0, 2), j++)
letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*")
returntext += letter
return returntext
/proc/ninjaspeak(n) //NINJACODE
/*
The difference with stutter is that this proc can stutter more than 1 letter
The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma.
It's fairly easy to fix if dealing with single letters but not so much with compounds of letters./N
*/
var/te = html_decode(n)
var/t = ""
n = length(n)
var/p = 1
while(p <= n)
var/n_letter
var/n_mod = rand(1,4)
if(p+n_mod>n+1)
n_letter = copytext(te, p, n+1)
else
n_letter = copytext(te, p, p+n_mod)
if (prob(50))
if (prob(30))
n_letter = text("[n_letter]-[n_letter]-[n_letter]")
else
n_letter = text("[n_letter]-[n_letter]")
else
n_letter = text("[n_letter]")
t = text("[t][n_letter]")
p=p+n_mod
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
/proc/shake_camera(mob/M, duration, strength=1)
spawn(0)
if(!M || !M.client || M.shakecamera)
return
var/oldeye=M.client.eye
var/x
M.shakecamera = 1
for(x=0; x<duration, x++)
if(M && M.client)
M.client.eye = locate(dd_range(1,M.loc.x+rand(-strength,strength),world.maxx),dd_range(1,M.loc.y+rand(-strength,strength),world.maxy),M.loc.z)
sleep(1)
if(M)
M.shakecamera = 0
if(M.client)
M.client.eye=oldeye
/proc/findname(msg)
if(!istext(msg))
msg = "[msg]"
for(var/mob/M in mob_list)
if(M.real_name == msg)
return M
return 0
/mob/proc/abiotic(full_body = 0)
if(l_hand && !l_hand.flags&ABSTRACT || r_hand && !r_hand.flags&ABSTRACT)
return 1
return 0
//converts intent-strings into numbers and back
/proc/intent_numeric(argument)
if(istext(argument))
switch(argument)
if("help") return 0
if("disarm") return 1
if("grab") return 2
else return 3
else
switch(argument)
if(0) return "help"
if(1) return "disarm"
if(2) return "grab"
else return "harm"
//change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left
/mob/verb/a_intent_change(input as text)
set name = "a-intent"
set hidden = 1
if(ishuman(src) || isalienadult(src) || isbrain(src))
switch(input)
if("help", "disarm", "grab", "harm")
a_intent = input
if("right")
a_intent = intent_numeric((intent_numeric(a_intent) + 1) % 4)
if("left")
a_intent = intent_numeric((intent_numeric(a_intent) + 3) % 4)
if(hud_used && hud_used.action_intent)
hud_used.action_intent.icon_state = "[a_intent]"
else if(isrobot(src) || ismonkey(src) || islarva(src))
switch(input)
if("help")
a_intent = "help"
if("harm")
a_intent = "harm"
if("right","left")
a_intent = intent_numeric(intent_numeric(a_intent) - 3)
if(hud_used && hud_used.action_intent)
if(a_intent == "harm")
hud_used.action_intent.icon_state = "harm"
else
hud_used.action_intent.icon_state = "help"
/proc/is_blind(A)
if(ismob(A))
var/mob/B = A
return B.eye_blind
return 0
/proc/is_special_character(mob/M) // returns 1 for special characters and 2 for heroes of gamemode //moved out of admins.dm because things other than admin procs were calling this.
if(!ticker || !ticker.mode)
return 0
if(!istype(M))
return 0
if(issilicon(M))
if(isrobot(M)) //For cyborgs, returns 1 if the cyborg has a law 0 and special_role. Returns 0 if the borg is merely slaved to an AI traitor.
var/mob/living/silicon/robot/R = M
if(R.emagged || R.syndicate) //Count as antags
return 1
if(R.mind && R.mind.special_role && R.laws && R.laws.zeroth).
if(R.connected_ai)
if(is_special_character(R.connected_ai) && R.connected_ai.laws && (R.connected_ai.laws.zeroth_borg == R.laws.zeroth || R.connected_ai.laws.zeroth == R.laws.zeroth))
return 0 //AI is the real traitor here, so the borg itself is not a traitor
return 1 //Slaved but also a traitor
return 1 //Unslaved, traitor
else if(isAI(M))
var/mob/living/silicon/ai/A = M
if(A.laws && A.laws.zeroth && A.mind && A.mind.special_role)
if(ticker.mode.config_tag == "malfunction" && M.mind in ticker.mode.malf_ai)//Malf law is a law 0
return 2
return 1
return 0
if(M.mind && M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist.
switch(ticker.mode.config_tag)
if("revolution")
if((M.mind in ticker.mode.head_revolutionaries) || (M.mind in ticker.mode.revolutionaries))
return 2
if("cult")
if(M.mind in ticker.mode.cult)
return 2
if("nuclear")
if(M.mind in ticker.mode.syndicates)
return 2
if("changeling")
if(M.mind in ticker.mode.changelings)
return 2
if("wizard")
if(M.mind in ticker.mode.wizards)
return 2
if("monkey")
if(M.viruses && (locate(/datum/disease/transformation/jungle_fever) in M.viruses))
return 2
if("abductor")
if(M.mind in ticker.mode.abductors)
return 2
return 1
return 0
/mob/proc/has_mutation(mutation)
return mutation in src.mutations ? 1 : 0
/proc/get_both_hands(mob/living/carbon/M)
var/list/hands = list(M.l_hand, M.r_hand)
return hands
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
return 1
/proc/notify_ghosts(var/message, var/ghost_sound = null) //Easy notification of ghosts.
for(var/mob/dead/observer/O in player_list)
if(O.client)
O << "<span class='ghostalert'>[message]<span>"
if(ghost_sound)
O << sound(ghost_sound)
/proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute, burn)
var/obj/item/organ/limb/affecting = H.get_organ(check_zone(user.zone_sel.selecting))
var/dam //changes repair text based on how much brute/burn was supplied
if(brute > burn)
dam = 1
else
dam = 0
if(affecting.status == ORGAN_ROBOTIC)
if(brute > 0 && affecting.brute_dam > 0 || burn > 0 && affecting.burn_dam > 0)
affecting.heal_damage(brute,burn,1)
H.update_damage_overlays(0)
H.updatehealth()
user.visible_message("[user] has fixed some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting.getDisplayName()].", "<span class='notice'>You fix some of the [dam ? "dents on" : "burnt wires in"] [H]'s [affecting.getDisplayName()].</span>")
return
else
user << "<span class='warning'>[H]'s [affecting.getDisplayName()] is already in good condition!</span>"
return
else
return