@@ -0,0 +1,335 @@
|
||||
/* For employment contracts and infernal contracts */
|
||||
|
||||
/obj/item/paper/contract
|
||||
throw_range = 3
|
||||
throw_speed = 3
|
||||
var/signed = FALSE
|
||||
var/datum/mind/target
|
||||
item_flags = NOBLUDGEON
|
||||
|
||||
/obj/item/paper/contract/proc/update_text()
|
||||
return
|
||||
|
||||
/obj/item/paper/contract/update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/paper/contract/employment
|
||||
icon_state = "paper_words"
|
||||
|
||||
/obj/item/paper/contract/employment/New(atom/loc, mob/living/nOwner)
|
||||
. = ..()
|
||||
if(!nOwner || !nOwner.mind)
|
||||
qdel(src)
|
||||
return -1
|
||||
target = nOwner.mind
|
||||
update_text()
|
||||
|
||||
|
||||
/obj/item/paper/contract/employment/update_text()
|
||||
name = "paper- [target] employment contract"
|
||||
info = "<center>Conditions of Employment</center><BR><BR><BR><BR>This Agreement is made and entered into as of the date of last signature below, by and between [target] (hereafter referred to as SLAVE), and Nanotrasen (hereafter referred to as the omnipresent and helpful watcher of humanity).<BR>WITNESSETH:<BR>WHEREAS, SLAVE is a natural born human or humanoid, possessing skills upon which he can aid the omnipresent and helpful watcher of humanity, who seeks employment in the omnipresent and helpful watcher of humanity.<BR>WHEREAS, the omnipresent and helpful watcher of humanity agrees to sporadically provide payment to SLAVE, in exchange for permanent servitude.<BR>NOW THEREFORE in consideration of the mutual covenants herein contained, and other good and valuable consideration, the parties hereto mutually agree as follows:<BR>In exchange for paltry payments, SLAVE agrees to work for the omnipresent and helpful watcher of humanity, for the remainder of his or her current and future lives.<BR>Further, SLAVE agrees to transfer ownership of his or her soul to the loyalty department of the omnipresent and helpful watcher of humanity.<BR>Should transfership of a soul not be possible, a lien shall be placed instead.<BR>Signed,<BR><i>[target]</i>"
|
||||
|
||||
|
||||
/obj/item/paper/contract/employment/attack(mob/living/M, mob/living/carbon/human/user)
|
||||
var/deconvert = FALSE
|
||||
if(M.mind == target && !M.owns_soul())
|
||||
if(user.mind && (user.mind.assigned_role == "Lawyer"))
|
||||
deconvert = TRUE
|
||||
else if (user.mind && (user.mind.assigned_role =="Head of Personnel") || (user.mind.assigned_role == "CentCom Commander"))
|
||||
deconvert = prob (25) // the HoP doesn't have AS much legal training
|
||||
else
|
||||
deconvert = prob (5)
|
||||
if(deconvert)
|
||||
M.visible_message("<span class='notice'>[user] reminds [M] that [M]'s soul was already purchased by Nanotrasen!</span>")
|
||||
to_chat(M, "<span class='boldnotice'>You feel that your soul has returned to its rightful owner, Nanotrasen.</span>")
|
||||
M.return_soul()
|
||||
else
|
||||
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] beats [M] over the head with [src]!</span>")
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/paper/contract/infernal
|
||||
var/contractType = 0
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/datum/mind/owner
|
||||
var/datum/antagonist/devil/devil_datum
|
||||
icon_state = "paper_onfire"
|
||||
|
||||
/obj/item/paper/contract/infernal/power
|
||||
name = "paper- contract for infernal power"
|
||||
contractType = CONTRACT_POWER
|
||||
|
||||
/obj/item/paper/contract/infernal/wealth
|
||||
name = "paper- contract for unlimited wealth"
|
||||
contractType = CONTRACT_WEALTH
|
||||
|
||||
/obj/item/paper/contract/infernal/prestige
|
||||
name = "paper- contract for prestige"
|
||||
contractType = CONTRACT_PRESTIGE
|
||||
|
||||
/obj/item/paper/contract/infernal/magic
|
||||
name = "paper- contract for magical power"
|
||||
contractType = CONTRACT_MAGIC
|
||||
|
||||
/obj/item/paper/contract/infernal/revive
|
||||
name = "paper- contract of resurrection"
|
||||
contractType = CONTRACT_REVIVE
|
||||
var/cooldown = FALSE
|
||||
|
||||
/obj/item/paper/contract/infernal/knowledge
|
||||
name = "paper- contract for knowledge"
|
||||
contractType = CONTRACT_KNOWLEDGE
|
||||
|
||||
/obj/item/paper/contract/infernal/friend
|
||||
name = "paper- contract for a friend"
|
||||
contractType = CONTRACT_FRIEND
|
||||
|
||||
/obj/item/paper/contract/infernal/unwilling
|
||||
name = "paper- infernal contract"
|
||||
contractType = CONTRACT_UNWILLING
|
||||
|
||||
/obj/item/paper/contract/infernal/New(atom/loc, mob/living/nTarget, datum/mind/nOwner)
|
||||
..()
|
||||
owner = nOwner
|
||||
devil_datum = owner.has_antag_datum(/datum/antagonist/devil)
|
||||
target = nTarget
|
||||
update_text()
|
||||
|
||||
/obj/item/paper/contract/infernal/suicide_act(mob/user)
|
||||
if(signed && (user == target.current) && istype(user, /mob/living/carbon/human/))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.forcesay("OH GREAT INFERNO! I DEMAND YOU COLLECT YOUR BOUNTY IMMEDIATELY!")
|
||||
H.visible_message("<span class='suicide'>[H] holds up a contract claiming [user.p_their()] soul, then immediately catches fire. It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
H.adjust_fire_stacks(20)
|
||||
H.IgniteMob()
|
||||
return(FIRELOSS)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/paper/contract/infernal/update_text()
|
||||
info = "This shouldn't be seen. Error DEVIL:6"
|
||||
|
||||
/obj/item/paper/contract/infernal/power/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for infernal power</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for power and physical strength. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/wealth/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for unlimited wealth</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for a pocket that never runs out of valuable resources. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/prestige/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for prestige</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for prestige and esteem among my peers. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/magic/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for magic</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for arcane abilities beyond normal human ability. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/revive/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for resurrection</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for resurrection and curing of all injuries. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/knowledge/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for knowledge</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for boundless knowledge. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/friend/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for a friend</B></center><BR><BR><BR>I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename], in exchange for a friend. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/unwilling/update_text(signature = "____________", blood = 0)
|
||||
info = "<center><B>Contract for slave</B></center><BR><BR><BR>I, [target], hereby offer my soul to the infernal hells by way of the infernal agent [devil_datum.truename]. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.<BR><BR><BR>Signed, "
|
||||
if(blood)
|
||||
info += "<font face=\"Nyala\" color=#600A0A size=6><i>[signature]</i></font>"
|
||||
else
|
||||
info += "<i>[signature]</i>"
|
||||
|
||||
/obj/item/paper/contract/infernal/attackby(obj/item/P, mob/living/carbon/human/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
|
||||
attempt_signature(user)
|
||||
else if(istype(P, /obj/item/stamp))
|
||||
to_chat(user, "<span class='notice'>You stamp the paper with your rubber stamp, however the ink ignites as you release the stamp.</span>")
|
||||
else if(P.get_temperature())
|
||||
user.visible_message("<span class='danger'>[user] brings [P] next to [src], but [src] does not catch fire!</span>", "<span class='danger'>[src] refuses to ignite!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/attack(mob/M, mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(M == user && target == M.mind && M.mind.soulOwner != owner && attempt_signature(user, 1))
|
||||
user.visible_message("<span class='danger'>[user] slices [user.p_their()] wrist with [src], and scrawls [user.p_their()] name in blood.</span>", "<span class='danger'>You slice your wrist open and scrawl your name in blood.</span>")
|
||||
user.blood_volume = max(user.blood_volume - 100, 0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/proc/attempt_signature(mob/living/carbon/human/user, blood = 0)
|
||||
if(!user.IsAdvancedToolUser() || !user.is_literate())
|
||||
to_chat(user, "<span class='notice'>You don't know how to read or write.</span>")
|
||||
return 0
|
||||
if(user.mind != target)
|
||||
to_chat(user, "<span class='notice'>Your signature simply slides off the sheet, it seems this contract is not meant for you to sign.</span>")
|
||||
return 0
|
||||
if(user.mind.soulOwner == owner)
|
||||
to_chat(user, "<span class='notice'>This devil already owns your soul, you may not sell it to [owner.p_them()] again.</span>")
|
||||
return 0
|
||||
if(signed)
|
||||
to_chat(user, "<span class='notice'>This contract has already been signed. It may not be signed again.</span>")
|
||||
return 0
|
||||
if(!user.mind.hasSoul)
|
||||
to_chat(user, "<span class='notice'>You do not possess a soul.</span>")
|
||||
return 0
|
||||
if(HAS_TRAIT(user, TRAIT_DUMB))
|
||||
to_chat(user, "<span class='notice'>You quickly scrawl 'your name' on the contract.</span>")
|
||||
signIncorrectly()
|
||||
return 0
|
||||
if (contractType == CONTRACT_REVIVE)
|
||||
to_chat(user, "<span class='notice'>You are already alive, this contract would do nothing.</span>")
|
||||
return 0
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You quickly scrawl your name on the contract</span>")
|
||||
if(fulfillContract(target.current, blood)<=0)
|
||||
to_chat(user, "<span class='notice'>But it seemed to have no effect, perhaps even Hell itself cannot grant this boon?</span>")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/paper/contract/infernal/revive/attack(mob/M, mob/living/user)
|
||||
if (target == M.mind && M.stat == DEAD && M.mind.soulOwner == M.mind)
|
||||
if (cooldown)
|
||||
to_chat(user, "<span class='notice'>Give [M] a chance to think through the contract, don't rush [M.p_them()].</span>")
|
||||
return 0
|
||||
cooldown = TRUE
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/mob/dead/observer/ghost = H.get_ghost()
|
||||
var/response = "No"
|
||||
if(ghost)
|
||||
ghost.notify_cloning("A devil has offered you revival, at the cost of your soul.",'sound/effects/genetics.ogg', H)
|
||||
response = tgalert(ghost, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200)
|
||||
if(!ghost)
|
||||
return //handle logouts that happen whilst the alert is waiting for a response.
|
||||
else
|
||||
response = tgalert(target.current, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200)
|
||||
if(response == "Yes")
|
||||
H.revive(1,0)
|
||||
log_combat(user, H, "infernally revived via contract")
|
||||
user.visible_message("<span class='notice'>With a sudden blaze, [H] stands back up.</span>")
|
||||
H.fakefire()
|
||||
fulfillContract(H, 1)//Revival contracts are always signed in blood
|
||||
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/fakefireextinguish), 5, TIMER_UNIQUE)
|
||||
addtimer(CALLBACK(src, "resetcooldown"), 300, TIMER_UNIQUE)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/paper/contract/infernal/revive/proc/resetcooldown()
|
||||
cooldown = FALSE
|
||||
|
||||
|
||||
/obj/item/paper/contract/infernal/proc/fulfillContract(mob/living/carbon/human/user = target.current, blood = FALSE)
|
||||
signed = TRUE
|
||||
if(user.mind.soulOwner != user.mind) //They already sold their soul to someone else?
|
||||
var/datum/antagonist/devil/ownerDevilInfo = user.mind.soulOwner.has_antag_datum(/datum/antagonist/devil)
|
||||
ownerDevilInfo.remove_soul(user.mind) //Then they lose their claim.
|
||||
user.mind.soulOwner = owner
|
||||
user.hellbound = contractType
|
||||
user.mind.damnation_type = contractType
|
||||
var/datum/antagonist/devil/devilInfo = owner.has_antag_datum(/datum/antagonist/devil)
|
||||
devilInfo.add_soul(user.mind)
|
||||
update_text(user.real_name, blood)
|
||||
to_chat(user, "<span class='notice'>A profound emptiness washes over you as you lose ownership of your soul.</span>")
|
||||
to_chat(user, "<span class='boldnotice'>This does NOT make you an antagonist if you were not already.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/paper/contract/infernal/proc/signIncorrectly(mob/living/carbon/human/user = target.current, blood = FALSE)
|
||||
signed = 1
|
||||
update_text("your name", blood)
|
||||
|
||||
/obj/item/paper/contract/infernal/power/fulfillContract(mob/living/carbon/human/user = target.current, blood = FALSE)
|
||||
if(!user.dna)
|
||||
return -1
|
||||
user.dna.add_mutation(HULK)
|
||||
var/obj/item/organ/regenerative_core/organ = new /obj/item/organ/regenerative_core
|
||||
organ.Insert(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/wealth/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
|
||||
if(!istype(user) || !user.mind) // How in the hell could that happen?
|
||||
return -1
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_wealth(null))
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/prestige/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
|
||||
//Basically turns the signer into the captain, and uploads an ion law making them the captain.
|
||||
var/obj/item/worn = user.wear_id
|
||||
var/obj/item/card/id/id = null
|
||||
if(worn)
|
||||
id = worn.GetID()
|
||||
if(id)
|
||||
id.icon_state = "gold"
|
||||
id.access = get_all_accesses()+get_all_centcom_access()
|
||||
id.assignment = "Captain"
|
||||
id.update_label()
|
||||
else
|
||||
id = new /obj/item/card/id/gold(user.loc)
|
||||
id.registered_name = user.real_name
|
||||
id.access = get_all_accesses()+get_all_centcom_access()
|
||||
id.assignment = "Captain"
|
||||
id.update_label()
|
||||
if(worn)
|
||||
if(istype(worn, /obj/item/pda))
|
||||
var/obj/item/pda/PDA = worn
|
||||
PDA.id = id
|
||||
id.forceMove(worn)
|
||||
else if(istype(worn, /obj/item/storage/wallet))
|
||||
var/obj/item/storage/wallet/W = worn
|
||||
W.front_id = id
|
||||
id.forceMove(worn)
|
||||
worn.update_icon()
|
||||
var/datum/round_event/ion_storm/add_law_only/ion = new()
|
||||
ion.announceEvent = -1
|
||||
ion.ionMessage = "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law."
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/magic/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
|
||||
if(!istype(user) || !user.mind)
|
||||
return -1
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/robeless(null))
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/knowledge/fulfillContract(mob/living/carbon/human/user = target.current, blood = 0)
|
||||
if(!istype(user) || !user.mind)
|
||||
return -1
|
||||
user.dna.add_mutation(XRAY)
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/view_range(null))
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/contract/infernal/friend/fulfillContract(mob/living/user = target.current, blood = 0)
|
||||
if(!istype(user) || !user.mind)
|
||||
return -1
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_friend(null))
|
||||
return ..()
|
||||
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Paper
|
||||
* also scraps of paper
|
||||
*
|
||||
* lipstick wiping is in code/game/objects/items/weapons/cosmetics.dm!
|
||||
*/
|
||||
|
||||
/obj/item/paper
|
||||
name = "paper"
|
||||
gender = NEUTER
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paper"
|
||||
item_state = "paper"
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_range = 1
|
||||
throw_speed = 1
|
||||
pressure_resistance = 0
|
||||
slot_flags = ITEM_SLOT_HEAD
|
||||
body_parts_covered = HEAD
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 50
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
var/info //What's actually written on the paper.
|
||||
var/info_links //A different version of the paper which includes html links at fields and EOF
|
||||
var/stamps //The (text for the) stamps on the paper.
|
||||
var/fields = 0 //Amount of user created fields
|
||||
var/list/stamped
|
||||
var/rigged = 0
|
||||
var/spam_flag = 0
|
||||
var/contact_poison // Reagent ID to transfer on contact
|
||||
var/contact_poison_volume = 0
|
||||
var/datum/oracle_ui/ui = null
|
||||
var/force_stars = FALSE // If we should force the text to get obfuscated with asterisks
|
||||
|
||||
|
||||
/obj/item/paper/pickup(user)
|
||||
if(contact_poison && ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(!istype(G) || G.transfer_prints)
|
||||
H.reagents.add_reagent(contact_poison,contact_poison_volume)
|
||||
contact_poison = null
|
||||
ui.check_view_all()
|
||||
..()
|
||||
|
||||
/obj/item/paper/dropped(mob/user)
|
||||
ui.check_view(user)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/paper/Initialize()
|
||||
. = ..()
|
||||
pixel_y = rand(-8, 8)
|
||||
pixel_x = rand(-9, 9)
|
||||
ui = new /datum/oracle_ui(src, 420, 600, get_asset_datum(/datum/asset/spritesheet/simple/paper))
|
||||
ui.can_resize = FALSE
|
||||
update_icon()
|
||||
updateinfolinks()
|
||||
|
||||
/obj/item/paper/oui_getcontent(mob/target)
|
||||
if(!target.is_literate() || force_stars)
|
||||
force_stars = FALSE
|
||||
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
|
||||
else if(istype(target.get_active_held_item(), /obj/item/pen) | istype(target.get_active_held_item(), /obj/item/toy/crayon))
|
||||
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links]<HR>[stamps]</BODY><div align='right'style='position:fixed;bottom:0;font-style:bold;'><A href='?src=[REF(src)];help=1'>\[?\]</A></div></HTML>"
|
||||
else
|
||||
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info]<HR>[stamps]</BODY></HTML>"
|
||||
|
||||
/obj/item/paper/oui_canview(mob/target)
|
||||
if(check_rights_for(target.client, R_FUN)) //Allows admins to view faxes
|
||||
return TRUE
|
||||
if(isAI(target))
|
||||
force_stars = TRUE
|
||||
return TRUE
|
||||
if(iscyborg(target))
|
||||
return get_dist(src, target) < 2
|
||||
return ..()
|
||||
|
||||
/obj/item/paper/update_icon()
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
icon_state = "paper_onfire"
|
||||
return
|
||||
if(info)
|
||||
icon_state = "paper_words"
|
||||
return
|
||||
icon_state = "paper"
|
||||
|
||||
|
||||
/obj/item/paper/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to fold it.</span>")
|
||||
if(oui_canview(user))
|
||||
ui.render(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You're too far away to read it!</span>")
|
||||
|
||||
/obj/item/paper/proc/show_content(mob/user)
|
||||
user.examinate(src)
|
||||
|
||||
/obj/item/paper/verb/rename()
|
||||
set name = "Rename paper"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.incapacitated() || !usr.is_literate())
|
||||
return
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(HAS_TRAIT(H, TRAIT_CLUMSY) && prob(25))
|
||||
to_chat(H, "<span class='warning'>You cut yourself on the paper! Ahhhh! Ahhhhh!</span>")
|
||||
H.damageoverlaytemp = 9001
|
||||
H.update_damage_hud()
|
||||
return
|
||||
var/n_name = stripped_input(usr, "What would you like to label the paper?", "Paper Labelling", null, MAX_NAME_LEN)
|
||||
if((loc == usr && usr.stat == CONSCIOUS))
|
||||
name = "paper[(n_name ? text("- '[n_name]'") : null)]"
|
||||
add_fingerprint(usr)
|
||||
ui.render_all()
|
||||
|
||||
/obj/item/paper/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] scratches a grid on [user.p_their()] wrist with the paper! It looks like [user.p_theyre()] trying to commit sudoku...</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/paper/proc/reset_spamflag()
|
||||
spam_flag = FALSE
|
||||
|
||||
/obj/item/paper/attack_self(mob/user)
|
||||
show_content(user)
|
||||
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
|
||||
if(!spam_flag)
|
||||
spam_flag = TRUE
|
||||
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
addtimer(CALLBACK(src, .proc/reset_spamflag), 20)
|
||||
|
||||
/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
|
||||
show_content(user)
|
||||
|
||||
/obj/item/paper/proc/addtofield(id, text, links = 0)
|
||||
var/locid = 0
|
||||
var/laststart = 1
|
||||
var/textindex = 1
|
||||
while(locid < 15) //hey whoever decided a while(1) was a good idea here, i hate you
|
||||
var/istart = 0
|
||||
if(links)
|
||||
istart = findtext(info_links, "<span class=\"paper_field\">", laststart)
|
||||
else
|
||||
istart = findtext(info, "<span class=\"paper_field\">", laststart)
|
||||
|
||||
if(istart == 0)
|
||||
return //No field found with matching id
|
||||
|
||||
laststart = istart+1
|
||||
locid++
|
||||
if(locid == id)
|
||||
var/iend = 1
|
||||
if(links)
|
||||
iend = findtext(info_links, "</span>", istart)
|
||||
else
|
||||
iend = findtext(info, "</span>", istart)
|
||||
|
||||
//textindex = istart+26
|
||||
textindex = iend
|
||||
break
|
||||
|
||||
if(links)
|
||||
var/before = copytext(info_links, 1, textindex)
|
||||
var/after = copytext(info_links, textindex)
|
||||
info_links = before + text + after
|
||||
else
|
||||
var/before = copytext(info, 1, textindex)
|
||||
var/after = copytext(info, textindex)
|
||||
info = before + text + after
|
||||
updateinfolinks()
|
||||
|
||||
|
||||
/obj/item/paper/proc/updateinfolinks()
|
||||
info_links = info
|
||||
for(var/i in 1 to min(fields, 15))
|
||||
addtofield(i, "<font face=\"[PEN_FONT]\"><A href='?src=[REF(src)];write=[i]'>write</A></font>", 1)
|
||||
info_links = info_links + "<font face=\"[PEN_FONT]\"><A href='?src=[REF(src)];write=end'>write</A></font>"
|
||||
ui.render_all()
|
||||
|
||||
|
||||
/obj/item/paper/proc/clearpaper()
|
||||
info = null
|
||||
stamps = null
|
||||
LAZYCLEARLIST(stamped)
|
||||
cut_overlays()
|
||||
updateinfolinks()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/paper/proc/parsepencode(t, obj/item/pen/P, mob/user, iscrayon = 0)
|
||||
if(length(t) < 1) //No input means nothing needs to be parsed
|
||||
return
|
||||
|
||||
t = parsemarkdown(t, user, iscrayon)
|
||||
|
||||
if(!iscrayon)
|
||||
t = "<font face=\"[P.font]\" color=[P.colour]>[t]</font>"
|
||||
else
|
||||
var/obj/item/toy/crayon/C = P
|
||||
t = "<font face=\"[CRAYON_FONT]\" color=[C.paint_color]><b>[t]</b></font>"
|
||||
|
||||
// Count the fields
|
||||
var/laststart = 1
|
||||
while(fields < 15)
|
||||
var/i = findtext(t, "<span class=\"paper_field\">", laststart)
|
||||
if(i == 0)
|
||||
break
|
||||
laststart = i+1
|
||||
fields++
|
||||
|
||||
return t
|
||||
|
||||
/obj/item/paper/proc/reload_fields() // Useful if you made the paper programicly and want to include fields. Also runs updateinfolinks() for you.
|
||||
fields = 0
|
||||
var/laststart = 1
|
||||
while(fields < 15)
|
||||
var/i = findtext(info, "<span class=\"paper_field\">", laststart)
|
||||
if(i == 0)
|
||||
break
|
||||
laststart = i+1
|
||||
fields++
|
||||
updateinfolinks()
|
||||
|
||||
|
||||
/obj/item/paper/proc/openhelp(mob/user)
|
||||
user << browse({"<HTML><HEAD><TITLE>Paper Help</TITLE></HEAD>
|
||||
<BODY>
|
||||
You can use backslash (\\) to escape special characters.<br>
|
||||
<br>
|
||||
<b><center>Crayon&Pen commands</center></b><br>
|
||||
<br>
|
||||
# text : Defines a header.<br>
|
||||
|text| : Centers the text.<br>
|
||||
**text** : Makes the text <b>bold</b>.<br>
|
||||
*text* : Makes the text <i>italic</i>.<br>
|
||||
^text^ : Increases the <font size = \"4\">size</font> of the text.<br>
|
||||
%s : Inserts a signature of your name in a foolproof way.<br>
|
||||
%f : Inserts an invisible field which lets you start type from there. Useful for forms.<br>
|
||||
<br>
|
||||
<b><center>Pen exclusive commands</center></b><br>
|
||||
((text)) : Decreases the <font size = \"1\">size</font> of the text.<br>
|
||||
* item : An unordered list item.<br>
|
||||
* item: An unordered list child item.<br>
|
||||
--- : Adds a horizontal rule.
|
||||
</BODY></HTML>"}, "window=paper_help")
|
||||
|
||||
|
||||
/obj/item/paper/Topic(href, href_list)
|
||||
..()
|
||||
var/literate = usr.is_literate()
|
||||
if(!usr.canUseTopic(src, BE_CLOSE, literate))
|
||||
return
|
||||
|
||||
if(href_list["help"])
|
||||
openhelp(usr)
|
||||
return
|
||||
if(href_list["write"])
|
||||
var/id = href_list["write"]
|
||||
var/t = stripped_multiline_input("Enter what you want to write:", "Write", no_trim=TRUE)
|
||||
if(!t || !usr.canUseTopic(src, BE_CLOSE, literate))
|
||||
return
|
||||
var/obj/item/i = usr.get_active_held_item() //Check to see if he still got that darn pen, also check if he's using a crayon or pen.
|
||||
var/iscrayon = 0
|
||||
if(!istype(i, /obj/item/pen))
|
||||
if(!istype(i, /obj/item/toy/crayon))
|
||||
return
|
||||
iscrayon = 1
|
||||
|
||||
if(!in_range(src, usr) && loc != usr && !istype(loc, /obj/item/clipboard) && loc.loc != usr && usr.get_active_held_item() != i) //Some check to see if he's allowed to write
|
||||
return
|
||||
|
||||
t = parsepencode(t, i, usr, iscrayon) // Encode everything from pencode to html
|
||||
|
||||
if(t != null) //No input from the user means nothing needs to be added
|
||||
if(id!="end")
|
||||
addtofield(text2num(id), t) // He wants to edit a field, let him.
|
||||
else
|
||||
info += t // Oh, he wants to edit to the end of the file, let him.
|
||||
updateinfolinks()
|
||||
show_content(usr)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/paper/attackby(obj/item/P, mob/living/carbon/human/user, params)
|
||||
..()
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
return
|
||||
|
||||
if(is_blind(user))
|
||||
return
|
||||
|
||||
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
|
||||
if(user.is_literate())
|
||||
show_content(user)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't know how to read or write.</span>")
|
||||
return
|
||||
|
||||
else if(istype(P, /obj/item/stamp))
|
||||
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
|
||||
if (isnull(stamps))
|
||||
stamps = sheet.css_tag()
|
||||
stamps += sheet.icon_tag(P.icon_state)
|
||||
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]")
|
||||
stampoverlay.pixel_x = rand(-2, 2)
|
||||
stampoverlay.pixel_y = rand(-3, 2)
|
||||
|
||||
LAZYADD(stamped, P.icon_state)
|
||||
add_overlay(stampoverlay)
|
||||
|
||||
to_chat(user, "<span class='notice'>You stamp the paper with your rubber stamp.</span>")
|
||||
ui.render_all()
|
||||
|
||||
if(P.get_temperature())
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
|
||||
user.visible_message("<span class='warning'>[user] accidentally ignites [user.p_them()]self!</span>", \
|
||||
"<span class='userdanger'>You miss the paper and accidentally light yourself on fire!</span>")
|
||||
user.dropItemToGround(P)
|
||||
user.adjust_fire_stacks(1)
|
||||
user.IgniteMob()
|
||||
return
|
||||
|
||||
if(!(in_range(user, src))) //to prevent issues as a result of telepathically lighting a paper
|
||||
return
|
||||
|
||||
user.dropItemToGround(src)
|
||||
user.visible_message("<span class='danger'>[user] lights [src] ablaze with [P]!</span>", "<span class='danger'>You light [src] on fire!</span>")
|
||||
fire_act()
|
||||
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/paper/fire_act(exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(!(resistance_flags & FIRE_PROOF))
|
||||
icon_state = "paper_onfire"
|
||||
info = "[stars(info)]"
|
||||
|
||||
|
||||
/obj/item/paper/extinguish()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/*
|
||||
* Construction paper
|
||||
*/
|
||||
|
||||
/obj/item/paper/construction
|
||||
|
||||
/obj/item/paper/construction/Initialize()
|
||||
. = ..()
|
||||
color = pick("FF0000", "#33cc33", "#ffb366", "#551A8B", "#ff80d5", "#4d94ff")
|
||||
|
||||
/*
|
||||
* Natural paper
|
||||
*/
|
||||
|
||||
/obj/item/paper/natural/Initialize()
|
||||
. = ..()
|
||||
color = "#FFF5ED"
|
||||
|
||||
/obj/item/paper/crumpled
|
||||
name = "paper scrap"
|
||||
icon_state = "scrap"
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/paper/crumpled/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/paper/crumpled/bloody
|
||||
icon_state = "scrap_bloodied"
|
||||
@@ -0,0 +1,172 @@
|
||||
/obj/item/paper_bin
|
||||
name = "paper bin"
|
||||
desc = "Contains all the paper you'll never need."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paper_bin1"
|
||||
item_state = "sheet-metal"
|
||||
lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi'
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
pressure_resistance = 8
|
||||
var/papertype = /obj/item/paper
|
||||
var/total_paper = 30
|
||||
var/list/papers = list()
|
||||
var/obj/item/pen/bin_pen
|
||||
|
||||
/obj/item/paper_bin/Initialize(mapload)
|
||||
. = ..()
|
||||
interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
|
||||
if(!mapload)
|
||||
return
|
||||
var/obj/item/pen/P = locate(/obj/item/pen) in src.loc
|
||||
if(P && !bin_pen)
|
||||
P.forceMove(src)
|
||||
bin_pen = P
|
||||
update_icon()
|
||||
|
||||
/obj/item/paper_bin/Destroy()
|
||||
if(papers)
|
||||
for(var/i in papers)
|
||||
qdel(i)
|
||||
papers = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/paper_bin/fire_act(exposed_temperature, exposed_volume)
|
||||
if(total_paper)
|
||||
total_paper = 0
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/obj/item/paper_bin/MouseDrop(atom/over_object)
|
||||
. = ..()
|
||||
var/mob/living/M = usr
|
||||
if(!istype(M) || M.incapacitated() || !Adjacent(M))
|
||||
return
|
||||
|
||||
if(over_object == M)
|
||||
M.put_in_hands(src)
|
||||
|
||||
else if(istype(over_object, /obj/screen/inventory/hand))
|
||||
var/obj/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
|
||||
|
||||
add_fingerprint(M)
|
||||
|
||||
/obj/item/paper_bin/attack_paw(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/paper_bin/attack_hand(mob/user)
|
||||
if(user.lying)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(bin_pen)
|
||||
var/obj/item/pen/P = bin_pen
|
||||
P.add_fingerprint(user)
|
||||
P.forceMove(user.loc)
|
||||
user.put_in_hands(P)
|
||||
to_chat(user, "<span class='notice'>You take [P] out of \the [src].</span>")
|
||||
bin_pen = null
|
||||
update_icon()
|
||||
else if(total_paper >= 1)
|
||||
total_paper--
|
||||
update_icon()
|
||||
// If there's any custom paper on the stack, use that instead of creating a new paper.
|
||||
var/obj/item/paper/P
|
||||
if(papers.len > 0)
|
||||
P = papers[papers.len]
|
||||
papers.Remove(P)
|
||||
else
|
||||
P = new papertype(src)
|
||||
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
|
||||
if(prob(30))
|
||||
P.info = "<font face=\"[CRAYON_FONT]\" color=\"red\"><b>HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK<br>APRIL FOOLS</b></font>"
|
||||
P.rigged = 1
|
||||
P.updateinfolinks()
|
||||
|
||||
P.add_fingerprint(user)
|
||||
P.forceMove(user.loc)
|
||||
user.put_in_hands(P)
|
||||
to_chat(user, "<span class='notice'>You take [P] out of \the [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
add_fingerprint(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/paper_bin/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/paper))
|
||||
var/obj/item/paper/P = I
|
||||
if(!user.transferItemToLoc(P, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You put [P] in [src].</span>")
|
||||
papers.Add(P)
|
||||
total_paper++
|
||||
update_icon()
|
||||
else if(istype(I, /obj/item/pen) && !bin_pen)
|
||||
var/obj/item/pen/P = I
|
||||
if(!user.transferItemToLoc(P, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You put [P] in [src].</span>")
|
||||
bin_pen = P
|
||||
update_icon()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/paper_bin/examine(mob/user)
|
||||
..()
|
||||
if(total_paper)
|
||||
to_chat(user, "It contains " + (total_paper > 1 ? "[total_paper] papers" : " one paper")+".")
|
||||
else
|
||||
to_chat(user, "It doesn't contain anything.")
|
||||
|
||||
|
||||
/obj/item/paper_bin/update_icon()
|
||||
if(total_paper < 1)
|
||||
icon_state = "paper_bin0"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
cut_overlays()
|
||||
if(bin_pen)
|
||||
add_overlay(mutable_appearance(bin_pen.icon, bin_pen.icon_state))
|
||||
|
||||
/obj/item/paper_bin/construction
|
||||
name = "construction paper bin"
|
||||
desc = "Contains all the paper you'll never need, IN COLOR!"
|
||||
icon_state = "paper_binc"
|
||||
papertype = /obj/item/paper/construction
|
||||
|
||||
/obj/item/paper_bin/bundlenatural
|
||||
name = "natural paper bundle"
|
||||
desc = "A bundle of paper created using traditional methods."
|
||||
icon_state = "paper_bundle"
|
||||
papertype = /obj/item/paper/natural
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/paper_bin/bundlenatural/attack_hand(mob/user)
|
||||
..()
|
||||
if(total_paper < 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/paper_bin/bundlenatural/fire_act(exposed_temperature, exposed_volume)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/paper_bin/bundlenatural/attackby(obj/item/W, mob/user)
|
||||
if(W.get_sharpness())
|
||||
to_chat(user, "<span class='notice'>You snip \the [src], spilling paper everywhere.</span>")
|
||||
var/turf/T = get_turf(src.loc)
|
||||
while(total_paper > 0)
|
||||
total_paper--
|
||||
var/obj/item/paper/P
|
||||
if(papers.len > 0)
|
||||
P = papers[papers.len]
|
||||
papers -= P
|
||||
else
|
||||
P = new papertype()
|
||||
P.forceMove(T)
|
||||
CHECK_TICK
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,136 @@
|
||||
|
||||
/obj/item/paperplane
|
||||
name = "paper plane"
|
||||
desc = "Paper, folded in the shape of a plane."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paperplane"
|
||||
throw_range = 7
|
||||
throw_speed = 1
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 50
|
||||
|
||||
var/hit_probability = 2//%
|
||||
var/obj/item/paper/internalPaper
|
||||
|
||||
/obj/item/paperplane/origami
|
||||
desc = "Paper, masterfully folded in the shape of a plane."
|
||||
throwforce = 20 //same as throwing stars, but no chance of embedding.
|
||||
hit_probability = 100 //guaranteed to cause eye damage when it hits a mob.
|
||||
|
||||
/obj/item/paperplane/Initialize(mapload, obj/item/paper/newPaper)
|
||||
. = ..()
|
||||
pixel_y = rand(-8, 8)
|
||||
pixel_x = rand(-9, 9)
|
||||
if(newPaper)
|
||||
internalPaper = newPaper
|
||||
flags_1 = newPaper.flags_1
|
||||
color = newPaper.color
|
||||
newPaper.forceMove(src)
|
||||
else
|
||||
internalPaper = new(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/paperplane/handle_atom_del(atom/A)
|
||||
if(A == internalPaper)
|
||||
internalPaper = null
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/paperplane/Destroy()
|
||||
QDEL_NULL(internalPaper)
|
||||
return ..()
|
||||
|
||||
/obj/item/paperplane/suicide_act(mob/living/user)
|
||||
user.Stun(200)
|
||||
user.visible_message("<span class='suicide'>[user] jams [src] in [user.p_their()] nose. It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
user.adjust_blurriness(6)
|
||||
user.adjust_eye_damage(rand(6,8))
|
||||
sleep(10)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/paperplane/update_icon()
|
||||
cut_overlays()
|
||||
var/list/stamped = internalPaper.stamped
|
||||
if(stamped)
|
||||
for(var/S in stamped)
|
||||
add_overlay("paperplane_[S]")
|
||||
|
||||
/obj/item/paperplane/attack_self(mob/user)
|
||||
to_chat(user, "<span class='notice'>You unfold [src].</span>")
|
||||
var/obj/item/paper/internal_paper_tmp = internalPaper
|
||||
internal_paper_tmp.forceMove(loc)
|
||||
internalPaper = null
|
||||
qdel(src)
|
||||
user.put_in_hands(internal_paper_tmp)
|
||||
|
||||
/obj/item/paperplane/attackby(obj/item/P, mob/living/carbon/human/user, params)
|
||||
..()
|
||||
if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
|
||||
to_chat(user, "<span class='notice'>You should unfold [src] before changing it.</span>")
|
||||
return
|
||||
|
||||
else if(istype(P, /obj/item/stamp)) //we don't randomize stamps on a paperplane
|
||||
internalPaper.attackby(P, user) //spoofed attack to update internal paper.
|
||||
update_icon()
|
||||
|
||||
else if(P.get_temperature())
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
|
||||
user.visible_message("<span class='warning'>[user] accidentally ignites [user.p_them()]self!</span>", \
|
||||
"<span class='userdanger'>You miss [src] and accidentally light yourself on fire!</span>")
|
||||
user.dropItemToGround(P)
|
||||
user.adjust_fire_stacks(1)
|
||||
user.IgniteMob()
|
||||
return
|
||||
|
||||
if(!(in_range(user, src))) //to prevent issues as a result of telepathically lighting a paper
|
||||
return
|
||||
user.dropItemToGround(src)
|
||||
user.visible_message("<span class='danger'>[user] lights [src] ablaze with [P]!</span>", "<span class='danger'>You light [src] on fire!</span>")
|
||||
fire_act()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
/obj/item/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback)
|
||||
. = ..(target, range, speed, thrower, FALSE, diagonals_first, callback)
|
||||
|
||||
/obj/item/paperplane/throw_impact(atom/hit_atom)
|
||||
if(iscarbon(hit_atom))
|
||||
var/mob/living/carbon/C = hit_atom
|
||||
if(C.can_catch_item(TRUE))
|
||||
var/datum/action/innate/origami/origami_action = locate() in C.actions
|
||||
if(origami_action?.active) //if they're a master of origami and have the ability turned on, force throwmode on so they'll automatically catch the plane.
|
||||
C.throw_mode_on()
|
||||
|
||||
if(..() || !ishuman(hit_atom))//if the plane is caught or it hits a nonhuman
|
||||
return
|
||||
var/mob/living/carbon/human/H = hit_atom
|
||||
if(prob(hit_probability))
|
||||
if(H.is_eyes_covered())
|
||||
return
|
||||
visible_message("<span class='danger'>\The [src] hits [H] in the eye!</span>")
|
||||
H.adjust_blurriness(6)
|
||||
H.adjust_eye_damage(rand(6,8))
|
||||
H.Knockdown(40)
|
||||
H.emote("scream")
|
||||
|
||||
/obj/item/paper/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click [src] to fold it into a paper plane.</span>")
|
||||
|
||||
/obj/item/paper/AltClick(mob/living/carbon/user, obj/item/I)
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user), NO_TK))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You fold [src] into the shape of a plane!</span>")
|
||||
user.temporarilyRemoveItemFromInventory(src)
|
||||
var/obj/item/paperplane/plane_type = /obj/item/paperplane
|
||||
//Origami Master
|
||||
var/datum/action/innate/origami/origami_action = locate() in user.actions
|
||||
if(origami_action?.active)
|
||||
plane_type = /obj/item/paperplane/origami
|
||||
|
||||
I = new plane_type(user, src)
|
||||
user.put_in_hands(I)
|
||||
@@ -0,0 +1,218 @@
|
||||
/* Pens!
|
||||
* Contains:
|
||||
* Pens
|
||||
* Sleepy Pens
|
||||
* Parapens
|
||||
* Edaggers
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Pens
|
||||
*/
|
||||
/obj/item/pen
|
||||
desc = "It's a normal black ink pen."
|
||||
name = "pen"
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "pen"
|
||||
item_state = "pen"
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_EARS
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL=10)
|
||||
pressure_resistance = 2
|
||||
grind_results = list("iron" = 2, "iodine" = 1)
|
||||
var/colour = "black" //what colour the ink is!
|
||||
var/degrees = 0
|
||||
var/font = PEN_FONT
|
||||
|
||||
/obj/item/pen/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...</span>")
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/pen/blue
|
||||
desc = "It's a normal blue ink pen."
|
||||
icon_state = "pen_blue"
|
||||
colour = "blue"
|
||||
|
||||
/obj/item/pen/red
|
||||
desc = "It's a normal red ink pen."
|
||||
icon_state = "pen_red"
|
||||
colour = "red"
|
||||
|
||||
/obj/item/pen/invisible
|
||||
desc = "It's an invisible pen marker."
|
||||
icon_state = "pen"
|
||||
colour = "white"
|
||||
|
||||
/obj/item/pen/fourcolor
|
||||
desc = "It's a fancy four-color ink pen, set to black."
|
||||
name = "four-color pen"
|
||||
colour = "black"
|
||||
|
||||
/obj/item/pen/fourcolor/attack_self(mob/living/carbon/user)
|
||||
switch(colour)
|
||||
if("black")
|
||||
colour = "red"
|
||||
if("red")
|
||||
colour = "green"
|
||||
if("green")
|
||||
colour = "blue"
|
||||
else
|
||||
colour = "black"
|
||||
to_chat(user, "<span class='notice'>\The [src] will now write in [colour].</span>")
|
||||
desc = "It's a fancy four-color ink pen, set to [colour]."
|
||||
|
||||
/obj/item/pen/fountain
|
||||
name = "fountain pen"
|
||||
desc = "It's a common fountain pen, with a faux wood body."
|
||||
icon_state = "pen-fountain"
|
||||
font = FOUNTAIN_PEN_FONT
|
||||
|
||||
/obj/item/pen/fountain/captain
|
||||
name = "captain's fountain pen"
|
||||
desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
|
||||
icon_state = "pen-fountain-o"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_speed = 4
|
||||
colour = "crimson"
|
||||
materials = list(MAT_GOLD = 750)
|
||||
sharpness = IS_SHARP
|
||||
resistance_flags = FIRE_PROOF
|
||||
unique_reskin = list("Oak" = "pen-fountain-o",
|
||||
"Gold" = "pen-fountain-g",
|
||||
"Rosewood" = "pen-fountain-r",
|
||||
"Black and Silver" = "pen-fountain-b",
|
||||
"Command Blue" = "pen-fountain-cb"
|
||||
)
|
||||
|
||||
/obj/item/pen/fountain/captain/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 200, 115) //the pen is mightier than the sword
|
||||
|
||||
/obj/item/pen/fountain/captain/reskin_obj(mob/M)
|
||||
..()
|
||||
if(current_skin)
|
||||
desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp."
|
||||
|
||||
/obj/item/pen/attack_self(mob/living/carbon/user)
|
||||
var/deg = input(user, "What angle would you like to rotate the pen head to? (1-360)", "Rotate Pen Head") as null|num
|
||||
if(deg && (deg > 0 && deg <= 360))
|
||||
degrees = deg
|
||||
to_chat(user, "<span class='notice'>You rotate the top of the pen to [degrees] degrees.</span>")
|
||||
SEND_SIGNAL(src, COMSIG_PEN_ROTATED, deg, user)
|
||||
|
||||
/obj/item/pen/attack(mob/living/M, mob/user,stealth)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(!force)
|
||||
if(M.can_inject(user, 1))
|
||||
to_chat(user, "<span class='warning'>You stab [M] with the pen.</span>")
|
||||
if(!stealth)
|
||||
to_chat(M, "<span class='danger'>You feel a tiny prick!</span>")
|
||||
. = 1
|
||||
|
||||
log_combat(user, M, "stabbed", src)
|
||||
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/pen/afterattack(obj/O, mob/living/user, proximity)
|
||||
. = ..()
|
||||
//Changing Name/Description of items. Only works if they have the 'unique_rename' flag set
|
||||
if(isobj(O) && proximity && (O.obj_flags & UNIQUE_RENAME))
|
||||
var/penchoice = input(user, "What would you like to edit?", "Rename or change description?") as null|anything in list("Rename","Change description")
|
||||
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
|
||||
return
|
||||
if(penchoice == "Rename")
|
||||
var/input = stripped_input(user,"What do you want to name \the [O.name]?", ,"", MAX_NAME_LEN)
|
||||
var/oldname = O.name
|
||||
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
|
||||
return
|
||||
if(oldname == input)
|
||||
to_chat(user, "You changed \the [O.name] to... well... \the [O.name].")
|
||||
else
|
||||
O.name = input
|
||||
to_chat(user, "\The [oldname] has been successfully been renamed to \the [input].")
|
||||
O.renamedByPlayer = TRUE
|
||||
|
||||
if(penchoice == "Change description")
|
||||
var/input = stripped_input(user,"Describe \the [O.name] here", ,"", 100)
|
||||
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
|
||||
return
|
||||
O.desc = input
|
||||
to_chat(user, "You have successfully changed \the [O.name]'s description.")
|
||||
|
||||
/*
|
||||
* Sleepypens
|
||||
*/
|
||||
|
||||
/obj/item/pen/sleepy/attack(mob/living/M, mob/user)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(..())
|
||||
if(reagents.total_volume)
|
||||
if(M.reagents)
|
||||
reagents.reaction(M, INJECT)
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
|
||||
|
||||
/obj/item/pen/sleepy/Initialize()
|
||||
. = ..()
|
||||
create_reagents(45, OPENCONTAINER)
|
||||
reagents.add_reagent("chloralhydrate", 20)
|
||||
reagents.add_reagent("mutetoxin", 15)
|
||||
reagents.add_reagent("tirizene", 10)
|
||||
|
||||
/*
|
||||
* (Alan) Edaggers
|
||||
*/
|
||||
/obj/item/pen/edagger
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/pen/edagger/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 60, 100, 0, 'sound/weapons/blade1.ogg', TRUE)
|
||||
|
||||
/obj/item/pen/edagger/attack_self(mob/living/user)
|
||||
if(on)
|
||||
on = FALSE
|
||||
force = initial(force)
|
||||
w_class = initial(w_class)
|
||||
name = initial(name)
|
||||
hitsound = initial(hitsound)
|
||||
embedding = embedding.setRating(embed_chance = EMBED_CHANCE)
|
||||
throwforce = initial(throwforce)
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 5, 1)
|
||||
to_chat(user, "<span class='warning'>[src] can now be concealed.</span>")
|
||||
else
|
||||
on = TRUE
|
||||
force = 18
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
name = "energy dagger"
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
embedding = embedding.setRating(embed_chance = 100) //rule of cool
|
||||
throwforce = 35
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
|
||||
to_chat(user, "<span class='warning'>[src] is now active.</span>")
|
||||
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
|
||||
butchering.butchering_enabled = on
|
||||
update_icon()
|
||||
|
||||
/obj/item/pen/edagger/update_icon()
|
||||
if(on)
|
||||
icon_state = "edagger"
|
||||
item_state = "edagger"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
else
|
||||
icon_state = initial(icon_state) //looks like a normal pen when off.
|
||||
item_state = initial(item_state)
|
||||
lefthand_file = initial(lefthand_file)
|
||||
righthand_file = initial(righthand_file)
|
||||
Reference in New Issue
Block a user