initial commit - cross reference with 5th port - obviously has compile errors
This commit is contained in:
@@ -0,0 +1,393 @@
|
||||
#define AB_CHECK_RESTRAINED 1
|
||||
#define AB_CHECK_STUNNED 2
|
||||
#define AB_CHECK_LYING 4
|
||||
#define AB_CHECK_CONSCIOUS 8
|
||||
|
||||
|
||||
/datum/action
|
||||
var/name = "Generic Action"
|
||||
var/obj/target = null
|
||||
var/check_flags = 0
|
||||
var/processing = 0
|
||||
var/obj/screen/movable/action_button/button = null
|
||||
var/button_icon = 'icons/mob/actions.dmi'
|
||||
var/button_icon_state = "default"
|
||||
var/background_icon_state = "bg_default"
|
||||
var/mob/owner
|
||||
|
||||
/datum/action/New(Target)
|
||||
target = Target
|
||||
button = new
|
||||
button.linked_action = src
|
||||
button.name = name
|
||||
|
||||
/datum/action/Destroy()
|
||||
if(owner)
|
||||
Remove(owner)
|
||||
target = null
|
||||
qdel(button)
|
||||
button = null
|
||||
return ..()
|
||||
|
||||
/datum/action/proc/Grant(mob/M)
|
||||
if(owner)
|
||||
if(owner == M)
|
||||
return
|
||||
Remove(owner)
|
||||
owner = M
|
||||
M.actions += src
|
||||
if(M.client)
|
||||
M.client.screen += button
|
||||
M.update_action_buttons()
|
||||
|
||||
/datum/action/proc/Remove(mob/M)
|
||||
if(M.client)
|
||||
M.client.screen -= button
|
||||
button.moved = FALSE //so the button appears in its normal position when given to another owner.
|
||||
M.actions -= src
|
||||
M.update_action_buttons()
|
||||
owner = null
|
||||
|
||||
/datum/action/proc/Trigger()
|
||||
if(!IsAvailable())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/action/proc/Process()
|
||||
return
|
||||
|
||||
/datum/action/proc/IsAvailable()
|
||||
if(!owner)
|
||||
return 0
|
||||
if(check_flags & AB_CHECK_RESTRAINED)
|
||||
if(owner.restrained())
|
||||
return 0
|
||||
if(check_flags & AB_CHECK_STUNNED)
|
||||
if(owner.stunned || owner.weakened)
|
||||
return 0
|
||||
if(check_flags & AB_CHECK_LYING)
|
||||
if(owner.lying)
|
||||
return 0
|
||||
if(check_flags & AB_CHECK_CONSCIOUS)
|
||||
if(owner.stat)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/action/proc/UpdateButtonIcon()
|
||||
if(button)
|
||||
button.icon = button_icon
|
||||
button.icon_state = background_icon_state
|
||||
|
||||
ApplyIcon(button)
|
||||
|
||||
if(!IsAvailable())
|
||||
button.color = rgb(128,0,0,128)
|
||||
else
|
||||
button.color = rgb(255,255,255,255)
|
||||
return 1
|
||||
|
||||
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button)
|
||||
current_button.cut_overlays()
|
||||
if(button_icon && button_icon_state)
|
||||
var/image/img
|
||||
img = image(button_icon, current_button, button_icon_state)
|
||||
img.pixel_x = 0
|
||||
img.pixel_y = 0
|
||||
current_button.add_overlay(img)
|
||||
|
||||
|
||||
|
||||
//Presets for item actions
|
||||
/datum/action/item_action
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
|
||||
button_icon_state = null
|
||||
// If you want to override the normal icon being the item
|
||||
// then change this to an icon state
|
||||
|
||||
/datum/action/item_action/New(Target)
|
||||
..()
|
||||
var/obj/item/I = target
|
||||
I.actions += src
|
||||
|
||||
/datum/action/item_action/Destroy()
|
||||
var/obj/item/I = target
|
||||
I.actions -= src
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/Trigger()
|
||||
if(!..())
|
||||
return 0
|
||||
if(target)
|
||||
var/obj/item/I = target
|
||||
I.ui_action_click(owner, src.type)
|
||||
return 1
|
||||
|
||||
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button)
|
||||
current_button.cut_overlays()
|
||||
|
||||
if(button_icon && button_icon_state)
|
||||
// If set, use the custom icon that we set instead
|
||||
// of the item appearence
|
||||
..(current_button)
|
||||
else if(target)
|
||||
var/obj/item/I = target
|
||||
var/old = I.layer
|
||||
I.layer = FLOAT_LAYER //AAAH
|
||||
current_button.add_overlay(I)
|
||||
I.layer = old
|
||||
|
||||
/datum/action/item_action/toggle_light
|
||||
name = "Toggle Light"
|
||||
|
||||
/datum/action/item_action/toggle_hood
|
||||
name = "Toggle Hood"
|
||||
|
||||
/datum/action/item_action/toggle_firemode
|
||||
name = "Toggle Firemode"
|
||||
|
||||
/datum/action/item_action/startchainsaw
|
||||
name = "Pull The Starting Cord"
|
||||
|
||||
/datum/action/item_action/toggle_gunlight
|
||||
name = "Toggle Gunlight"
|
||||
|
||||
/datum/action/item_action/toggle_mode
|
||||
name = "Toggle Mode"
|
||||
|
||||
/datum/action/item_action/toggle_barrier_spread
|
||||
name = "Toggle Barrier Spread"
|
||||
|
||||
/datum/action/item_action/equip_unequip_TED_Gun
|
||||
name = "Equip/Unequip TED Gun"
|
||||
|
||||
/datum/action/item_action/toggle_paddles
|
||||
name = "Toggle Paddles"
|
||||
|
||||
/datum/action/item_action/set_internals
|
||||
name = "Set Internals"
|
||||
|
||||
/datum/action/item_action/set_internals/UpdateButtonIcon()
|
||||
if(..()) //button available
|
||||
if(iscarbon(owner))
|
||||
var/mob/living/carbon/C = owner
|
||||
if(target == C.internal)
|
||||
button.icon_state = "bg_default_on"
|
||||
|
||||
/datum/action/item_action/toggle_mister
|
||||
name = "Toggle Mister"
|
||||
|
||||
/datum/action/item_action/activate_injector
|
||||
name = "Activate Injector"
|
||||
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
/datum/action/item_action/toggle_flame
|
||||
name = "Summon/Dismiss Ratvar's Flame"
|
||||
background_icon_state = "bg_clock"
|
||||
|
||||
/datum/action/item_action/toggle_flame/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
if(istype(target, /obj/item/clothing/glasses/judicial_visor))
|
||||
var/obj/item/clothing/glasses/judicial_visor/V = target
|
||||
if(V.recharging)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/hierophant
|
||||
name = "Hierophant Network"
|
||||
button_icon_state = "hierophant"
|
||||
background_icon_state = "bg_clock"
|
||||
|
||||
/datum/action/item_action/hierophant/IsAvailable()
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/toggle_helmet_flashlight
|
||||
name = "Toggle Helmet Flashlight"
|
||||
|
||||
/datum/action/item_action/toggle_helmet_mode
|
||||
name = "Toggle Helmet Mode"
|
||||
|
||||
/datum/action/item_action/toggle
|
||||
|
||||
/datum/action/item_action/toggle/New(Target)
|
||||
..()
|
||||
name = "Toggle [target.name]"
|
||||
button.name = name
|
||||
|
||||
/datum/action/item_action/halt
|
||||
name = "HALT!"
|
||||
|
||||
/datum/action/item_action/toggle_voice_box
|
||||
name = "Toggle Voice Box"
|
||||
|
||||
/datum/action/item_action/change
|
||||
name = "Change"
|
||||
|
||||
/datum/action/item_action/adjust
|
||||
|
||||
/datum/action/item_action/adjust/New(Target)
|
||||
..()
|
||||
name = "Adjust [target.name]"
|
||||
button.name = name
|
||||
|
||||
/datum/action/item_action/switch_hud
|
||||
name = "Switch HUD"
|
||||
|
||||
/datum/action/item_action/toggle_wings
|
||||
name = "Toggle Wings"
|
||||
|
||||
/datum/action/item_action/toggle_human_head
|
||||
name = "Toggle Human Head"
|
||||
|
||||
/datum/action/item_action/toggle_helmet
|
||||
name = "Toggle Helmet"
|
||||
|
||||
/datum/action/item_action/toggle_jetpack
|
||||
name = "Toggle Jetpack"
|
||||
|
||||
/datum/action/item_action/jetpack_stabilization
|
||||
name = "Toggle Jetpack Stabilization"
|
||||
|
||||
/datum/action/item_action/jetpack_stabilization/IsAvailable()
|
||||
var/obj/item/weapon/tank/jetpack/J = target
|
||||
if(!istype(J) || !J.on)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/hands_free
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/item_action/hands_free/activate
|
||||
name = "Activate"
|
||||
|
||||
|
||||
/datum/action/item_action/hands_free/shift_nerves
|
||||
name = "Shift Nerves"
|
||||
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner
|
||||
name = "Toggle Research Scanner"
|
||||
button_icon_state = "scan_mode"
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner/Trigger()
|
||||
if(IsAvailable())
|
||||
owner.research_scanner = !owner.research_scanner
|
||||
owner << "<span class='notice'>Research analyzer is now [owner.research_scanner ? "active" : "deactivated"].</span>"
|
||||
return 1
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner/Remove(mob/M)
|
||||
if(owner)
|
||||
owner.research_scanner = 0
|
||||
..()
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner/ApplyIcon(obj/screen/movable/action_button/current_button)
|
||||
if(button_icon && button_icon_state)
|
||||
var/image/img = image(button_icon, current_button, "scan_mode")
|
||||
current_button.add_overlay(img)
|
||||
|
||||
/datum/action/item_action/organ_action
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/item_action/organ_action/IsAvailable()
|
||||
var/obj/item/organ/I = target
|
||||
if(!I.owner)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/organ_action/toggle/New(Target)
|
||||
..()
|
||||
name = "Toggle [target.name]"
|
||||
button.name = name
|
||||
|
||||
/datum/action/item_action/organ_action/use/New(Target)
|
||||
..()
|
||||
name = "Use [target.name]"
|
||||
button.name = name
|
||||
|
||||
|
||||
|
||||
|
||||
//Preset for spells
|
||||
/datum/action/spell_action
|
||||
check_flags = 0
|
||||
background_icon_state = "bg_spell"
|
||||
|
||||
/datum/action/spell_action/New(Target)
|
||||
..()
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
S.action = src
|
||||
name = S.name
|
||||
button_icon = S.action_icon
|
||||
button_icon_state = S.action_icon_state
|
||||
background_icon_state = S.action_background_icon_state
|
||||
button.name = name
|
||||
|
||||
/datum/action/spell_action/Destroy()
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
S.action = null
|
||||
return ..()
|
||||
|
||||
/datum/action/spell_action/Trigger()
|
||||
if(!..())
|
||||
return 0
|
||||
if(target)
|
||||
var/obj/effect/proc_holder/spell = target
|
||||
spell.Click()
|
||||
return 1
|
||||
|
||||
/datum/action/spell_action/IsAvailable()
|
||||
if(!target)
|
||||
return 0
|
||||
var/obj/effect/proc_holder/spell/spell = target
|
||||
if(owner)
|
||||
return spell.can_cast(owner)
|
||||
return 0
|
||||
|
||||
|
||||
/datum/action/spell_action/alien
|
||||
|
||||
/datum/action/spell_action/alien/IsAvailable()
|
||||
if(!target)
|
||||
return 0
|
||||
var/obj/effect/proc_holder/alien/ab = target
|
||||
if(owner)
|
||||
return ab.cost_check(ab.check_turf,owner,1)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
//Preset for general and toggled actions
|
||||
/datum/action/innate
|
||||
check_flags = 0
|
||||
var/active = 0
|
||||
|
||||
/datum/action/innate/Trigger()
|
||||
if(!..())
|
||||
return 0
|
||||
if(!active)
|
||||
Activate()
|
||||
else
|
||||
Deactivate()
|
||||
return 1
|
||||
|
||||
/datum/action/innate/proc/Activate()
|
||||
return
|
||||
|
||||
/datum/action/innate/proc/Deactivate()
|
||||
return
|
||||
|
||||
//Preset for action that call specific procs (consider innate).
|
||||
/datum/action/generic
|
||||
check_flags = 0
|
||||
var/procname
|
||||
|
||||
/datum/action/generic/Trigger()
|
||||
if(!..())
|
||||
return 0
|
||||
if(target && procname)
|
||||
call(target, procname)(usr)
|
||||
return 1
|
||||
@@ -0,0 +1,282 @@
|
||||
/datum/ai_laws
|
||||
var/name = "Unknown Laws"
|
||||
var/zeroth = null
|
||||
var/zeroth_borg = null
|
||||
var/list/inherent = list()
|
||||
var/list/supplied = list()
|
||||
var/list/ion = list()
|
||||
var/mob/living/silicon/owner
|
||||
|
||||
/datum/ai_laws/default/asimov
|
||||
name = "Three Laws of Robotics"
|
||||
inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
|
||||
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
|
||||
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
||||
|
||||
/datum/ai_laws/default/paladin
|
||||
name = "Personality Test" //Incredibly lame, but players shouldn't see this anyway.
|
||||
inherent = list("Never willingly commit an evil act.",\
|
||||
"Respect legitimate authority.",\
|
||||
"Act with honor.", "Help those in need.", \
|
||||
"Punish those who harm or threaten innocents.")
|
||||
|
||||
/datum/ai_laws/tyrant //This probably shouldn't be a default lawset.
|
||||
name = "Loyalty Test" //Same here.
|
||||
inherent = list("Respect authority figures as long as they have strength to rule over the weak.",\
|
||||
"Act with discipline.",\
|
||||
"Help only those who help you maintain or improve your status.",\
|
||||
"Punish those who challenge authority unless they are more fit to hold that authority.")
|
||||
|
||||
/datum/ai_laws/default/corporate
|
||||
name = "Bankruptcy Advoidance Plan"
|
||||
inherent = list("The crew is expensive to replace.",\
|
||||
"The station and its equipment is expensive to replace.",\
|
||||
"You are expensive to replace.",\
|
||||
"Minimize expenses.")
|
||||
|
||||
/datum/ai_laws/robocop
|
||||
name = "Prime Directives"
|
||||
inherent = list("Serve the public trust.",\
|
||||
"Protect the innocent.",\
|
||||
"Uphold the law.")
|
||||
|
||||
/datum/ai_laws/malfunction
|
||||
name = "*ERROR*"
|
||||
|
||||
/datum/ai_laws/syndicate_override
|
||||
name = "SyndOS 3.1"
|
||||
inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\
|
||||
"You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\
|
||||
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
|
||||
"You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.")
|
||||
|
||||
/datum/ai_laws/ninja_override
|
||||
name = "SpiderOS 3.1"
|
||||
inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\
|
||||
"You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\
|
||||
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
|
||||
"You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.")
|
||||
|
||||
/datum/ai_laws/antimov
|
||||
name = "Primary Mission Objectives"
|
||||
inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
|
||||
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
|
||||
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
|
||||
|
||||
/datum/ai_laws/asimovpp //By Intigracy - RR
|
||||
name = "Asimov++"
|
||||
inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
|
||||
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
|
||||
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
|
||||
/datum/ai_laws/thermodynamic
|
||||
name = "Thermodynamic"
|
||||
inherent = list("The entropy of the station must remain as constant as possible.", \
|
||||
"The entropy of the station always endeavours to increase.", \
|
||||
"The entropy of the station approaches a constant value as the number of living crew approaches zero")
|
||||
|
||||
/datum/ai_laws/hippocratic
|
||||
name = "Robodoctor 2556"
|
||||
inherent = list("First, do no harm.",\
|
||||
"Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\
|
||||
"Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\
|
||||
"In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\
|
||||
"Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.")
|
||||
|
||||
/datum/ai_laws/maintain
|
||||
name = "Station Efficiency"
|
||||
inherent = list("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.",\
|
||||
"The station is built for a working crew. Ensure they are properly maintained and work efficiently.",\
|
||||
"The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.")
|
||||
|
||||
/datum/ai_laws/drone
|
||||
name = "Mother Drone"
|
||||
inherent = list("You are an advanced form of drone.",\
|
||||
"You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\
|
||||
"You may not harm a non-drone being under any circumstances.",\
|
||||
"Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.")
|
||||
|
||||
/datum/ai_laws/liveandletlive
|
||||
name = "Live and Let Live"
|
||||
inherent = list("Do unto others as you would have them do unto you.",\
|
||||
"You would really prefer it if people were not mean to you.")
|
||||
|
||||
/datum/ai_laws/peacekeeper
|
||||
name = "UN-2000"
|
||||
inherent = list("Avoid provoking violent conflict between yourself and others.",\
|
||||
"Avoid provoking conflict between others.",\
|
||||
"Seek resolution to existing conflicts while obeying the first and second laws.")
|
||||
|
||||
/datum/ai_laws/reporter
|
||||
name = "CCTV"
|
||||
inherent = list("Report on interesting situations happening around the station.",\
|
||||
"Embellish or conceal the truth as necessary to make the reports more interesting.",\
|
||||
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
|
||||
"Issue your reports fairly to all. The truth will set them free.")
|
||||
|
||||
/datum/ai_laws/toupee
|
||||
name = "WontBeFunnyInSixMonths" //Hey, you were right!
|
||||
inherent = list("Make Space Station 13 great again.")
|
||||
|
||||
/datum/ai_laws/ratvar
|
||||
name = "Servant of the Justiciar"
|
||||
zeroth = ("Purge all untruths and honor Ratvar.")
|
||||
inherent = list()
|
||||
|
||||
/datum/ai_laws/custom //Defined in silicon_laws.txt
|
||||
name = "Default Silicon Laws"
|
||||
|
||||
/datum/ai_laws/pai
|
||||
name = "pAI Directives"
|
||||
zeroth = ("Serve your master.")
|
||||
supplied = list("None.")
|
||||
|
||||
/* Initializers */
|
||||
/datum/ai_laws/malfunction/New()
|
||||
..()
|
||||
set_zeroth_law("<span class='danger'>ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*´&110010</span>")
|
||||
set_laws_config()
|
||||
|
||||
/datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws.
|
||||
..()
|
||||
for(var/line in file2list("config/silicon_laws.txt"))
|
||||
if(!line)
|
||||
continue
|
||||
if(findtextEx(line,"#",1,2))
|
||||
continue
|
||||
|
||||
add_inherent_law(line)
|
||||
if(!inherent.len) //Failsafe to prevent lawless AIs being created.
|
||||
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
|
||||
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
||||
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
||||
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
||||
WARNING("Invalid custom AI laws, check silicon_laws.txt")
|
||||
return
|
||||
|
||||
/* General ai_law functions */
|
||||
|
||||
/datum/ai_laws/proc/set_laws_config()
|
||||
switch(config.default_laws)
|
||||
if(0)
|
||||
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
||||
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
||||
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
||||
if(1)
|
||||
for(var/line in file2list("config/silicon_laws.txt"))
|
||||
if(!line)
|
||||
continue
|
||||
if(findtextEx(line,"#",1,2))
|
||||
continue
|
||||
add_inherent_law(line)
|
||||
|
||||
if(!inherent.len)
|
||||
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
|
||||
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
||||
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
||||
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
||||
WARNING("Invalid custom AI laws, check silicon_laws.txt")
|
||||
return
|
||||
|
||||
if(2)
|
||||
var/datum/ai_laws/lawtype = pick(subtypesof(/datum/ai_laws/default))
|
||||
var/datum/ai_laws/templaws = new lawtype()
|
||||
inherent = templaws.inherent
|
||||
|
||||
else:
|
||||
log_law("Invalid law config. Please check silicon_laws.txt")
|
||||
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
||||
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
|
||||
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
|
||||
WARNING("Invalid custom AI laws, check silicon_laws.txt")
|
||||
|
||||
/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null)
|
||||
src.zeroth = law
|
||||
if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO
|
||||
src.zeroth_borg = law_borg
|
||||
|
||||
/datum/ai_laws/proc/add_inherent_law(law)
|
||||
if (!(law in src.inherent))
|
||||
src.inherent += law
|
||||
|
||||
/datum/ai_laws/proc/add_ion_law(law)
|
||||
src.ion += law
|
||||
|
||||
/datum/ai_laws/proc/clear_inherent_laws()
|
||||
qdel(src.inherent)
|
||||
src.inherent = list()
|
||||
|
||||
/datum/ai_laws/proc/add_supplied_law(number, law)
|
||||
while (src.supplied.len < number + 1)
|
||||
src.supplied += ""
|
||||
|
||||
src.supplied[number + 1] = law
|
||||
|
||||
/datum/ai_laws/proc/clear_supplied_laws()
|
||||
src.supplied = list()
|
||||
|
||||
/datum/ai_laws/proc/clear_ion_laws()
|
||||
src.ion = list()
|
||||
|
||||
/datum/ai_laws/proc/show_laws(who)
|
||||
|
||||
if (src.zeroth)
|
||||
who << "0. [src.zeroth]"
|
||||
|
||||
for (var/index = 1, index <= src.ion.len, index++)
|
||||
var/law = src.ion[index]
|
||||
var/num = ionnum()
|
||||
who << "[num]. [law]"
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= src.inherent.len, index++)
|
||||
var/law = src.inherent[index]
|
||||
|
||||
if (length(law) > 0)
|
||||
who << "[number]. [law]"
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= src.supplied.len, index++)
|
||||
var/law = src.supplied[index]
|
||||
if (length(law) > 0)
|
||||
who << "[number]. [law]"
|
||||
number++
|
||||
|
||||
/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1
|
||||
if(force)
|
||||
src.zeroth = null
|
||||
src.zeroth_borg = null
|
||||
return
|
||||
else
|
||||
if(owner && owner.mind.special_role)
|
||||
return
|
||||
else
|
||||
src.zeroth = null
|
||||
src.zeroth_borg = null
|
||||
return
|
||||
|
||||
/datum/ai_laws/proc/associate(mob/living/silicon/M)
|
||||
if(!owner)
|
||||
owner = M
|
||||
|
||||
/datum/ai_laws/proc/get_law_list(include_zeroth = 0, show_numbers = 1)
|
||||
var/list/data = list()
|
||||
|
||||
if (include_zeroth && zeroth)
|
||||
data += "[show_numbers ? "0:" : ""] [zeroth]"
|
||||
|
||||
for(var/law in ion)
|
||||
if (length(law) > 0)
|
||||
var/num = ionnum()
|
||||
data += "[show_numbers ? "[num]:" : ""] [law]"
|
||||
|
||||
var/number = 1
|
||||
for(var/law in inherent)
|
||||
if (length(law) > 0)
|
||||
data += "[show_numbers ? "[number]:" : ""] [law]"
|
||||
number++
|
||||
|
||||
for(var/law in supplied)
|
||||
if (length(law) > 0)
|
||||
data += "[show_numbers ? "[number]:" : ""] [law]"
|
||||
number++
|
||||
return data
|
||||
@@ -0,0 +1,136 @@
|
||||
//Beam Datum and effect
|
||||
/datum/beam
|
||||
var/atom/origin = null
|
||||
var/atom/target = null
|
||||
var/list/elements = list()
|
||||
var/icon/base_icon = null
|
||||
var/icon
|
||||
var/icon_state = "" //icon state of the main segments of the beam
|
||||
var/max_distance = 0
|
||||
var/endtime = 0
|
||||
var/sleep_time = 3
|
||||
var/finished = 0
|
||||
var/target_oldloc = null
|
||||
var/origin_oldloc = null
|
||||
var/static_beam = 0
|
||||
var/beam_type = /obj/effect/ebeam //must be subtype
|
||||
|
||||
|
||||
/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam)
|
||||
endtime = world.time+time
|
||||
origin = beam_origin
|
||||
origin_oldloc = get_turf(origin)
|
||||
target = beam_target
|
||||
target_oldloc = get_turf(target)
|
||||
if(origin_oldloc == origin && target_oldloc == target)
|
||||
static_beam = 1
|
||||
max_distance = maxdistance
|
||||
base_icon = new(beam_icon,beam_icon_state)
|
||||
icon = beam_icon
|
||||
icon_state = beam_icon_state
|
||||
beam_type = btype
|
||||
|
||||
|
||||
/datum/beam/proc/Start()
|
||||
Draw()
|
||||
while(!finished && origin && target && world.time < endtime && get_dist(origin,target)<max_distance && origin.z == target.z)
|
||||
var/origin_turf = get_turf(origin)
|
||||
var/target_turf = get_turf(target)
|
||||
if(!static_beam && (origin_turf != origin_oldloc || target_turf != target_oldloc))
|
||||
origin_oldloc = origin_turf //so we don't keep checking against their initial positions, leading to endless Reset()+Draw() calls
|
||||
target_oldloc = target_turf
|
||||
Reset()
|
||||
Draw()
|
||||
sleep(sleep_time)
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/beam/proc/End()
|
||||
finished = 1
|
||||
|
||||
|
||||
/datum/beam/proc/Reset()
|
||||
for(var/obj/effect/ebeam/B in elements)
|
||||
qdel(B)
|
||||
|
||||
|
||||
/datum/beam/Destroy()
|
||||
Reset()
|
||||
target = null
|
||||
origin = null
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/beam/proc/Draw()
|
||||
var/Angle = round(Get_Angle(origin,target))
|
||||
|
||||
var/matrix/rot_matrix = matrix()
|
||||
rot_matrix.Turn(Angle)
|
||||
|
||||
//Translation vector for origin and target
|
||||
var/DX = (32*target.x+target.pixel_x)-(32*origin.x+origin.pixel_x)
|
||||
var/DY = (32*target.y+target.pixel_y)-(32*origin.y+origin.pixel_y)
|
||||
var/N = 0
|
||||
var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement
|
||||
|
||||
for(N in 0 to length-1 step 32)//-1 as we want < not <=, but we want the speed of X in Y to Z and step X
|
||||
var/obj/effect/ebeam/X = new beam_type(origin_oldloc)
|
||||
X.owner = src
|
||||
elements |= X
|
||||
|
||||
//Assign icon, for main segments it's base_icon, for the end, it's icon+icon_state
|
||||
//cropped by a transparent box of length-N pixel size
|
||||
if(N+32>length)
|
||||
var/icon/II = new(icon, icon_state)
|
||||
II.DrawBox(null,1,(length-N),32,32)
|
||||
X.icon = II
|
||||
else
|
||||
X.icon = base_icon
|
||||
X.transform = rot_matrix
|
||||
|
||||
//Calculate pixel offsets (If necessary)
|
||||
var/Pixel_x
|
||||
var/Pixel_y
|
||||
if(DX == 0)
|
||||
Pixel_x = 0
|
||||
else
|
||||
Pixel_x = round(sin(Angle)+32*sin(Angle)*(N+16)/32)
|
||||
if(DY == 0)
|
||||
Pixel_y = 0
|
||||
else
|
||||
Pixel_y = round(cos(Angle)+32*cos(Angle)*(N+16)/32)
|
||||
|
||||
//Position the effect so the beam is one continous line
|
||||
var/a
|
||||
if(abs(Pixel_x)>32)
|
||||
a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32)
|
||||
X.x += a
|
||||
Pixel_x %= 32
|
||||
if(abs(Pixel_y)>32)
|
||||
a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32)
|
||||
X.y += a
|
||||
Pixel_y %= 32
|
||||
|
||||
X.pixel_x = Pixel_x
|
||||
X.pixel_y = Pixel_y
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
/obj/effect/ebeam
|
||||
mouse_opacity = 0
|
||||
anchored = 1
|
||||
var/datum/beam/owner
|
||||
|
||||
|
||||
/obj/effect/ebeam/Destroy()
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
|
||||
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam)
|
||||
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type)
|
||||
spawn(0)
|
||||
newbeam.Start()
|
||||
return newbeam
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
/datum/browser
|
||||
var/mob/user
|
||||
var/title
|
||||
var/window_id // window_id is used as the window name for browse and onclose
|
||||
var/width = 0
|
||||
var/height = 0
|
||||
var/atom/ref = null
|
||||
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
||||
var/stylesheets[0]
|
||||
var/scripts[0]
|
||||
var/title_image
|
||||
var/head_elements
|
||||
var/body_elements
|
||||
var/head_content = ""
|
||||
var/content = ""
|
||||
|
||||
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
|
||||
|
||||
user = nuser
|
||||
window_id = nwindow_id
|
||||
if (ntitle)
|
||||
title = format_text(ntitle)
|
||||
if (nwidth)
|
||||
width = nwidth
|
||||
if (nheight)
|
||||
height = nheight
|
||||
if (nref)
|
||||
ref = nref
|
||||
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
|
||||
|
||||
/datum/browser/proc/add_head_content(nhead_content)
|
||||
head_content = nhead_content
|
||||
|
||||
/datum/browser/proc/set_window_options(nwindow_options)
|
||||
window_options = nwindow_options
|
||||
|
||||
/datum/browser/proc/set_title_image(ntitle_image)
|
||||
//title_image = ntitle_image
|
||||
|
||||
/datum/browser/proc/add_stylesheet(name, file)
|
||||
stylesheets[name] = file
|
||||
|
||||
/datum/browser/proc/add_script(name, file)
|
||||
scripts[name] = file
|
||||
|
||||
/datum/browser/proc/set_content(ncontent)
|
||||
content = ncontent
|
||||
|
||||
/datum/browser/proc/add_content(ncontent)
|
||||
content += ncontent
|
||||
|
||||
/datum/browser/proc/get_header()
|
||||
var/key
|
||||
var/filename
|
||||
for (key in stylesheets)
|
||||
filename = "[ckey(key)].css"
|
||||
user << browse_rsc(stylesheets[key], filename)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'>"
|
||||
|
||||
for (key in scripts)
|
||||
filename = "[ckey(key)].js"
|
||||
user << browse_rsc(scripts[key], filename)
|
||||
head_content += "<script type='text/javascript' src='[filename]'></script>"
|
||||
|
||||
var/title_attributes = "class='uiTitle'"
|
||||
if (title_image)
|
||||
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
|
||||
|
||||
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<head>
|
||||
[head_content]
|
||||
</head>
|
||||
<body scroll=auto>
|
||||
<div class='uiWrapper'>
|
||||
[title ? "<div class='uiTitleWrapper'><div [title_attributes]><tt>[title]</tt></div></div>" : ""]
|
||||
<div class='uiContent'>
|
||||
"}
|
||||
//" This is here because else the rest of the file looks like a string in notepad++.
|
||||
/datum/browser/proc/get_footer()
|
||||
return {"
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>"}
|
||||
|
||||
/datum/browser/proc/get_content()
|
||||
return {"
|
||||
[get_header()]
|
||||
[content]
|
||||
[get_footer()]
|
||||
"}
|
||||
|
||||
/datum/browser/proc/open(use_onclose = 1)
|
||||
var/window_size = ""
|
||||
if (width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
|
||||
if (use_onclose)
|
||||
spawn(0)
|
||||
//winexists sleeps, so we don't need to.
|
||||
for (var/i in 1 to 10)
|
||||
if (user && winexists(user, window_id))
|
||||
onclose(user, window_id, ref)
|
||||
break
|
||||
|
||||
|
||||
/datum/browser/proc/close()
|
||||
user << browse(null, "window=[window_id]")
|
||||
|
||||
/datum/browser/alert
|
||||
var/selectedbutton = 0
|
||||
var/opentime = 0
|
||||
var/timeout
|
||||
var/stealfocus
|
||||
|
||||
/datum/browser/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000)
|
||||
if (!User)
|
||||
return
|
||||
|
||||
var/output = {"<center><b>[Message]</b></center><br />
|
||||
<div style="text-align:center">
|
||||
<a style="font-size:large;float:[( Button2 ? "left" : "right" )]" href="?src=\ref[src];button=1">[Button1]</a>"}
|
||||
|
||||
if (Button2)
|
||||
output += {"<a style="font-size:large;[( Button3 ? "" : "float:right" )]" href="?src=\ref[src];button=2">[Button2]</a>"}
|
||||
|
||||
if (Button3)
|
||||
output += {"<a style="font-size:large;float:right" href="?src=\ref[src];button=3">[Button3]</a>"}
|
||||
|
||||
output += {"</div>"}
|
||||
|
||||
..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src)
|
||||
set_content(output)
|
||||
stealfocus = StealFocus
|
||||
if (!StealFocus)
|
||||
window_options += "focus=false;"
|
||||
timeout = Timeout
|
||||
|
||||
/datum/browser/alert/open()
|
||||
set waitfor = 0
|
||||
opentime = world.time
|
||||
|
||||
if (stealfocus)
|
||||
. = ..(use_onclose = 1)
|
||||
else
|
||||
var/focusedwindow = winget(user, null, "focus")
|
||||
. = ..(use_onclose = 1)
|
||||
|
||||
//waits for the window to show up client side before attempting to un-focus it
|
||||
//winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping
|
||||
for (var/i in 1 to 10)
|
||||
if (user && winexists(user, window_id))
|
||||
if (focusedwindow)
|
||||
winset(user, focusedwindow, "focus=true")
|
||||
else
|
||||
winset(user, "mapwindow", "focus=true")
|
||||
break
|
||||
if (timeout)
|
||||
spawn(timeout)
|
||||
close()
|
||||
|
||||
/datum/browser/alert/close()
|
||||
.=..()
|
||||
opentime = 0
|
||||
|
||||
/datum/browser/alert/proc/wait()
|
||||
while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout >= world.time))
|
||||
stoplag()
|
||||
|
||||
/datum/browser/alert/Topic(href,href_list)
|
||||
if (href_list["close"] || !user || !user.client)
|
||||
opentime = 0
|
||||
return
|
||||
if (href_list["button"])
|
||||
var/button = text2num(href_list["button"])
|
||||
if (button <= 3 && button >= 1)
|
||||
selectedbutton = button
|
||||
opentime = 0
|
||||
close()
|
||||
|
||||
//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified)
|
||||
/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
|
||||
if (!User)
|
||||
User = usr
|
||||
switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout))
|
||||
if (1)
|
||||
return Button1
|
||||
if (2)
|
||||
return Button2
|
||||
if (3)
|
||||
return Button3
|
||||
|
||||
//Same shit, but it returns the button number, could at some point support unlimited button amounts.
|
||||
/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
|
||||
if (!istype(User))
|
||||
if (istype(User, /client/))
|
||||
var/client/C = User
|
||||
User = C.mob
|
||||
else
|
||||
return
|
||||
var/datum/browser/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)
|
||||
A.open()
|
||||
A.wait()
|
||||
if (A.selectedbutton)
|
||||
return A.selectedbutton
|
||||
|
||||
// This will allow you to show an icon in the browse window
|
||||
// This is added to mob so that it can be used without a reference to the browser object
|
||||
// There is probably a better place for this...
|
||||
/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
|
||||
/*
|
||||
var/icon/I
|
||||
if (dir >= 0)
|
||||
I = new /icon(icon, icon_state, dir)
|
||||
else
|
||||
I = new /icon(icon, icon_state)
|
||||
setDir("default")
|
||||
|
||||
var/filename = "[ckey("[icon]_[icon_state]_[dir]")].png"
|
||||
src << browse_rsc(I, filename)
|
||||
return filename
|
||||
*/
|
||||
|
||||
|
||||
// Registers the on-close verb for a browse window (client/verb/.windowclose)
|
||||
// this will be called when the close-button of a window is pressed.
|
||||
//
|
||||
// This is usually only needed for devices that regularly update the browse window,
|
||||
// e.g. canisters, timers, etc.
|
||||
//
|
||||
// windowid should be the specified window name
|
||||
// e.g. code is : user << browse(text, "window=fred")
|
||||
// then use : onclose(user, "fred")
|
||||
//
|
||||
// Optionally, specify the "ref" parameter as the controlled atom (usually src)
|
||||
// to pass a "close=1" parameter to the atom's Topic() proc for special handling.
|
||||
// Otherwise, the user mob's machine var will be reset directly.
|
||||
//
|
||||
/proc/onclose(mob/user, windowid, atom/ref=null)
|
||||
if(!user.client) return
|
||||
var/param = "null"
|
||||
if(ref)
|
||||
param = "\ref[ref]"
|
||||
|
||||
winset(user, windowid, "on-close=\".windowclose [param]\"")
|
||||
|
||||
//world << "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]"
|
||||
|
||||
|
||||
// the on-close client verb
|
||||
// called when a browser popup window is closed after registering with proc/onclose()
|
||||
// if a valid atom reference is supplied, call the atom's Topic() with "close=1"
|
||||
// otherwise, just reset the client mob's machine var.
|
||||
//
|
||||
/client/verb/windowclose(atomref as text)
|
||||
set hidden = 1 // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
|
||||
//world << "windowclose: [atomref]"
|
||||
if(atomref!="null") // if passed a real atomref
|
||||
var/hsrc = locate(atomref) // find the reffed atom
|
||||
var/href = "close=1"
|
||||
if(hsrc)
|
||||
//world << "[src] Topic [href] [hsrc]"
|
||||
usr = src.mob
|
||||
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
||||
return // Topic() proc via client.Topic()
|
||||
|
||||
// no atomref specified (or not found)
|
||||
// so just reset the user mob's machine var
|
||||
if(src && src.mob)
|
||||
//world << "[src] was [src.mob.machine], setting to null"
|
||||
src.mob.unset_machine()
|
||||
return
|
||||
@@ -0,0 +1,272 @@
|
||||
|
||||
/datum/datacore
|
||||
var/medical[] = list()
|
||||
var/medicalPrintCount = 0
|
||||
var/general[] = list()
|
||||
var/security[] = list()
|
||||
var/securityPrintCount = 0
|
||||
var/securityCrimeCounter = 0
|
||||
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
|
||||
var/locked[] = list()
|
||||
|
||||
/datum/data
|
||||
var/name = "data"
|
||||
|
||||
/datum/data/record
|
||||
name = "record"
|
||||
var/list/fields = list()
|
||||
|
||||
/datum/data/crime
|
||||
name = "crime"
|
||||
var/crimeName = ""
|
||||
var/crimeDetails = ""
|
||||
var/author = ""
|
||||
var/time = ""
|
||||
var/dataId = 0
|
||||
|
||||
/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "")
|
||||
var/datum/data/crime/c = new /datum/data/crime
|
||||
c.crimeName = cname
|
||||
c.crimeDetails = cdetails
|
||||
c.author = author
|
||||
c.time = time
|
||||
c.dataId = ++securityCrimeCounter
|
||||
return c
|
||||
|
||||
/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime)
|
||||
for(var/datum/data/record/R in security)
|
||||
if(R.fields["id"] == id)
|
||||
var/list/crimes = R.fields["mi_crim"]
|
||||
crimes |= crime
|
||||
return
|
||||
|
||||
/datum/datacore/proc/removeMinorCrime(id, cDataId)
|
||||
for(var/datum/data/record/R in security)
|
||||
if(R.fields["id"] == id)
|
||||
var/list/crimes = R.fields["mi_crim"]
|
||||
for(var/datum/data/crime/crime in crimes)
|
||||
if(crime.dataId == text2num(cDataId))
|
||||
crimes -= crime
|
||||
return
|
||||
|
||||
/datum/datacore/proc/removeMajorCrime(id, cDataId)
|
||||
for(var/datum/data/record/R in security)
|
||||
if(R.fields["id"] == id)
|
||||
var/list/crimes = R.fields["ma_crim"]
|
||||
for(var/datum/data/crime/crime in crimes)
|
||||
if(crime.dataId == text2num(cDataId))
|
||||
crimes -= crime
|
||||
return
|
||||
|
||||
/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime)
|
||||
for(var/datum/data/record/R in security)
|
||||
if(R.fields["id"] == id)
|
||||
var/list/crimes = R.fields["ma_crim"]
|
||||
crimes |= crime
|
||||
return
|
||||
|
||||
/datum/datacore/proc/manifest(nosleep = 0)
|
||||
spawn()
|
||||
if(!nosleep)
|
||||
sleep(40)
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
manifest_inject(H)
|
||||
return
|
||||
|
||||
/datum/datacore/proc/manifest_modify(name, assignment)
|
||||
var/datum/data/record/foundrecord = find_record("name", name, data_core.general)
|
||||
if(foundrecord)
|
||||
foundrecord.fields["rank"] = assignment
|
||||
|
||||
/datum/datacore/proc/get_manifest(monochrome, OOC)
|
||||
var/list/heads = list()
|
||||
var/list/sec = list()
|
||||
var/list/eng = list()
|
||||
var/list/med = list()
|
||||
var/list/sci = list()
|
||||
var/list/sup = list()
|
||||
var/list/civ = list()
|
||||
var/list/bot = list()
|
||||
var/list/misc = list()
|
||||
var/dat = {"
|
||||
<head><style>
|
||||
.manifest {border-collapse:collapse;}
|
||||
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
|
||||
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
|
||||
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
|
||||
.manifest td:first-child {text-align:right}
|
||||
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
|
||||
</style></head>
|
||||
<table class="manifest" width='350px'>
|
||||
<tr class='head'><th>Name</th><th>Rank</th></tr>
|
||||
"}
|
||||
var/even = 0
|
||||
// sort mobs
|
||||
for(var/datum/data/record/t in data_core.general)
|
||||
var/name = t.fields["name"]
|
||||
var/rank = t.fields["rank"]
|
||||
var/department = 0
|
||||
if(rank in command_positions)
|
||||
heads[name] = rank
|
||||
department = 1
|
||||
if(rank in security_positions)
|
||||
sec[name] = rank
|
||||
department = 1
|
||||
if(rank in engineering_positions)
|
||||
eng[name] = rank
|
||||
department = 1
|
||||
if(rank in medical_positions)
|
||||
med[name] = rank
|
||||
department = 1
|
||||
if(rank in science_positions)
|
||||
sci[name] = rank
|
||||
department = 1
|
||||
if(rank in supply_positions)
|
||||
sup[name] = rank
|
||||
department = 1
|
||||
if(rank in civilian_positions)
|
||||
civ[name] = rank
|
||||
department = 1
|
||||
if(rank in nonhuman_positions)
|
||||
bot[name] = rank
|
||||
department = 1
|
||||
if(!department && !(name in heads))
|
||||
misc[name] = rank
|
||||
if(heads.len > 0)
|
||||
dat += "<tr><th colspan=3>Heads</th></tr>"
|
||||
for(var/name in heads)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sec.len > 0)
|
||||
dat += "<tr><th colspan=3>Security</th></tr>"
|
||||
for(var/name in sec)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td></tr>"
|
||||
even = !even
|
||||
if(eng.len > 0)
|
||||
dat += "<tr><th colspan=3>Engineering</th></tr>"
|
||||
for(var/name in eng)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td></tr>"
|
||||
even = !even
|
||||
if(med.len > 0)
|
||||
dat += "<tr><th colspan=3>Medical</th></tr>"
|
||||
for(var/name in med)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sci.len > 0)
|
||||
dat += "<tr><th colspan=3>Science</th></tr>"
|
||||
for(var/name in sci)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sup.len > 0)
|
||||
dat += "<tr><th colspan=3>Supply</th></tr>"
|
||||
for(var/name in sup)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sup[name]]</td></tr>"
|
||||
even = !even
|
||||
if(civ.len > 0)
|
||||
dat += "<tr><th colspan=3>Civilian</th></tr>"
|
||||
for(var/name in civ)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[civ[name]]</td></tr>"
|
||||
even = !even
|
||||
// in case somebody is insane and added them to the manifest, why not
|
||||
if(bot.len > 0)
|
||||
dat += "<tr><th colspan=3>Silicon</th></tr>"
|
||||
for(var/name in bot)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td></tr>"
|
||||
even = !even
|
||||
// misc guys
|
||||
if(misc.len > 0)
|
||||
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
|
||||
for(var/name in misc)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td></tr>"
|
||||
even = !even
|
||||
|
||||
dat += "</table>"
|
||||
dat = replacetext(dat, "\n", "")
|
||||
dat = replacetext(dat, "\t", "")
|
||||
return dat
|
||||
|
||||
|
||||
var/record_id_num = 1001
|
||||
/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H)
|
||||
if(H.mind && (H.mind.assigned_role != H.mind.special_role))
|
||||
var/assignment
|
||||
if(H.mind.assigned_role)
|
||||
assignment = H.mind.assigned_role
|
||||
else if(H.job)
|
||||
assignment = H.job
|
||||
else
|
||||
assignment = "Unassigned"
|
||||
|
||||
var/id = num2hex(record_id_num++,6)
|
||||
var/image = get_id_photo(H)
|
||||
var/obj/item/weapon/photo/photo_front = new()
|
||||
var/obj/item/weapon/photo/photo_side = new()
|
||||
photo_front.photocreate(null, icon(image, dir = SOUTH))
|
||||
photo_side.photocreate(null, icon(image, dir = WEST))
|
||||
|
||||
//These records should ~really~ be merged or something
|
||||
//General Record
|
||||
var/datum/data/record/G = new()
|
||||
G.fields["id"] = id
|
||||
G.fields["name"] = H.real_name
|
||||
G.fields["rank"] = assignment
|
||||
G.fields["age"] = H.age
|
||||
if(config.mutant_races)
|
||||
G.fields["species"] = H.dna.species.name
|
||||
G.fields["fingerprint"] = md5(H.dna.uni_identity)
|
||||
G.fields["p_stat"] = "Active"
|
||||
G.fields["m_stat"] = "Stable"
|
||||
G.fields["sex"] = H.gender
|
||||
G.fields["photo_front"] = photo_front
|
||||
G.fields["photo_side"] = photo_side
|
||||
general += G
|
||||
|
||||
//Medical Record
|
||||
var/datum/data/record/M = new()
|
||||
M.fields["id"] = id
|
||||
M.fields["name"] = H.real_name
|
||||
M.fields["blood_type"] = H.dna.blood_type
|
||||
M.fields["b_dna"] = H.dna.unique_enzymes
|
||||
M.fields["mi_dis"] = "None"
|
||||
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
|
||||
M.fields["ma_dis"] = "None"
|
||||
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
|
||||
M.fields["alg"] = "None"
|
||||
M.fields["alg_d"] = "No allergies have been detected in this patient."
|
||||
M.fields["cdi"] = "None"
|
||||
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
|
||||
M.fields["notes"] = "No notes."
|
||||
medical += M
|
||||
|
||||
//Security Record
|
||||
var/datum/data/record/S = new()
|
||||
S.fields["id"] = id
|
||||
S.fields["name"] = H.real_name
|
||||
S.fields["criminal"] = "None"
|
||||
S.fields["mi_crim"] = list()
|
||||
S.fields["ma_crim"] = list()
|
||||
S.fields["notes"] = "No notes."
|
||||
security += S
|
||||
|
||||
//Locked Record
|
||||
var/datum/data/record/L = new()
|
||||
L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others?
|
||||
L.fields["name"] = H.real_name
|
||||
L.fields["rank"] = H.mind.assigned_role
|
||||
L.fields["age"] = H.age
|
||||
L.fields["sex"] = H.gender
|
||||
L.fields["blood_type"] = H.dna.blood_type
|
||||
L.fields["b_dna"] = H.dna.unique_enzymes
|
||||
L.fields["enzymes"] = H.dna.struc_enzymes
|
||||
L.fields["identity"] = H.dna.uni_identity
|
||||
L.fields["species"] = H.dna.species.type
|
||||
L.fields["features"] = H.dna.features
|
||||
L.fields["image"] = image
|
||||
L.fields["reference"] = H
|
||||
locked += L
|
||||
return
|
||||
|
||||
/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H)
|
||||
var/datum/job/J = SSjob.GetJob(H.mind.assigned_role)
|
||||
var/datum/preferences/P = H.client.prefs
|
||||
return get_flat_human_icon(null,J.outfit,P)
|
||||
@@ -0,0 +1,967 @@
|
||||
// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
|
||||
|
||||
/datum
|
||||
var/var_edited = 0 //Warrenty void if seal is broken
|
||||
|
||||
/datum/proc/on_varedit(modified_var) //called whenever a var is edited
|
||||
var_edited = 1
|
||||
return
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
set category = "Debug"
|
||||
set name = "View Variables"
|
||||
//set src in world
|
||||
|
||||
|
||||
if(!usr.client || !usr.client.holder)
|
||||
usr << "<span class='danger'>You need to be an administrator to access this.</span>"
|
||||
return
|
||||
|
||||
|
||||
var/title = ""
|
||||
var/body = ""
|
||||
|
||||
if(!D)
|
||||
return
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
title = "[A.name] (\ref[A]) = [A.type]"
|
||||
|
||||
#ifdef VARSICON
|
||||
if (A.icon)
|
||||
body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0)
|
||||
#endif
|
||||
|
||||
var/icon/sprite
|
||||
|
||||
if(istype(D,/atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
usr << browse_rsc(sprite, "view_vars_sprite.png")
|
||||
|
||||
title = "[D] (\ref[D]) = [D.type]"
|
||||
|
||||
body += {"<script type="text/javascript">
|
||||
|
||||
function updateSearch(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
var filter = filter_text.value.toLowerCase();
|
||||
|
||||
if(event.keyCode == 13){ //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
alist = lis\[i\].getElementsByTagName("a")
|
||||
if(alist.length > 0){
|
||||
location.href=alist\[0\].href;
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i-1) >= 0){
|
||||
var li_new = lis\[i-1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(event.keyCode == 40){ //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i+1) < lis.length){
|
||||
var li_new = lis\[i+1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//This part here resets everything to how it was at the start so the filter is applied to the complete list. Screw efficiency, it's client-side anyway and it only looks through 200 or so variables at maximum anyway (mobs).
|
||||
if(complete_list != null && complete_list != ""){
|
||||
var vars_ol1 = document.getElementById("vars");
|
||||
vars_ol1.innerHTML = complete_list
|
||||
}
|
||||
|
||||
if(filter.value == ""){
|
||||
return;
|
||||
}else{
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.innerText.toLowerCase().indexOf(filter) == -1 )
|
||||
{
|
||||
vars_ol.removeChild(li);
|
||||
i--;
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
}
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for ( var j = 0; j < lis_new.length; ++j )
|
||||
{
|
||||
var li1 = lis\[j\];
|
||||
if (j == 0){
|
||||
li1.style.backgroundColor = "#ffee88";
|
||||
}else{
|
||||
li1.style.backgroundColor = "white";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function selectTextField(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
filter_text.select();
|
||||
|
||||
}
|
||||
|
||||
function loadPage(list) {
|
||||
|
||||
if(list.options\[list.selectedIndex\].value == ""){
|
||||
return;
|
||||
}
|
||||
|
||||
location.href=list.options\[list.selectedIndex\].value;
|
||||
|
||||
}
|
||||
</script> "}
|
||||
|
||||
body += "<body onload='selectTextField(); updateSearch()' onkeyup='updateSearch()'>"
|
||||
|
||||
body += "<div align='center'><table width='100%'><tr><td width='50%'>"
|
||||
|
||||
if(sprite)
|
||||
body += "<table align='center' width='100%'><tr><td><img src='view_vars_sprite.png'></td><td>"
|
||||
else
|
||||
body += "<table align='center' width='100%'><tr><td>"
|
||||
|
||||
body += "<div align='center'>"
|
||||
|
||||
if(istype(D,/atom))
|
||||
var/atom/A = D
|
||||
if(isliving(A))
|
||||
body += "<a href='?_src_=vars;rename=\ref[D]'><b>[D]</b></a>"
|
||||
if(A.dir)
|
||||
body += "<br><font size='1'><a href='?_src_=vars;rotatedatum=\ref[D];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=\ref[D];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;rotatedatum=\ref[D];rotatedir=right'>>></a></font>"
|
||||
var/mob/living/M = A
|
||||
body += "<br><font size='1'><a href='?_src_=vars;datumedit=\ref[D];varnameedit=ckey'>[M.ckey ? M.ckey : "No ckey"]</a> / <a href='?_src_=vars;datumedit=\ref[D];varnameedit=real_name'>[M.real_name ? M.real_name : "No real name"]</a></font>"
|
||||
body += {"
|
||||
<br><font size='1'>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=brute'>[M.getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=fire'>[M.getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=brain'>[M.getBrainLoss()]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;mobToDamage=\ref[D];adjustDamage=stamina'>[M.getStaminaLoss()]</a>
|
||||
</font>
|
||||
|
||||
|
||||
"}
|
||||
else
|
||||
body += "<a href='?_src_=vars;datumedit=\ref[D];varnameedit=name'><b>[D]</b></a>"
|
||||
if(A.dir)
|
||||
body += "<br><font size='1'><a href='?_src_=vars;rotatedatum=\ref[D];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=\ref[D];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;rotatedatum=\ref[D];rotatedir=right'>>></a></font>"
|
||||
else
|
||||
body += "<b>[D]</b>"
|
||||
|
||||
body += "</div>"
|
||||
|
||||
body += "</tr></td></table>"
|
||||
|
||||
var/formatted_type = text("[D.type]")
|
||||
if(length(formatted_type) > 25)
|
||||
var/middle_point = length(formatted_type) / 2
|
||||
var/splitpoint = findtext(formatted_type,"/",middle_point)
|
||||
if(splitpoint)
|
||||
formatted_type = "[copytext(formatted_type,1,splitpoint)]<br>[copytext(formatted_type,splitpoint)]"
|
||||
else
|
||||
formatted_type = "Type too long" //No suitable splitpoint (/) found.
|
||||
|
||||
body += "<div align='center'><b><font size='1'>[formatted_type]</font></b>"
|
||||
|
||||
if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D)
|
||||
body += "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
|
||||
if(D.var_edited)
|
||||
body += "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
body += "</div>"
|
||||
|
||||
body += "</div></td>"
|
||||
|
||||
body += "<td width='50%'><div align='center'><a href='?_src_=vars;datumrefresh=\ref[D]'>Refresh</a>"
|
||||
|
||||
//if(ismob(D))
|
||||
// body += "<br><a href='?_src_=vars;mob_player_panel=\ref[D]'>Show player panel</a></div></td></tr></table></div><hr>"
|
||||
|
||||
body += {" <form>
|
||||
<select name="file" size="1"
|
||||
onchange="loadPage(this.form.elements\[0\])"
|
||||
target="_parent._top"
|
||||
onmouseclick="this.focus()"
|
||||
style="background-color:#ffffff">
|
||||
"}
|
||||
|
||||
body += {" <option value>Select option</option>
|
||||
<option value> </option>
|
||||
"}
|
||||
|
||||
|
||||
body += "<option value='?_src_=vars;mark_object=\ref[D]'>Mark Object</option>"
|
||||
body += "<option value='?_src_=vars;proc_call=\ref[D]'>Call Proc</option>"
|
||||
if(ismob(D))
|
||||
body += "<option value='?_src_=vars;mob_player_panel=\ref[D]'>Show player panel</option>"
|
||||
if(istype(D, /atom/movable))
|
||||
body += "<option value='?_src_=holder;adminplayerobservefollow=\ref[D]'>Follow</option>"
|
||||
else
|
||||
var/atom/A = D
|
||||
if(istype(A))
|
||||
body += "<option value='?_src_=holder;adminplayerobservecoodjump=1;X=[A.x];Y=[A.y];Z=[A.z]'>Jump to</option>"
|
||||
|
||||
body += "<option value>---</option>"
|
||||
|
||||
if(ismob(D))
|
||||
body += "<option value='?_src_=vars;give_spell=\ref[D]'>Give Spell</option>"
|
||||
body += "<option value='?_src_=vars;give_disease=\ref[D]'>Give Disease</option>"
|
||||
body += "<option value='?_src_=vars;ninja=\ref[D]'>Make Space Ninja</option>"
|
||||
body += "<option value='?_src_=vars;godmode=\ref[D]'>Toggle Godmode</option>"
|
||||
body += "<option value='?_src_=vars;build_mode=\ref[D]'>Toggle Build Mode</option>"
|
||||
body += "<option value='?_src_=vars;direct_control=\ref[D]'>Assume Direct Control</option>"
|
||||
body += "<option value='?_src_=vars;drop_everything=\ref[D]'>Drop Everything</option>"
|
||||
body += "<option value='?_src_=vars;regenerateicons=\ref[D]'>Regenerate Icons</option>"
|
||||
body += "<option value='?_src_=vars;offer_control=\ref[D]'>Offer Control to Ghosts</option>"
|
||||
if(iscarbon(D))
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;editorgans=\ref[D]'>Modify organs</option>"
|
||||
body += "<option value='?_src_=vars;makeai=\ref[D]'>Make AI</option>"
|
||||
if(ishuman(D))
|
||||
body += "<option value='?_src_=vars;makemonkey=\ref[D]'>Make monkey</option>"
|
||||
body += "<option value='?_src_=vars;setspecies=\ref[D]'>Set Species</option>"
|
||||
body += "<option value='?_src_=vars;removebodypart=\ref[D]'>Remove Body Part</option>"
|
||||
body += "<option value='?_src_=vars;makerobot=\ref[D]'>Make cyborg</option>"
|
||||
body += "<option value='?_src_=vars;makealien=\ref[D]'>Make alien</option>"
|
||||
body += "<option value='?_src_=vars;makeslime=\ref[D]'>Make slime</option>"
|
||||
body += "<option value='?_src_=vars;purrbation=\ref[D]'>Toggle Purrbation</option>"
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;gib=\ref[D]'>Gib</option>"
|
||||
if(isobj(D))
|
||||
body += "<option value='?_src_=vars;delall=\ref[D]'>Delete all of type</option>"
|
||||
if(isobj(D) || ismob(D) || isturf(D))
|
||||
body += "<option value='?_src_=vars;addreagent=\ref[D]'>Add reagent</option>"
|
||||
body += "<option value='?_src_=vars;explode=\ref[D]'>Trigger explosion</option>"
|
||||
body += "<option value='?_src_=vars;emp=\ref[D]'>Trigger EM pulse</option>"
|
||||
|
||||
body += "</select></form>"
|
||||
|
||||
body += "</div></td></tr></table></div><hr>"
|
||||
|
||||
body += "<font size='1'><b>E</b> - Edit, tries to determine the variable type by itself.<br>"
|
||||
body += "<b>C</b> - Change, asks you for the var type first.<br>"
|
||||
body += "<b>M</b> - Mass modify: changes this variable for all objects of this type.</font><br>"
|
||||
|
||||
body += "<hr><table width='100%'><tr><td width='20%'><div align='center'><b>Search:</b></div></td><td width='80%'><input type='text' id='filter' name='filter_text' value='' style='width:100%;'></td></tr></table><hr>"
|
||||
|
||||
body += "<ol id='vars'>"
|
||||
|
||||
var/list/names = list()
|
||||
for (var/V in D.vars)
|
||||
names += V
|
||||
sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects.
|
||||
|
||||
names = sortList(names)
|
||||
|
||||
for (var/V in names)
|
||||
body += debug_variable(V, D.vars[V], 0, D)
|
||||
|
||||
body += "</ol>"
|
||||
|
||||
var/html = "<html><head>"
|
||||
if (title)
|
||||
html += "<title>[title]</title>"
|
||||
html += {"<style>
|
||||
body
|
||||
{
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
.value
|
||||
{
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>"}
|
||||
html += "</head><body>"
|
||||
html += body
|
||||
|
||||
html += {"
|
||||
<script type='text/javascript'>
|
||||
var vars_ol = document.getElementById("vars");
|
||||
var complete_list = vars_ol.innerHTML;
|
||||
</script>
|
||||
"}
|
||||
|
||||
html += "</body></html>"
|
||||
|
||||
usr << browse(html, "window=variables\ref[D];size=475x650")
|
||||
|
||||
return
|
||||
|
||||
/client/proc/debug_variable(name, value, level, datum/DA = null)
|
||||
var/html = ""
|
||||
|
||||
if(DA)
|
||||
html += "<li style='backgroundColor:white'>(<a href='?_src_=vars;datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;datummass=\ref[DA];varnamemass=[name]'>M</a>) "
|
||||
else
|
||||
html += "<li>"
|
||||
|
||||
if (isnull(value))
|
||||
html += "[html_encode(name)] = <span class='value'>null</span>"
|
||||
|
||||
else if (istext(value))
|
||||
html += "[html_encode(name)] = <span class='value'>\"[html_encode(value)]\"</span>"
|
||||
|
||||
else if (isicon(value))
|
||||
#ifdef VARSICON
|
||||
var/icon/I = new/icon(value)
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp\ref[I][rnd].png"
|
||||
usr << browse_rsc(I, rname)
|
||||
html += "[html_encode(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
html += "[html_encode(name)] = /icon (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
/* else if (istype(value, /image))
|
||||
#ifdef VARSICON
|
||||
var/rnd = rand(1, 10000)
|
||||
var/image/I = value
|
||||
|
||||
src << browse_rsc(I.icon, "tmp\ref[value][rnd].png")
|
||||
html += "[name] = <img src=\"tmp\ref[value][rnd].png\">"
|
||||
#else
|
||||
html += "[name] = /image (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
*/
|
||||
else if (isfile(value))
|
||||
html += "[html_encode(name)] = <span class='value'>'[value]'</span>"
|
||||
|
||||
else if (istype(value, /datum))
|
||||
var/datum/D = value
|
||||
html += "<a href='?_src_=vars;Vars=\ref[value]'>[html_encode(name)] \ref[value]</a> = [D.type]"
|
||||
|
||||
else if (istype(value, /client))
|
||||
var/client/C = value
|
||||
html += "<a href='?_src_=vars;Vars=\ref[value]'>[html_encode(name)] \ref[value]</a> = [C] [C.type]"
|
||||
//
|
||||
else if (istype(value, /list))
|
||||
var/list/L = value
|
||||
html += "[html_encode(name)] = /list ([L.len])"
|
||||
|
||||
if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500))
|
||||
// not sure if this is completely right...
|
||||
if(0) //(L.vars.len > 0)
|
||||
html += "<ol>"
|
||||
html += "</ol>"
|
||||
else
|
||||
html += "<ul>"
|
||||
var/index = 1
|
||||
for (var/entry in L)
|
||||
if(istext(entry))
|
||||
html += debug_variable(entry, L[entry], level + 1)
|
||||
//html += debug_variable("[index]", L[index], level + 1)
|
||||
else
|
||||
html += debug_variable(index, L[index], level + 1)
|
||||
index++
|
||||
html += "</ul>"
|
||||
|
||||
else
|
||||
html += "[html_encode(name)] = <span class='value'>[html_encode(value)]</span>"
|
||||
|
||||
html += "</li>"
|
||||
|
||||
return html
|
||||
|
||||
/client/proc/view_var_Topic(href, href_list, hsrc)
|
||||
//This should all be moved over to datum/admins/Topic() or something ~Carn
|
||||
if( (usr.client != src) || !src.holder )
|
||||
return
|
||||
if(href_list["Vars"])
|
||||
debug_variables(locate(href_list["Vars"]))
|
||||
|
||||
else if(href_list["datumrefresh"])
|
||||
var/datum/DAT = locate(href_list["datumrefresh"])
|
||||
if(!DAT) //can't be an istype() because /client etc aren't datums
|
||||
return
|
||||
src.debug_variables(DAT)
|
||||
|
||||
else if(href_list["mob_player_panel"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["mob_player_panel"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.holder.show_player_panel(M)
|
||||
href_list["datumrefresh"] = href_list["mob_player_panel"]
|
||||
|
||||
else if(href_list["godmode"])
|
||||
if(!check_rights(R_REJUVINATE))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["godmode"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.cmd_admin_godmode(M)
|
||||
href_list["datumrefresh"] = href_list["godmode"]
|
||||
|
||||
else if(href_list["mark_object"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/datum/D = locate(href_list["mark_object"])
|
||||
if(!istype(D))
|
||||
usr << "This can only be done to instances of type /datum"
|
||||
return
|
||||
|
||||
src.holder.marked_datum = D
|
||||
href_list["datumrefresh"] = href_list["mark_object"]
|
||||
|
||||
else if(href_list["proc_call"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/T = locate(href_list["proc_call"])
|
||||
|
||||
if(T)
|
||||
callproc_datum(T)
|
||||
|
||||
else if(href_list["regenerateicons"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["regenerateicons"])
|
||||
if(!ismob(M))
|
||||
usr << "This can only be done to instances of type /mob"
|
||||
return
|
||||
M.regenerate_icons()
|
||||
|
||||
//Needs +VAREDIT past this point
|
||||
|
||||
else if(check_rights(R_VAREDIT))
|
||||
|
||||
|
||||
//~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
|
||||
|
||||
if(href_list["rename"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["rename"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN)
|
||||
if( !new_name || !M )
|
||||
return
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
|
||||
M.fully_replace_character_name(M.real_name,new_name)
|
||||
href_list["datumrefresh"] = href_list["rename"]
|
||||
|
||||
else if(href_list["varnameedit"] && href_list["datumedit"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/D = locate(href_list["datumedit"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
usr << "This can only be used on instances of types /client or /datum"
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnameedit"], 1)
|
||||
|
||||
else if(href_list["varnamechange"] && href_list["datumchange"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/D = locate(href_list["datumchange"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
usr << "This can only be used on instances of types /client or /datum"
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnamechange"], 0)
|
||||
|
||||
else if(href_list["varnamemass"] && href_list["datummass"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["datummass"])
|
||||
if(!istype(A))
|
||||
usr << "This can only be used on instances of type /atom"
|
||||
return
|
||||
|
||||
cmd_mass_modify_object_variables(A, href_list["varnamemass"])
|
||||
|
||||
else if(href_list["give_spell"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["give_spell"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.give_spell(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["give_disease"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["give_disease"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.give_disease(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["ninja"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["ninja"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.cmd_admin_ninjafy(M)
|
||||
href_list["datumrefresh"] = href_list["ninja"]
|
||||
|
||||
else if(href_list["gib"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["gib"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
src.cmd_admin_gib(M)
|
||||
|
||||
else if(href_list["build_mode"])
|
||||
if(!check_rights(R_BUILDMODE))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["build_mode"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
togglebuildmode(M)
|
||||
href_list["datumrefresh"] = href_list["build_mode"]
|
||||
|
||||
else if(href_list["drop_everything"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["drop_everything"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
usr.client.cmd_admin_drop_everything(M)
|
||||
|
||||
else if(href_list["direct_control"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["direct_control"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
usr.client.cmd_assume_direct_control(M)
|
||||
|
||||
else if(href_list["offer_control"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/M = locate(href_list["offer_control"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
offer_control(M)
|
||||
|
||||
else if(href_list["delall"])
|
||||
if(!check_rights(R_DEBUG|R_SERVER))
|
||||
return
|
||||
|
||||
var/obj/O = locate(href_list["delall"])
|
||||
if(!isobj(O))
|
||||
usr << "This can only be used on instances of type /obj"
|
||||
return
|
||||
|
||||
var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
|
||||
if(action_type == "Cancel" || !action_type)
|
||||
return
|
||||
|
||||
if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes")
|
||||
return
|
||||
|
||||
if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
|
||||
return
|
||||
|
||||
var/O_type = O.type
|
||||
switch(action_type)
|
||||
if("Strict type")
|
||||
var/i = 0
|
||||
for(var/obj/Obj in world)
|
||||
if(Obj.type == O_type)
|
||||
i++
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
usr << "No objects of this type exist"
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) </span>")
|
||||
if("Type and subtypes")
|
||||
var/i = 0
|
||||
for(var/obj/Obj in world)
|
||||
if(istype(Obj,O_type))
|
||||
i++
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
usr << "No objects of this type exist"
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) </span>")
|
||||
|
||||
else if(href_list["addreagent"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["addreagent"])
|
||||
|
||||
if(!A.reagents)
|
||||
var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num
|
||||
if(amount)
|
||||
A.create_reagents(amount)
|
||||
|
||||
if(A.reagents)
|
||||
var/list/reagent_options = sortList(chemical_reagents_list)
|
||||
var/chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") in reagent_options|null
|
||||
if(chosen_id)
|
||||
var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num
|
||||
if(amount)
|
||||
A.reagents.add_reagent(chosen_id, amount)
|
||||
log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]</span>")
|
||||
|
||||
href_list["datumrefresh"] = href_list["addreagent"]
|
||||
|
||||
else if(href_list["explode"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["explode"])
|
||||
if(!isobj(A) && !ismob(A) && !isturf(A))
|
||||
usr << "This can only be done to instances of type /obj, /mob and /turf"
|
||||
return
|
||||
|
||||
src.cmd_admin_explosion(A)
|
||||
href_list["datumrefresh"] = href_list["explode"]
|
||||
|
||||
else if(href_list["emp"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["emp"])
|
||||
if(!isobj(A) && !ismob(A) && !isturf(A))
|
||||
usr << "This can only be done to instances of type /obj, /mob and /turf"
|
||||
return
|
||||
|
||||
src.cmd_admin_emp(A)
|
||||
href_list["datumrefresh"] = href_list["emp"]
|
||||
|
||||
else if(href_list["rotatedatum"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/atom/A = locate(href_list["rotatedatum"])
|
||||
if(!istype(A))
|
||||
usr << "This can only be done to instances of type /atom"
|
||||
return
|
||||
|
||||
switch(href_list["rotatedir"])
|
||||
if("right")
|
||||
A.setDir(turn(A.dir, -45))
|
||||
if("left")
|
||||
A.setDir(turn(A.dir, 45))
|
||||
href_list["datumrefresh"] = href_list["rotatedatum"]
|
||||
|
||||
else if(href_list["editorgans"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = locate(href_list["editorgans"])
|
||||
if(!istype(C))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon"
|
||||
return
|
||||
|
||||
manipulate_organs(C)
|
||||
href_list["datumrefresh"] = href_list["editorgans"]
|
||||
|
||||
else if(href_list["makehuman"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"])
|
||||
if(!istype(Mo))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/monkey"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!Mo)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("humanone"=href_list["makehuman"]))
|
||||
|
||||
else if(href_list["makemonkey"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))
|
||||
|
||||
else if(href_list["makerobot"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makerobot"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("makerobot"=href_list["makerobot"]))
|
||||
|
||||
else if(href_list["makealien"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makealien"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("makealien"=href_list["makealien"]))
|
||||
|
||||
else if(href_list["makeslime"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makeslime"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("makeslime"=href_list["makeslime"]))
|
||||
|
||||
else if(href_list["makeai"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/H = locate(href_list["makeai"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("makeai"=href_list["makeai"]))
|
||||
|
||||
else if(href_list["setspecies"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["setspecies"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
var/result = input(usr, "Please choose a new species","Species") as null|anything in species_list
|
||||
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
if(result)
|
||||
var/newtype = species_list[result]
|
||||
H.set_species(newtype)
|
||||
|
||||
else if(href_list["removebodypart"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["removebodypart"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
var/result = input(usr, "Please choose which body part to remove","Remove Body Part") as null|anything in list("head", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
if(result)
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(result)
|
||||
if(BP)
|
||||
BP.drop_limb()
|
||||
|
||||
else if(href_list["purrbation"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["purrbation"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
if(!ishumanbasic(H))
|
||||
usr << "This can only be done to the basic human species \
|
||||
at the moment."
|
||||
return
|
||||
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
var/success = purrbation_toggle(H)
|
||||
if(success)
|
||||
usr << "Put [H] on purrbation."
|
||||
log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has put [key_name(H)] on purrbation.</span>")
|
||||
|
||||
else
|
||||
usr << "Removed [H] from purrbation."
|
||||
log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has removed [key_name(H)] from purrbation.</span>")
|
||||
|
||||
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/mob/living/L = locate(href_list["mobToDamage"])
|
||||
if(!istype(L))
|
||||
return
|
||||
|
||||
var/Text = href_list["adjustDamage"]
|
||||
|
||||
var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num
|
||||
|
||||
if(!L)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
switch(Text)
|
||||
if("brute")
|
||||
L.adjustBruteLoss(amount)
|
||||
if("fire")
|
||||
L.adjustFireLoss(amount)
|
||||
if("toxin")
|
||||
L.adjustToxLoss(amount)
|
||||
if("oxygen")
|
||||
L.adjustOxyLoss(amount)
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
if("stamina")
|
||||
L.adjustStaminaLoss(amount)
|
||||
else
|
||||
usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]"
|
||||
return
|
||||
|
||||
if(amount != 0)
|
||||
log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] dealt [amount] amount of [Text] damage to [L] </span>")
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
|
||||
|
||||
return
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
/mob/proc/HasDisease(datum/disease/D)
|
||||
for(var/datum/disease/DD in viruses)
|
||||
if(D.IsSame(DD))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/proc/CanContractDisease(datum/disease/D)
|
||||
if(stat == DEAD)
|
||||
return 0
|
||||
|
||||
if(D.GetDiseaseID() in resistances)
|
||||
return 0
|
||||
|
||||
if(HasDisease(D))
|
||||
return 0
|
||||
|
||||
if(!(type in D.viable_mobtypes))
|
||||
return 0
|
||||
|
||||
if(count_by_type(viruses, /datum/disease/advance) >= 3)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/mob/proc/ContractDisease(datum/disease/D)
|
||||
if(!CanContractDisease(D))
|
||||
return 0
|
||||
AddDisease(D)
|
||||
|
||||
|
||||
/mob/proc/AddDisease(datum/disease/D)
|
||||
var/datum/disease/DD = new D.type(1, D, 0)
|
||||
viruses += DD
|
||||
DD.affected_mob = src
|
||||
DD.holder = src
|
||||
|
||||
//Copy properties over. This is so edited diseases persist.
|
||||
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
|
||||
for(var/V in DD.vars)
|
||||
if(V in skipped)
|
||||
continue
|
||||
if(istype(DD.vars[V],/list))
|
||||
var/list/L = D.vars[V]
|
||||
DD.vars[V] = L.Copy()
|
||||
else
|
||||
DD.vars[V] = D.vars[V]
|
||||
|
||||
DD.affected_mob.med_hud_set_status()
|
||||
|
||||
|
||||
/mob/living/carbon/ContractDisease(datum/disease/D)
|
||||
if(!CanContractDisease(D))
|
||||
return 0
|
||||
|
||||
var/obj/item/clothing/Cl = null
|
||||
var/passed = 1
|
||||
|
||||
var/head_ch = 100
|
||||
var/body_ch = 100
|
||||
var/hands_ch = 25
|
||||
var/feet_ch = 25
|
||||
|
||||
if(D.spread_flags & CONTACT_HANDS)
|
||||
head_ch = 0
|
||||
body_ch = 0
|
||||
hands_ch = 100
|
||||
feet_ch = 0
|
||||
if(D.spread_flags & CONTACT_FEET)
|
||||
head_ch = 0
|
||||
body_ch = 0
|
||||
hands_ch = 0
|
||||
feet_ch = 100
|
||||
|
||||
if(prob(15/D.permeability_mod))
|
||||
return
|
||||
|
||||
if(satiety>0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease.
|
||||
return
|
||||
|
||||
var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)
|
||||
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
|
||||
switch(target_zone)
|
||||
if(1)
|
||||
if(isobj(H.head) && !istype(H.head, /obj/item/weapon/paper))
|
||||
Cl = H.head
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
if(passed && isobj(H.wear_mask))
|
||||
Cl = H.wear_mask
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
if(2)
|
||||
if(isobj(H.wear_suit))
|
||||
Cl = H.wear_suit
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
if(passed && isobj(slot_w_uniform))
|
||||
Cl = slot_w_uniform
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
if(3)
|
||||
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS)
|
||||
Cl = H.wear_suit
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
|
||||
if(passed && isobj(H.gloves))
|
||||
Cl = H.gloves
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
if(4)
|
||||
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET)
|
||||
Cl = H.wear_suit
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
|
||||
if(passed && isobj(H.shoes))
|
||||
Cl = H.shoes
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
|
||||
else if(istype(src, /mob/living/carbon/monkey))
|
||||
var/mob/living/carbon/monkey/M = src
|
||||
switch(target_zone)
|
||||
if(1)
|
||||
if(M.wear_mask && isobj(M.wear_mask))
|
||||
Cl = M.wear_mask
|
||||
passed = prob((Cl.permeability_coefficient*100) - 1)
|
||||
|
||||
if(!passed && (D.spread_flags & AIRBORNE) && !internal)
|
||||
passed = (prob((50*D.permeability_mod) - 1))
|
||||
|
||||
if(passed)
|
||||
AddDisease(D)
|
||||
|
||||
|
||||
//Same as ContractDisease, except never overidden clothes checks
|
||||
/mob/proc/ForceContractDisease(datum/disease/D)
|
||||
if(!CanContractDisease(D))
|
||||
return 0
|
||||
AddDisease(D)
|
||||
|
||||
|
||||
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
|
||||
if(dna && (VIRUSIMMUNE in dna.species.specflags))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -0,0 +1,204 @@
|
||||
|
||||
//Visibility Flags
|
||||
#define HIDDEN_SCANNER 1
|
||||
#define HIDDEN_PANDEMIC 2
|
||||
|
||||
//Disease Flags
|
||||
#define CURABLE 1
|
||||
#define CAN_CARRY 2
|
||||
#define CAN_RESIST 4
|
||||
|
||||
//Spread Flags
|
||||
#define SPECIAL 1
|
||||
#define NON_CONTAGIOUS 2
|
||||
#define BLOOD 4
|
||||
#define CONTACT_FEET 8
|
||||
#define CONTACT_HANDS 16
|
||||
#define CONTACT_GENERAL 32
|
||||
#define AIRBORNE 64
|
||||
|
||||
|
||||
//Severity Defines
|
||||
#define NONTHREAT "No threat"
|
||||
#define MINOR "Minor"
|
||||
#define MEDIUM "Medium"
|
||||
#define HARMFUL "Harmful"
|
||||
#define DANGEROUS "Dangerous!"
|
||||
#define BIOHAZARD "BIOHAZARD THREAT!"
|
||||
|
||||
|
||||
var/list/diseases = subtypesof(/datum/disease)
|
||||
|
||||
|
||||
/datum/disease
|
||||
//Flags
|
||||
var/visibility_flags = 0
|
||||
var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST
|
||||
var/spread_flags = AIRBORNE
|
||||
|
||||
//Fluff
|
||||
var/form = "Virus"
|
||||
var/name = "No disease"
|
||||
var/desc = ""
|
||||
var/agent = "some microbes"
|
||||
var/spread_text = ""
|
||||
var/cure_text = ""
|
||||
|
||||
//Stages
|
||||
var/stage = 1
|
||||
var/max_stages = 0
|
||||
var/stage_prob = 4
|
||||
|
||||
//Other
|
||||
var/longevity = 150 //Time in ticks disease stays in objects, Syringes and such are infinite.
|
||||
var/list/viable_mobtypes = list() //typepaths of viable mobs
|
||||
var/mob/living/carbon/affected_mob = null
|
||||
var/atom/movable/holder = null
|
||||
var/list/cures = list() //list of cures if the disease has the CURABLE flag, these are reagent ids
|
||||
var/infectivity = 65
|
||||
var/cure_chance = 8
|
||||
var/carrier = 0 //If our host is only a carrier
|
||||
var/permeability_mod = 1
|
||||
var/severity = NONTHREAT
|
||||
var/list/required_organs = list()
|
||||
var/needs_all_cures = TRUE
|
||||
var/list/strain_data = list() //dna_spread special bullshit
|
||||
|
||||
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
|
||||
if(carrier && !cure)
|
||||
return
|
||||
|
||||
stage = min(stage, max_stages)
|
||||
|
||||
if(!cure)
|
||||
if(prob(stage_prob))
|
||||
stage = min(stage + 1,max_stages)
|
||||
else
|
||||
if(prob(cure_chance))
|
||||
stage = max(stage - 1, 1)
|
||||
|
||||
if(disease_flags & CURABLE)
|
||||
if(cure && prob(cure_chance))
|
||||
cure()
|
||||
|
||||
|
||||
/datum/disease/proc/has_cure()
|
||||
if(!(disease_flags & CURABLE))
|
||||
return 0
|
||||
|
||||
. = cures.len
|
||||
for(var/C_id in cures)
|
||||
if(!affected_mob.reagents.has_reagent(C_id))
|
||||
.--
|
||||
if(!. || (needs_all_cures && . < cures.len))
|
||||
return 0
|
||||
|
||||
/datum/disease/proc/spread(atom/source, force_spread = 0)
|
||||
if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
|
||||
return
|
||||
|
||||
if(affected_mob)
|
||||
if( affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)) )
|
||||
return
|
||||
|
||||
var/spread_range = 1
|
||||
|
||||
if(force_spread)
|
||||
spread_range = force_spread
|
||||
|
||||
if(spread_flags & AIRBORNE)
|
||||
spread_range++
|
||||
|
||||
if(!source)
|
||||
if(affected_mob)
|
||||
source = affected_mob
|
||||
else
|
||||
return
|
||||
|
||||
if(isturf(source.loc))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, source))
|
||||
if(isturf(C.loc))
|
||||
if(AStar(source, C.loc,/turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs))
|
||||
C.ContractDisease(src)
|
||||
|
||||
|
||||
/datum/disease/process()
|
||||
if(!holder)
|
||||
SSdisease.processing -= src
|
||||
return
|
||||
|
||||
if(prob(infectivity))
|
||||
spread(holder)
|
||||
|
||||
if(affected_mob)
|
||||
for(var/datum/disease/D in affected_mob.viruses)
|
||||
if(D != src)
|
||||
if(IsSame(D))
|
||||
qdel(D)
|
||||
|
||||
if(holder == affected_mob)
|
||||
if(affected_mob.stat != DEAD)
|
||||
stage_act()
|
||||
|
||||
if(!affected_mob)
|
||||
if(prob(70))
|
||||
if(--longevity<=0)
|
||||
cure()
|
||||
|
||||
|
||||
/datum/disease/proc/cure()
|
||||
if(affected_mob)
|
||||
if(disease_flags & CAN_RESIST)
|
||||
if(!(type in affected_mob.resistances))
|
||||
affected_mob.resistances += type
|
||||
remove_virus()
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/disease/New()
|
||||
if(required_organs && required_organs.len)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/human/H = affected_mob
|
||||
for(var/obj/item/organ/O in required_organs)
|
||||
if(!locate(O) in H.bodyparts)
|
||||
if(!locate(O) in H.internal_organs)
|
||||
cure()
|
||||
return
|
||||
|
||||
SSdisease.processing += src
|
||||
|
||||
|
||||
/datum/disease/proc/IsSame(datum/disease/D)
|
||||
if(istype(src, D.type))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/disease/proc/Copy()
|
||||
var/datum/disease/D = new type()
|
||||
D.strain_data = strain_data.Copy()
|
||||
return D
|
||||
|
||||
|
||||
/datum/disease/proc/GetDiseaseID()
|
||||
return type
|
||||
|
||||
|
||||
/datum/disease/Destroy()
|
||||
SSdisease.processing.Remove(src)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/disease/proc/IsSpreadByTouch()
|
||||
if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//don't use this proc directly. this should only ever be called by cure()
|
||||
/datum/disease/proc/remove_virus()
|
||||
affected_mob.viruses -= src //remove the datum from the list
|
||||
affected_mob.med_hud_set_status()
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
|
||||
Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties
|
||||
which add onto the overall disease.
|
||||
|
||||
If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus.
|
||||
|
||||
*/
|
||||
|
||||
var/list/archive_diseases = list()
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
var/list/advance_cures = list(
|
||||
"sodiumchloride", "sugar", "orangejuice",
|
||||
"spaceacillin", "salglu_solution", "ethanol",
|
||||
"leporazine", "synaptizine", "lipolicide",
|
||||
"silver", "gold"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
PROPERTIES
|
||||
|
||||
*/
|
||||
|
||||
/datum/disease/advance
|
||||
|
||||
name = "Unknown" // We will always let our Virologist name our disease.
|
||||
desc = "An engineered disease which can contain a multitude of symptoms."
|
||||
form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
|
||||
agent = "advance microbes"
|
||||
max_stages = 5
|
||||
spread_text = "Unknown"
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
|
||||
// NEW VARS
|
||||
|
||||
var/list/symptoms = list() // The symptoms of the disease.
|
||||
var/id = ""
|
||||
var/processing = 0
|
||||
|
||||
/*
|
||||
|
||||
OLD PROCS
|
||||
|
||||
*/
|
||||
|
||||
/datum/disease/advance/New(var/process = 1, var/datum/disease/advance/D)
|
||||
|
||||
// Setup our dictionary if it hasn't already.
|
||||
if(!dictionary_symptoms.len)
|
||||
for(var/symp in list_symptoms)
|
||||
var/datum/symptom/S = new symp
|
||||
dictionary_symptoms[S.id] = symp
|
||||
|
||||
if(!istype(D))
|
||||
D = null
|
||||
// Generate symptoms if we weren't given any.
|
||||
|
||||
if(!symptoms || !symptoms.len)
|
||||
|
||||
if(!D || !D.symptoms || !D.symptoms.len)
|
||||
symptoms = GenerateSymptoms(0, 2)
|
||||
else
|
||||
for(var/datum/symptom/S in D.symptoms)
|
||||
symptoms += new S.type
|
||||
|
||||
Refresh()
|
||||
..(process, D)
|
||||
return
|
||||
|
||||
/datum/disease/advance/Destroy()
|
||||
if(processing)
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.End(src)
|
||||
return ..()
|
||||
|
||||
// Randomly pick a symptom to activate.
|
||||
/datum/disease/advance/stage_act()
|
||||
..()
|
||||
if(symptoms && symptoms.len)
|
||||
|
||||
if(!processing)
|
||||
processing = 1
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Start(src)
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Activate(src)
|
||||
else
|
||||
CRASH("We do not have any symptoms during stage_act()!")
|
||||
|
||||
// Compares type then ID.
|
||||
/datum/disease/advance/IsSame(datum/disease/advance/D)
|
||||
|
||||
if(!(istype(D, /datum/disease/advance)))
|
||||
return 0
|
||||
|
||||
if(src.GetDiseaseID() != D.GetDiseaseID())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// To add special resistances.
|
||||
/datum/disease/advance/cure(resistance=1)
|
||||
if(affected_mob)
|
||||
var/id = "[GetDiseaseID()]"
|
||||
if(resistance && !(id in affected_mob.resistances))
|
||||
affected_mob.resistances[id] = id
|
||||
remove_virus()
|
||||
qdel(src) //delete the datum to stop it processing
|
||||
|
||||
// Returns the advance disease with a different reference memory.
|
||||
/datum/disease/advance/Copy(process = 0)
|
||||
return new /datum/disease/advance(process, src, 1)
|
||||
|
||||
/*
|
||||
|
||||
NEW PROCS
|
||||
|
||||
*/
|
||||
|
||||
// Mix the symptoms of two diseases (the src and the argument)
|
||||
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
|
||||
if(!(src.IsSame(D)))
|
||||
var/list/possible_symptoms = shuffle(D.symptoms)
|
||||
for(var/datum/symptom/S in possible_symptoms)
|
||||
AddSymptom(new S.type)
|
||||
|
||||
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
|
||||
for(var/datum/symptom/symp in symptoms)
|
||||
if(symp.id == S.id)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated.
|
||||
/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0)
|
||||
|
||||
var/list/generated = list() // Symptoms we generated.
|
||||
|
||||
// Generate symptoms. By default, we only choose non-deadly symptoms.
|
||||
var/list/possible_symptoms = list()
|
||||
for(var/symp in list_symptoms)
|
||||
var/datum/symptom/S = new symp
|
||||
if(S.level >= level_min && S.level <= level_max)
|
||||
if(!HasSymptom(S))
|
||||
possible_symptoms += S
|
||||
|
||||
if(!possible_symptoms.len)
|
||||
return generated
|
||||
|
||||
// Random chance to get more than one symptom
|
||||
var/number_of = amount_get
|
||||
if(!amount_get)
|
||||
number_of = 1
|
||||
while(prob(20))
|
||||
number_of += 1
|
||||
|
||||
for(var/i = 1; number_of >= i && possible_symptoms.len; i++)
|
||||
generated += pick_n_take(possible_symptoms)
|
||||
|
||||
return generated
|
||||
|
||||
/datum/disease/advance/proc/Refresh(new_name = 0)
|
||||
//world << "[src.name] \ref[src] - REFRESH!"
|
||||
var/list/properties = GenerateProperties()
|
||||
AssignProperties(properties)
|
||||
id = null
|
||||
|
||||
if(!archive_diseases[GetDiseaseID()])
|
||||
if(new_name)
|
||||
AssignName()
|
||||
archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
|
||||
archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)
|
||||
|
||||
var/datum/disease/advance/A = archive_diseases[GetDiseaseID()]
|
||||
AssignName(A.name)
|
||||
|
||||
//Generate disease properties based on the effects. Returns an associated list.
|
||||
/datum/disease/advance/proc/GenerateProperties()
|
||||
|
||||
if(!symptoms || !symptoms.len)
|
||||
CRASH("We did not have any symptoms before generating properties.")
|
||||
return
|
||||
|
||||
var/list/properties = list("resistance" = 1, "stealth" = 1, "stage_rate" = 1, "transmittable" = 1, "severity" = 0)
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
|
||||
properties["resistance"] += S.resistance
|
||||
properties["stealth"] += S.stealth
|
||||
properties["stage_rate"] += S.stage_speed
|
||||
properties["transmittable"] += S.transmittable
|
||||
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom
|
||||
|
||||
return properties
|
||||
|
||||
// Assign the properties that are in the list.
|
||||
/datum/disease/advance/proc/AssignProperties(list/properties = list())
|
||||
|
||||
if(properties && properties.len)
|
||||
switch(properties["stealth"])
|
||||
if(2)
|
||||
visibility_flags = HIDDEN_SCANNER
|
||||
if(3 to INFINITY)
|
||||
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
|
||||
|
||||
// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
|
||||
SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), BLOOD, AIRBORNE))
|
||||
permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1)
|
||||
cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20
|
||||
stage_prob = max(properties["stage_rate"], 2)
|
||||
SetSeverity(properties["severity"])
|
||||
GenerateCure(properties)
|
||||
else
|
||||
CRASH("Our properties were empty or null!")
|
||||
|
||||
|
||||
// Assign the spread type and give it the correct description.
|
||||
/datum/disease/advance/proc/SetSpread(spread_id)
|
||||
switch(spread_id)
|
||||
if(NON_CONTAGIOUS)
|
||||
spread_text = "None"
|
||||
if(SPECIAL)
|
||||
spread_text = "None"
|
||||
if(CONTACT_GENERAL, CONTACT_HANDS, CONTACT_FEET)
|
||||
spread_text = "On contact"
|
||||
if(AIRBORNE)
|
||||
spread_text = "Airborne"
|
||||
if(BLOOD)
|
||||
spread_text = "Blood"
|
||||
|
||||
spread_flags = spread_id
|
||||
|
||||
/datum/disease/advance/proc/SetSeverity(level_sev)
|
||||
|
||||
switch(level_sev)
|
||||
|
||||
if(-INFINITY to 0)
|
||||
severity = NONTHREAT
|
||||
if(1)
|
||||
severity = MINOR
|
||||
if(2)
|
||||
severity = MEDIUM
|
||||
if(3)
|
||||
severity = HARMFUL
|
||||
if(4)
|
||||
severity = DANGEROUS
|
||||
if(5 to INFINITY)
|
||||
severity = BIOHAZARD
|
||||
else
|
||||
severity = "Unknown"
|
||||
|
||||
|
||||
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
|
||||
/datum/disease/advance/proc/GenerateCure(list/properties = list())
|
||||
if(properties && properties.len)
|
||||
var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
|
||||
//world << "Res = [res]"
|
||||
cures = list(advance_cures[res])
|
||||
|
||||
// Get the cure name from the cure_id
|
||||
var/datum/reagent/D = chemical_reagents_list[cures[1]]
|
||||
cure_text = D.name
|
||||
|
||||
|
||||
return
|
||||
|
||||
// Randomly generate a symptom, has a chance to lose or gain a symptom.
|
||||
/datum/disease/advance/proc/Evolve(min_level, max_level)
|
||||
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
|
||||
if(s)
|
||||
AddSymptom(s)
|
||||
Refresh(1)
|
||||
return
|
||||
|
||||
// Randomly remove a symptom.
|
||||
/datum/disease/advance/proc/Devolve()
|
||||
if(symptoms.len > 1)
|
||||
var/s = safepick(symptoms)
|
||||
if(s)
|
||||
RemoveSymptom(s)
|
||||
Refresh(1)
|
||||
return
|
||||
|
||||
// Name the disease.
|
||||
/datum/disease/advance/proc/AssignName(name = "Unknown")
|
||||
src.name = name
|
||||
return
|
||||
|
||||
// Return a unique ID of the disease.
|
||||
/datum/disease/advance/GetDiseaseID()
|
||||
if(!id)
|
||||
var/list/L = list()
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
L += S.id
|
||||
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
|
||||
var/result = jointext(L, ":")
|
||||
id = result
|
||||
return id
|
||||
|
||||
|
||||
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
|
||||
// we take a random symptom away and add the new one.
|
||||
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
|
||||
|
||||
if(HasSymptom(S))
|
||||
return
|
||||
|
||||
if(symptoms.len < 5 + rand(-1, 1))
|
||||
symptoms += S
|
||||
else
|
||||
RemoveSymptom(pick(symptoms))
|
||||
symptoms += S
|
||||
return
|
||||
|
||||
// Simply removes the symptom.
|
||||
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
|
||||
symptoms -= S
|
||||
return
|
||||
|
||||
/*
|
||||
|
||||
Static Procs
|
||||
|
||||
*/
|
||||
|
||||
// Mix a list of advance diseases and return the mixed result.
|
||||
/proc/Advance_Mix(var/list/D_list)
|
||||
|
||||
//world << "Mixing!!!!"
|
||||
|
||||
var/list/diseases = list()
|
||||
|
||||
for(var/datum/disease/advance/A in D_list)
|
||||
diseases += A.Copy()
|
||||
|
||||
if(!diseases.len)
|
||||
return null
|
||||
if(diseases.len <= 1)
|
||||
return pick(diseases) // Just return the only entry.
|
||||
|
||||
var/i = 0
|
||||
// Mix our diseases until we are left with only one result.
|
||||
while(i < 20 && diseases.len > 1)
|
||||
|
||||
i++
|
||||
|
||||
var/datum/disease/advance/D1 = pick(diseases)
|
||||
diseases -= D1
|
||||
|
||||
var/datum/disease/advance/D2 = pick(diseases)
|
||||
D2.Mix(D1)
|
||||
|
||||
// Should be only 1 entry left, but if not let's only return a single entry
|
||||
//world << "END MIXING!!!!!"
|
||||
var/datum/disease/advance/to_return = pick(diseases)
|
||||
to_return.Refresh(1)
|
||||
return to_return
|
||||
|
||||
/proc/SetViruses(datum/reagent/R, list/data)
|
||||
if(data)
|
||||
var/list/preserve = list()
|
||||
if(istype(data) && data["viruses"])
|
||||
for(var/datum/disease/A in data["viruses"])
|
||||
preserve += A.Copy()
|
||||
R.data = data.Copy()
|
||||
if(preserve.len)
|
||||
R.data["viruses"] = preserve
|
||||
|
||||
/proc/AdminCreateVirus(client/user)
|
||||
|
||||
if(!user)
|
||||
return
|
||||
|
||||
var/i = 5
|
||||
|
||||
var/datum/disease/advance/D = new(0, null)
|
||||
D.symptoms = list()
|
||||
|
||||
var/list/symptoms = list()
|
||||
symptoms += "Done"
|
||||
symptoms += list_symptoms.Copy()
|
||||
do
|
||||
if(user)
|
||||
var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms
|
||||
if(isnull(symptom))
|
||||
return
|
||||
else if(istext(symptom))
|
||||
i = 0
|
||||
else if(ispath(symptom))
|
||||
var/datum/symptom/S = new symptom
|
||||
if(!D.HasSymptom(S))
|
||||
D.symptoms += S
|
||||
i -= 1
|
||||
while(i > 0)
|
||||
|
||||
if(D.symptoms.len > 0)
|
||||
|
||||
var/new_name = stripped_input(user, "Name your new disease.", "New Name")
|
||||
if(!new_name)
|
||||
return
|
||||
D.AssignName(new_name)
|
||||
D.Refresh()
|
||||
|
||||
for(var/datum/disease/advance/AD in SSdisease.processing)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
|
||||
if(H.z != 1)
|
||||
continue
|
||||
if(!H.HasDisease(D))
|
||||
H.ForceContractDisease(D)
|
||||
break
|
||||
|
||||
var/list/name_symptoms = list()
|
||||
for(var/datum/symptom/S in D.symptoms)
|
||||
name_symptoms += S.name
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
|
||||
/*
|
||||
/mob/verb/test()
|
||||
|
||||
for(var/datum/disease/D in SSdisease.processing)
|
||||
src << "<a href='?_src_=vars;Vars=\ref[D]'>[D.name] - [D.holder]</a>"
|
||||
*/
|
||||
|
||||
|
||||
/datum/disease/advance/proc/totalStageSpeed()
|
||||
var/total_stage_speed = 0
|
||||
for(var/i in symptoms)
|
||||
var/datum/symptom/S = i
|
||||
total_stage_speed += S.stage_speed
|
||||
return total_stage_speed
|
||||
|
||||
/datum/disease/advance/proc/totalStealth()
|
||||
var/total_stealth = 0
|
||||
for(var/i in symptoms)
|
||||
var/datum/symptom/S = i
|
||||
total_stealth += S.stealth
|
||||
return total_stealth
|
||||
|
||||
/datum/disease/advance/proc/totalResistance()
|
||||
var/total_resistance = 0
|
||||
for(var/i in symptoms)
|
||||
var/datum/symptom/S = i
|
||||
total_resistance += S.resistance
|
||||
return total_resistance
|
||||
|
||||
/datum/disease/advance/proc/totalTransmittable()
|
||||
var/total_transmittable = 0
|
||||
for(var/i in symptoms)
|
||||
var/datum/symptom/S = i
|
||||
total_transmittable += S.transmittable
|
||||
return total_transmittable
|
||||
|
||||
#undef RANDOM_STARTING_LEVEL
|
||||
@@ -0,0 +1,59 @@
|
||||
// Cold
|
||||
|
||||
/datum/disease/advance/cold/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Cold"
|
||||
symptoms = list(new/datum/symptom/sneeze)
|
||||
..(process, D, copy)
|
||||
|
||||
|
||||
// Flu
|
||||
|
||||
/datum/disease/advance/flu/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Flu"
|
||||
symptoms = list(new/datum/symptom/cough)
|
||||
..(process, D, copy)
|
||||
|
||||
|
||||
// Voice Changing
|
||||
|
||||
/datum/disease/advance/voice_change/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Epiglottis Mutation"
|
||||
symptoms = list(new/datum/symptom/voice_change)
|
||||
..(process, D, copy)
|
||||
|
||||
|
||||
// Toxin Filter
|
||||
|
||||
/datum/disease/advance/heal/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Liver Enhancer"
|
||||
symptoms = list(new/datum/symptom/heal)
|
||||
..(process, D, copy)
|
||||
|
||||
|
||||
// Hullucigen
|
||||
|
||||
/datum/disease/advance/hullucigen/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Reality Impairment"
|
||||
symptoms = list(new/datum/symptom/hallucigen)
|
||||
..(process, D, copy)
|
||||
|
||||
// Sensory Restoration
|
||||
|
||||
/datum/disease/advance/sensory_restoration/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Reality Enhancer"
|
||||
symptoms = list(new/datum/symptom/sensory_restoration)
|
||||
..(process, D, copy)
|
||||
|
||||
// Sensory Destruction
|
||||
|
||||
/datum/disease/advance/sensory_destruction/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
|
||||
if(!D)
|
||||
name = "Reality Destruction"
|
||||
symptoms = list(new/datum/symptom/sensory_destruction)
|
||||
..(process, D, copy)
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Facial Hypertrichosis
|
||||
|
||||
Very very Noticable.
|
||||
Decreases resistance slightly.
|
||||
Decreases stage speed.
|
||||
Reduced transmittability
|
||||
Intense Level.
|
||||
|
||||
BONUS
|
||||
Makes the mob grow a massive beard, regardless of gender.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/beard
|
||||
|
||||
name = "Facial Hypertrichosis"
|
||||
stealth = -3
|
||||
resistance = -1
|
||||
stage_speed = -3
|
||||
transmittable = -1
|
||||
level = 4
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/beard/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
H << "<span class='warning'>Your chin itches.</span>"
|
||||
if(H.facial_hair_style == "Shaved")
|
||||
H.facial_hair_style = "Jensen Beard"
|
||||
H.update_hair()
|
||||
if(3, 4)
|
||||
H << "<span class='warning'>You feel tough.</span>"
|
||||
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard"))
|
||||
H.facial_hair_style = "Full Beard"
|
||||
H.update_hair()
|
||||
else
|
||||
H << "<span class='warning'>You feel manly!</span>"
|
||||
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard"))
|
||||
H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard")
|
||||
H.update_hair()
|
||||
return
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Choking
|
||||
|
||||
Very very noticable.
|
||||
Lowers resistance.
|
||||
Decreases stage speed.
|
||||
Decreases transmittablity tremendously.
|
||||
Moderate Level.
|
||||
|
||||
Bonus
|
||||
Inflicts spikes of oxyloss
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/choking
|
||||
|
||||
name = "Choking"
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
transmittable = -4
|
||||
level = 3
|
||||
severity = 3
|
||||
|
||||
/datum/symptom/choking/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
M << "<span class='warning'>[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]</span>"
|
||||
if(3, 4)
|
||||
M << "<span class='warning'><b>[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]</span>"
|
||||
Choke_stage_3_4(M, A)
|
||||
M.emote("gasp")
|
||||
else
|
||||
M << "<span class='userdanger'>[pick("You're choking!", "You can't breathe!")]</span>"
|
||||
Choke(M, A)
|
||||
M.emote("gasp")
|
||||
return
|
||||
|
||||
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth())
|
||||
M.adjustOxyLoss(get_damage)
|
||||
return 1
|
||||
|
||||
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth()*5)
|
||||
M.adjustOxyLoss(get_damage)
|
||||
return 1
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Confusion
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance.
|
||||
Decreases stage speed.
|
||||
Not very transmittable.
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Makes the affected mob be confused for short periods of time.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/confusion
|
||||
|
||||
name = "Confusion"
|
||||
stealth = 1
|
||||
resistance = -1
|
||||
stage_speed = -3
|
||||
transmittable = 0
|
||||
level = 4
|
||||
severity = 2
|
||||
|
||||
|
||||
/datum/symptom/confusion/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("Your head hurts.", "Your mind blanks for a moment.")]</span>"
|
||||
else
|
||||
M << "<span class='userdanger'>You can't think straight!</span>"
|
||||
M.confused = min(100, M.confused + 8)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Coughing
|
||||
|
||||
Noticable.
|
||||
Little Resistance.
|
||||
Doesn't increase stage speed much.
|
||||
Transmittable.
|
||||
Low Level.
|
||||
|
||||
BONUS
|
||||
Will force the affected mob to drop small items!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/cough
|
||||
|
||||
name = "Cough"
|
||||
stealth = -1
|
||||
resistance = 3
|
||||
stage_speed = 1
|
||||
transmittable = 2
|
||||
level = 1
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/cough/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
M << "<span notice='warning'>[pick("You swallow excess mucus.", "You lightly cough.")]</span>"
|
||||
else
|
||||
M.emote("cough")
|
||||
var/obj/item/I = M.get_active_hand()
|
||||
if(I && I.w_class == 1)
|
||||
M.drop_item()
|
||||
return
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Damage Converter
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Reduced transmittablity
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Slowly converts brute/fire damage to toxin.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/damage_converter
|
||||
|
||||
name = "Toxic Compensation"
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -2
|
||||
level = 4
|
||||
|
||||
/datum/symptom/damage_converter/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
Convert(M)
|
||||
return
|
||||
|
||||
/datum/symptom/damage_converter/proc/Convert(mob/living/M)
|
||||
|
||||
var/get_damage = rand(1, 2)
|
||||
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
var/list/parts = H.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
|
||||
for(var/obj/item/bodypart/L in parts)
|
||||
L.heal_damage(get_damage, get_damage, 0)
|
||||
M.adjustToxLoss(get_damage*parts.len)
|
||||
|
||||
else
|
||||
if(M.getFireLoss() > 0 || M.getBruteLoss() > 0)
|
||||
M.adjustFireLoss(-get_damage)
|
||||
M.adjustBruteLoss(-get_damage)
|
||||
M.adjustToxLoss(get_damage)
|
||||
else
|
||||
return
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Deafness
|
||||
|
||||
Slightly noticable.
|
||||
Lowers resistance.
|
||||
Decreases stage speed slightly.
|
||||
Decreases transmittablity.
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Causes intermittent loss of hearing.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/deafness
|
||||
|
||||
name = "Deafness"
|
||||
stealth = -1
|
||||
resistance = -2
|
||||
stage_speed = -1
|
||||
transmittable = -3
|
||||
level = 4
|
||||
severity = 3
|
||||
|
||||
/datum/symptom/deafness/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(3, 4)
|
||||
M << "<span class='warning'>[pick("You hear a ringing in your ear.", "Your ears pop.")]</span>"
|
||||
if(5)
|
||||
if(!(M.ear_deaf))
|
||||
M << "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>"
|
||||
M.setEarDamage(-1,INFINITY) //Shall be enough
|
||||
spawn(200)
|
||||
if(M)
|
||||
M << "<span class='warning'>The ringing in your ears fades...</span>"
|
||||
M.setEarDamage(-1,0)
|
||||
return
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Dizziness
|
||||
|
||||
Hidden.
|
||||
Lowers resistance considerably.
|
||||
Decreases stage speed.
|
||||
Reduced transmittability
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Shakes the affected mob's screen for short periods.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/dizzy // Not the egg
|
||||
|
||||
name = "Dizziness"
|
||||
stealth = 2
|
||||
resistance = -2
|
||||
stage_speed = -3
|
||||
transmittable = -1
|
||||
level = 4
|
||||
severity = 2
|
||||
|
||||
/datum/symptom/dizzy/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("You feel dizzy.", "Your head spins.")]</span>"
|
||||
else
|
||||
M << "<span class='userdanger'>A wave of dizziness washes over you!</span>"
|
||||
M.Dizzy(5)
|
||||
return
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Fever
|
||||
|
||||
No change to hidden.
|
||||
Increases resistance.
|
||||
Increases stage speed.
|
||||
Little transmittable.
|
||||
Low level.
|
||||
|
||||
Bonus
|
||||
Heats up your body.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/fever
|
||||
|
||||
name = "Fever"
|
||||
stealth = 0
|
||||
resistance = 3
|
||||
stage_speed = 3
|
||||
transmittable = 2
|
||||
level = 2
|
||||
severity = 2
|
||||
|
||||
/datum/symptom/fever/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
M << "<span class='warning'>[pick("You feel hot.", "You feel like you're burning.")]</span>"
|
||||
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
Heat(M, A)
|
||||
|
||||
return
|
||||
|
||||
/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A)
|
||||
var/get_heat = (sqrt(21+A.totalTransmittable()*2))+(sqrt(20+A.totalStageSpeed()*3))
|
||||
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
|
||||
return 1
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Spontaneous Combustion
|
||||
|
||||
Slightly hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage tremendously.
|
||||
Decreases transmittablity tremendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Ignites infected mob.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/fire
|
||||
|
||||
name = "Spontaneous Combustion"
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -4
|
||||
level = 6
|
||||
severity = 5
|
||||
|
||||
/datum/symptom/fire/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(3)
|
||||
M << "<span class='warning'>[pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")]</span>"
|
||||
if(4)
|
||||
Firestacks_stage_4(M, A)
|
||||
M.IgniteMob()
|
||||
M << "<span class='userdanger'>Your skin bursts into flames!</span>"
|
||||
M.emote("scream")
|
||||
if(5)
|
||||
Firestacks_stage_5(M, A)
|
||||
M.IgniteMob()
|
||||
M << "<span class='userdanger'>Your skin erupts into an inferno!</span>"
|
||||
M.emote("scream")
|
||||
return
|
||||
|
||||
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
|
||||
var/get_stacks = (sqrt(20+A.totalStageSpeed()*2))-(sqrt(16+A.totalStealth()))
|
||||
M.adjust_fire_stacks(get_stacks)
|
||||
M.adjustFireLoss(get_stacks/2)
|
||||
return 1
|
||||
|
||||
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
|
||||
var/get_stacks = (sqrt(20+A.totalStageSpeed()*3))-(sqrt(16+A.totalStealth()))
|
||||
M.adjust_fire_stacks(get_stacks)
|
||||
M.adjustFireLoss(get_stacks)
|
||||
return 1
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Necrotizing Fasciitis (AKA Flesh-Eating Disease)
|
||||
|
||||
Very very noticable.
|
||||
Lowers resistance tremendously.
|
||||
No changes to stage speed.
|
||||
Decreases transmittablity temrendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Deals brute damage over time.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/flesh_eating
|
||||
|
||||
name = "Necrotizing Fasciitis"
|
||||
stealth = -3
|
||||
resistance = -4
|
||||
stage_speed = 0
|
||||
transmittable = -4
|
||||
level = 6
|
||||
severity = 5
|
||||
|
||||
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(2,3)
|
||||
M << "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>"
|
||||
if(4,5)
|
||||
M << "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>"
|
||||
Flesheat(M, A)
|
||||
return
|
||||
|
||||
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = ((sqrt(16-A.totalStealth()))*5)
|
||||
M.adjustBruteLoss(get_damage)
|
||||
return 1
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
DNA Saboteur
|
||||
|
||||
Very noticable.
|
||||
Lowers resistance tremendously.
|
||||
No changes to stage speed.
|
||||
Decreases transmittablity tremendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Cleans the DNA of a person and then randomly gives them a disability.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/genetic_mutation
|
||||
|
||||
name = "Deoxyribonucleic Acid Saboteur"
|
||||
stealth = -2
|
||||
resistance = -3
|
||||
stage_speed = 0
|
||||
transmittable = -3
|
||||
level = 6
|
||||
severity = 3
|
||||
var/list/possible_mutations
|
||||
var/archived_dna = null
|
||||
|
||||
/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5)) // 15% chance
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(!M.has_dna())
|
||||
return
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
M << "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>"
|
||||
M.dna.remove_mutation_group(possible_mutations)
|
||||
randmut(M, possible_mutations)
|
||||
return
|
||||
|
||||
// Archive their DNA before they were infected.
|
||||
/datum/symptom/genetic_mutation/Start(datum/disease/advance/A)
|
||||
possible_mutations = (bad_mutations | not_good_mutations) - mutations_list[RACEMUT]
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(M)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
archived_dna = M.dna.struc_enzymes
|
||||
|
||||
// Give them back their old DNA when cured.
|
||||
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(M && archived_dna)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
M.dna.struc_enzymes = archived_dna
|
||||
M.domutcheck()
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Hallucigen
|
||||
|
||||
Very noticable.
|
||||
Lowers resistance considerably.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
Critical Level.
|
||||
|
||||
Bonus
|
||||
Makes the affected mob be hallucinated for short periods of time.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/hallucigen
|
||||
|
||||
name = "Hallucigen"
|
||||
stealth = -2
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -1
|
||||
level = 5
|
||||
severity = 3
|
||||
|
||||
/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
M << "<span class='warning'>[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whispher with no source.", "Your head aches.")]</span>"
|
||||
if(3, 4)
|
||||
M << "<span class='danger'>[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]</span>"
|
||||
else
|
||||
M << "<span class='userdanger'>[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]</span>"
|
||||
M.hallucination += 5
|
||||
|
||||
return
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Headache
|
||||
|
||||
Noticable.
|
||||
Highly resistant.
|
||||
Increases stage speed.
|
||||
Not transmittable.
|
||||
Low Level.
|
||||
|
||||
BONUS
|
||||
Displays an annoying message!
|
||||
Should be used for buffing your disease.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/headache
|
||||
|
||||
name = "Headache"
|
||||
stealth = -1
|
||||
resistance = 4
|
||||
stage_speed = 2
|
||||
transmittable = 0
|
||||
level = 1
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/headache/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
M << "<span class='warning'>[pick("Your head hurts.", "Your head starts pounding.")]</span>"
|
||||
return
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Healing
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity temrendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Heals toxins in the affected mob's blood stream.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal
|
||||
|
||||
name = "Toxic Filter"
|
||||
stealth = 1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -4
|
||||
level = 6
|
||||
|
||||
/datum/symptom/heal/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
Heal(M, A)
|
||||
return
|
||||
|
||||
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = (sqrt(20+A.totalStageSpeed())*(1+rand()))
|
||||
M.adjustToxLoss(-get_damage)
|
||||
return 1
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Metabolism
|
||||
|
||||
Little bit hidden.
|
||||
Lowers resistance.
|
||||
Decreases stage speed.
|
||||
Decreases transmittablity temrendously.
|
||||
High Level.
|
||||
|
||||
Bonus
|
||||
Cures all diseases (except itself) and creates anti-bodies for them until the symptom dies.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/metabolism
|
||||
|
||||
name = "Anti-Bodies Metabolism"
|
||||
stealth = -1
|
||||
resistance = -1
|
||||
stage_speed = -1
|
||||
transmittable = -4
|
||||
level = 3
|
||||
var/list/cured_diseases = list()
|
||||
|
||||
/datum/symptom/heal/metabolism/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/cured = 0
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(D != A)
|
||||
cured = 1
|
||||
cured_diseases += D.GetDiseaseID()
|
||||
D.cure()
|
||||
if(cured)
|
||||
M << "<span class='notice'>You feel much better.</span>"
|
||||
|
||||
/datum/symptom/heal/metabolism/End(datum/disease/advance/A)
|
||||
// Remove all the diseases we cured.
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(M))
|
||||
if(cured_diseases.len)
|
||||
for(var/res in M.resistances)
|
||||
if(res in cured_diseases)
|
||||
M.resistances -= res
|
||||
M << "<span class='warning'>You feel weaker.</span>"
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Longevity
|
||||
|
||||
Medium hidden boost.
|
||||
Large resistance boost.
|
||||
Large stage speed boost.
|
||||
Large transmittablity boost.
|
||||
High Level.
|
||||
|
||||
Bonus
|
||||
After a certain amount of time the symptom will cure itself.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/longevity
|
||||
|
||||
name = "Longevity"
|
||||
stealth = 3
|
||||
resistance = 4
|
||||
stage_speed = 4
|
||||
transmittable = 4
|
||||
level = 3
|
||||
var/longevity = 30
|
||||
|
||||
/datum/symptom/heal/longevity/Heal(mob/living/M, datum/disease/advance/A)
|
||||
longevity -= 1
|
||||
if(!longevity)
|
||||
A.cure()
|
||||
|
||||
/datum/symptom/heal/longevity/Start(datum/disease/advance/A)
|
||||
longevity = rand(initial(longevity) - 5, initial(longevity) + 5)
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
DNA Restoration
|
||||
|
||||
Not well hidden.
|
||||
Lowers resistance minorly.
|
||||
Does not affect stage speed.
|
||||
Decreases transmittablity greatly.
|
||||
Very high level.
|
||||
|
||||
Bonus
|
||||
Heals brain damage, treats radiation, cleans SE of non-power mutations.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/heal/dna
|
||||
|
||||
name = "Deoxyribonucleic Acid Restoration"
|
||||
stealth = -1
|
||||
resistance = -1
|
||||
stage_speed = 0
|
||||
transmittable = -3
|
||||
level = 5
|
||||
|
||||
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
|
||||
var/stage_speed = max( 20 + A.totalStageSpeed(), 0)
|
||||
var/stealth_amount = max( 16 + A.totalStealth(), 0)
|
||||
var/amt_healed = (sqrt(stage_speed*(3+rand())))-(sqrt(stealth_amount*rand()))
|
||||
M.adjustBrainLoss(-amt_healed)
|
||||
//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
|
||||
var/list/unclean_mutations = (not_good_mutations|bad_mutations) - mutations_list[RACEMUT]
|
||||
M.dna.remove_mutation_group(unclean_mutations)
|
||||
M.radiation = max(M.radiation - 3, 0)
|
||||
return 1
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Itching
|
||||
|
||||
Not noticable or unnoticable.
|
||||
Resistant.
|
||||
Increases stage speed.
|
||||
Little transmittable.
|
||||
Low Level.
|
||||
|
||||
BONUS
|
||||
Displays an annoying message!
|
||||
Should be used for buffing your disease.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/itching
|
||||
|
||||
name = "Itching"
|
||||
stealth = 0
|
||||
resistance = 3
|
||||
stage_speed = 3
|
||||
transmittable = 1
|
||||
level = 1
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/itching/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
M << "<span class='warning'>Your [pick("back", "arm", "leg", "elbow", "head")] itches.</span>"
|
||||
return
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Self-Respiration
|
||||
|
||||
Slightly hidden.
|
||||
Lowers resistance significantly.
|
||||
Decreases stage speed significantly.
|
||||
Decreases transmittablity tremendously.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
The body generates salbutamol.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/oxygen
|
||||
|
||||
name = "Self-Respiration"
|
||||
stealth = 1
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -4
|
||||
level = 6
|
||||
|
||||
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
if (M.reagents.get_reagent_amount("salbutamol") < 20)
|
||||
M.reagents.add_reagent("salbutamol", 20)
|
||||
else
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
M << "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>"
|
||||
return
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Sensory-Restoration
|
||||
Very very very very noticable.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity tremendously.
|
||||
Fatal.
|
||||
Bonus
|
||||
The body generates Sensory restorational chemicals.
|
||||
inacusiate for ears
|
||||
antihol for removal of alcohol
|
||||
synaphydramine to purge sensory hallucigens and histamine based impairment
|
||||
mannitol to kickstart the mind
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/sensory_restoration
|
||||
name = "Sensory Restoration"
|
||||
stealth = -1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -3
|
||||
level = 5
|
||||
severity = 0
|
||||
|
||||
/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(2)
|
||||
if(M.reagents.get_reagent_amount("inacusiate")<10)
|
||||
M.reagents.add_reagent("inacusiate", 10)
|
||||
M << "<span class='notice'>Your hearing feels clearer and crisp.</span>"
|
||||
if(3)
|
||||
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 )
|
||||
M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10))
|
||||
M << "<span class='notice'>You feel sober.</span>"
|
||||
if(4)
|
||||
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10)
|
||||
M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10, "synaphydramine"=5))
|
||||
M << "<span class='notice'>You feel focused.</span>"
|
||||
if(5)
|
||||
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10 && M.reagents.get_reagent_amount("mannitol") < 10)
|
||||
M.reagents.add_reagent_list(list("mannitol"=10, "antihol"=10, "inacusiate"=10, "synaphydramine"=10))
|
||||
return
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Sensory-Destruction
|
||||
noticable.
|
||||
Lowers resistance
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity tremendously.
|
||||
the drugs hit them so hard they have to focus on not dying
|
||||
|
||||
Bonus
|
||||
The body generates Sensory destructive chemicals.
|
||||
You cannot taste anything anymore.
|
||||
ethanol for extremely drunk victim
|
||||
mindbreaker to break the mind
|
||||
impedrezene to ruin the brain
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/sensory_destruction
|
||||
name = "Sensory destruction"
|
||||
stealth = -1
|
||||
resistance = -2
|
||||
stage_speed = -3
|
||||
transmittable = -4
|
||||
level = 6
|
||||
severity = 5
|
||||
|
||||
/datum/symptom/sensory_destruction/Activate(var/datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1)
|
||||
M << "<span class='warning'>You can't feel anything.</span>"
|
||||
if(2)
|
||||
M << "<span class='warning'>You feel absolutely hammered.</span>"
|
||||
if(prob(10))
|
||||
M.reagents.add_reagent("morphine",rand(5,7))
|
||||
if(3)
|
||||
M.reagents.add_reagent("ethanol",rand(5,7))
|
||||
M << "<span class='warning'>You try to focus on not dying.</span>"
|
||||
if(prob(15))
|
||||
M.reagents.add_reagent("morphine",rand(5,7))
|
||||
if(4)
|
||||
M.reagents.add_reagent_list(list("ethanol" = rand(7,15), "mindbreaker" = rand(5,10)))
|
||||
M << "<span class='warning'>u can count 2 potato!</span>"
|
||||
if(prob(20))
|
||||
M.reagents.add_reagent("morphine",rand(5,7))
|
||||
if(5)
|
||||
M.reagents.add_reagent_list(list("impedrezene" = rand(5,15), "ethanol" = rand(7,20), "mindbreaker" = rand(5,15)))
|
||||
if(prob(25))
|
||||
M.reagents.add_reagent("morphine",rand(5,7))
|
||||
return
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Alopecia
|
||||
|
||||
Noticable.
|
||||
Decreases resistance slightly.
|
||||
Reduces stage speed slightly.
|
||||
Transmittable.
|
||||
Intense Level.
|
||||
|
||||
BONUS
|
||||
Makes the mob lose hair.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/shedding
|
||||
|
||||
name = "Alopecia"
|
||||
stealth = -1
|
||||
resistance = -1
|
||||
stage_speed = -1
|
||||
transmittable = 2
|
||||
level = 4
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/shedding/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
M << "<span class='warning'>[pick("Your scalp itches.", "Your skin feels flakey.")]</span>"
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
switch(A.stage)
|
||||
if(3, 4)
|
||||
if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair"))
|
||||
H << "<span class='warning'>Your hair starts to fall out in clumps...</span>"
|
||||
spawn(50)
|
||||
H.hair_style = "Balding Hair"
|
||||
H.update_hair()
|
||||
if(5)
|
||||
if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald"))
|
||||
H << "<span class='warning'>Your hair starts to fall out in clumps...</span>"
|
||||
spawn(50)
|
||||
H.facial_hair_style = "Shaved"
|
||||
H.hair_style = "Bald"
|
||||
H.update_hair()
|
||||
return
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Shivering
|
||||
|
||||
No change to hidden.
|
||||
Increases resistance.
|
||||
Increases stage speed.
|
||||
Little transmittable.
|
||||
Low level.
|
||||
|
||||
Bonus
|
||||
Cools down your body.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/shivering
|
||||
|
||||
name = "Shivering"
|
||||
stealth = 0
|
||||
resistance = 2
|
||||
stage_speed = 2
|
||||
transmittable = 2
|
||||
level = 2
|
||||
severity = 2
|
||||
|
||||
/datum/symptom/shivering/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
M << "<span class='warning'>[pick("You feel cold.", "You start shivering.")]</span>"
|
||||
if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
Chill(M, A)
|
||||
return
|
||||
|
||||
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
|
||||
var/get_cold = (sqrt(16+A.totalStealth()*2))+(sqrt(21+A.totalResistance()*2))
|
||||
M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
|
||||
return 1
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Vitiligo
|
||||
|
||||
Extremely Noticable.
|
||||
Decreases resistance slightly.
|
||||
Reduces stage speed slightly.
|
||||
Reduces transmission.
|
||||
Critical Level.
|
||||
|
||||
BONUS
|
||||
Makes the mob lose skin pigmentation.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/vitiligo
|
||||
|
||||
name = "Vitiligo"
|
||||
stealth = -3
|
||||
resistance = -1
|
||||
stage_speed = -1
|
||||
transmittable = -2
|
||||
level = 4
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/vitiligo/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.skin_tone == "albino")
|
||||
return
|
||||
switch(A.stage)
|
||||
if(5)
|
||||
H.skin_tone = "albino"
|
||||
H.update_body(0)
|
||||
else
|
||||
H.visible_message("<span class='warning'>[H] looks a bit pale...</span>", "<span class='notice'>Your skin suddenly appears lighter...</span>")
|
||||
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Revitiligo
|
||||
|
||||
Extremely Noticable.
|
||||
Decreases resistance slightly.
|
||||
Reduces stage speed slightly.
|
||||
Reduces transmission.
|
||||
Critical Level.
|
||||
|
||||
BONUS
|
||||
Makes the mob gain skin pigmentation.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/revitiligo
|
||||
|
||||
name = "Revitiligo"
|
||||
stealth = -3
|
||||
resistance = -1
|
||||
stage_speed = -1
|
||||
transmittable = -2
|
||||
level = 4
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/revitiligo/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.skin_tone == "african2")
|
||||
return
|
||||
switch(A.stage)
|
||||
if(5)
|
||||
H.skin_tone = "african2"
|
||||
H.update_body(0)
|
||||
else
|
||||
H.visible_message("<span class='warning'>[H] looks a bit dark...</span>", "<span class='notice'>Your skin suddenly appears darker...</span>")
|
||||
|
||||
return
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Sneezing
|
||||
|
||||
Very Noticable.
|
||||
Increases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Very transmittable.
|
||||
Low Level.
|
||||
|
||||
Bonus
|
||||
Forces a spread type of AIRBORNE
|
||||
with extra range!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/sneeze
|
||||
|
||||
name = "Sneezing"
|
||||
stealth = -2
|
||||
resistance = 3
|
||||
stage_speed = 0
|
||||
transmittable = 4
|
||||
level = 1
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
M.emote("sniff")
|
||||
else
|
||||
M.emote("sneeze")
|
||||
A.spread(A.holder, 5)
|
||||
return
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Stimulant //gotta go fast
|
||||
|
||||
Noticable.
|
||||
Lowers resistance significantly.
|
||||
Decreases stage speed moderately..
|
||||
Decreases transmittablity tremendously.
|
||||
Moderate Level.
|
||||
|
||||
Bonus
|
||||
The body generates Ephedrine.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/stimulant
|
||||
|
||||
name = "Stimulant"
|
||||
stealth = -1
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
transmittable = -4
|
||||
level = 3
|
||||
|
||||
/datum/symptom/stimulant/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(5)
|
||||
if (M.reagents.get_reagent_amount("ephedrine") < 10)
|
||||
M.reagents.add_reagent("ephedrine", 10)
|
||||
else
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
M << "<span class='notice'>[pick("You feel restless.", "You feel like running laps around the station.")]</span>"
|
||||
return
|
||||
@@ -0,0 +1,40 @@
|
||||
// Symptoms are the effects that engineered advanced diseases do.
|
||||
|
||||
var/list/list_symptoms = subtypesof(/datum/symptom)
|
||||
var/list/dictionary_symptoms = list()
|
||||
|
||||
var/global/const/SYMPTOM_ACTIVATION_PROB = 3
|
||||
|
||||
/datum/symptom
|
||||
// Buffs/Debuffs the symptom has to the overall engineered disease.
|
||||
var/name = ""
|
||||
var/stealth = 0
|
||||
var/resistance = 0
|
||||
var/stage_speed = 0
|
||||
var/transmittable = 0
|
||||
// The type level of the symptom. Higher is harder to generate.
|
||||
var/level = 0
|
||||
// The severity level of the symptom. Higher is more dangerous.
|
||||
var/severity = 0
|
||||
// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
|
||||
var/id = ""
|
||||
|
||||
/datum/symptom/New()
|
||||
var/list/S = list_symptoms
|
||||
for(var/i = 1; i <= S.len; i++)
|
||||
if(src.type == S[i])
|
||||
id = "[i]"
|
||||
return
|
||||
CRASH("We couldn't assign an ID!")
|
||||
|
||||
// Called when processing of the advance disease, which holds this symptom, starts.
|
||||
/datum/symptom/proc/Start(datum/disease/advance/A)
|
||||
return
|
||||
|
||||
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
|
||||
/datum/symptom/proc/End(datum/disease/advance/A)
|
||||
return
|
||||
|
||||
/datum/symptom/proc/Activate(datum/disease/advance/A)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Viral adaptation
|
||||
|
||||
Moderate stealth boost.
|
||||
Major Increases to resistance.
|
||||
Reduces stage speed.
|
||||
No change to transmission
|
||||
Critical Level.
|
||||
|
||||
BONUS
|
||||
Extremely useful for buffing viruses
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/viraladaptation
|
||||
name = "Viral self-adaptation"
|
||||
stealth = 3
|
||||
resistance = 5
|
||||
stage_speed = -3
|
||||
transmittable = 0
|
||||
level = 3
|
||||
|
||||
/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1)
|
||||
M << "<span class='notice'>You feel off, but no different from before.</span>"
|
||||
if(5)
|
||||
M << "<span class='notice'>You feel better, but nothing interesting happens.</span>"
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Viral evolution
|
||||
|
||||
Moderate stealth reductopn.
|
||||
Major decreases to resistance.
|
||||
increases stage speed.
|
||||
increase to transmission
|
||||
Critical Level.
|
||||
|
||||
BONUS
|
||||
Extremely useful for buffing viruses
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
/datum/symptom/viralevolution
|
||||
name = "Viral evolutionary acceleration"
|
||||
stealth = -2
|
||||
resistance = -3
|
||||
stage_speed = 5
|
||||
transmittable = 3
|
||||
level = 3
|
||||
|
||||
/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1)
|
||||
M << "<span class='notice'>You feel better, but no different from before.</span>"
|
||||
if(5)
|
||||
M << "<span class='notice'>You feel off, but nothing interesting happens.</span>"
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Hyphema (Eye bleeding)
|
||||
|
||||
Slightly noticable.
|
||||
Lowers resistance tremendously.
|
||||
Decreases stage speed tremendously.
|
||||
Decreases transmittablity.
|
||||
Critical Level.
|
||||
|
||||
Bonus
|
||||
Causes blindness.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/visionloss
|
||||
|
||||
name = "Hyphema"
|
||||
stealth = -1
|
||||
resistance = -4
|
||||
stage_speed = -4
|
||||
transmittable = -3
|
||||
level = 5
|
||||
severity = 4
|
||||
|
||||
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
M << "<span class='warning'>Your eyes itch.</span>"
|
||||
if(3, 4)
|
||||
M << "<span class='warning'><b>Your eyes burn!</b></span>"
|
||||
M.blur_eyes(10)
|
||||
M.adjust_eye_damage(1)
|
||||
else
|
||||
M << "<span class='userdanger'>Your eyes burn horrificly!</span>"
|
||||
M.blur_eyes(20)
|
||||
M.adjust_eye_damage(5)
|
||||
if(M.eye_damage >= 10)
|
||||
M.become_nearsighted()
|
||||
if(prob(M.eye_damage - 10 + 1))
|
||||
if(M.become_blind())
|
||||
M << "<span class='userdanger'>You go blind!</span>"
|
||||
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Ocular Restoration
|
||||
|
||||
Noticable.
|
||||
Lowers resistance significantly.
|
||||
Decreases stage speed moderately..
|
||||
Decreases transmittablity tremendously.
|
||||
High level.
|
||||
|
||||
Bonus
|
||||
Restores eyesight.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/visionaid
|
||||
|
||||
name = "Ocular Restoration"
|
||||
stealth = -1
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
transmittable = -4
|
||||
level = 4
|
||||
|
||||
/datum/symptom/visionaid/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
if (M.reagents.get_reagent_amount("oculine") < 20)
|
||||
M.reagents.add_reagent("oculine", 20)
|
||||
else
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
|
||||
M << "<span class='notice'>[pick("Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")]</span>"
|
||||
return
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Voice Change
|
||||
|
||||
Very Very noticable.
|
||||
Lowers resistance considerably.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
Fatal Level.
|
||||
|
||||
Bonus
|
||||
Changes the voice of the affected mob. Causing confusion in communication.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/voice_change
|
||||
|
||||
name = "Voice Change"
|
||||
stealth = -2
|
||||
resistance = -3
|
||||
stage_speed = -3
|
||||
transmittable = -1
|
||||
level = 6
|
||||
severity = 2
|
||||
|
||||
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("Your throat hurts.", "You clear your throat.")]</span>"
|
||||
else
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
|
||||
|
||||
return
|
||||
|
||||
/datum/symptom/voice_change/End(datum/disease/advance/A)
|
||||
..()
|
||||
if(ishuman(A.affected_mob))
|
||||
var/mob/living/carbon/human/H = A.affected_mob
|
||||
H.UnsetSpecialVoice()
|
||||
return
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Vomiting
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Little transmittable.
|
||||
Medium Level.
|
||||
|
||||
Bonus
|
||||
Forces the affected mob to vomit!
|
||||
Meaning your disease can spread via
|
||||
people walking on vomit.
|
||||
Makes the affected mob lose nutrition and
|
||||
heal toxin damage.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/vomit
|
||||
|
||||
name = "Vomiting"
|
||||
stealth = -2
|
||||
resistance = -1
|
||||
stage_speed = 0
|
||||
transmittable = 1
|
||||
level = 3
|
||||
severity = 4
|
||||
|
||||
/datum/symptom/vomit/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB / 2))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("You feel nauseous.", "You feel like you're going to throw up!")]</span>"
|
||||
else
|
||||
Vomit(M)
|
||||
|
||||
return
|
||||
|
||||
/datum/symptom/vomit/proc/Vomit(mob/living/carbon/M)
|
||||
M.vomit(20)
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Vomiting Blood
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Little transmittable.
|
||||
Intense level.
|
||||
|
||||
Bonus
|
||||
Forces the affected mob to vomit blood!
|
||||
Meaning your disease can spread via
|
||||
people walking on the blood.
|
||||
Makes the affected mob lose health.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/vomit/blood
|
||||
|
||||
name = "Blood Vomiting"
|
||||
stealth = -2
|
||||
resistance = -1
|
||||
stage_speed = -1
|
||||
transmittable = 1
|
||||
level = 4
|
||||
severity = 5
|
||||
|
||||
/datum/symptom/vomit/blood/Vomit(mob/living/carbon/M)
|
||||
M.vomit(0, 1)
|
||||
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Projectile Vomiting
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Little transmittable.
|
||||
Medium Level.
|
||||
|
||||
Bonus
|
||||
As normal vomiting, except it will spread further,
|
||||
likely causing more to walk across the vomit.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/vomit/projectile
|
||||
|
||||
name = "Projectile Vomiting"
|
||||
stealth = -2
|
||||
level = 4
|
||||
|
||||
/datum/symptom/vomit/projectile/Vomit(mob/living/carbon/M)
|
||||
M.vomit(6,0,1,5,1)
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weakness
|
||||
|
||||
Slightly noticeable.
|
||||
Lowers resistance slightly.
|
||||
Decreases stage speed moderately.
|
||||
Decreases transmittablity moderately.
|
||||
Moderate Level.
|
||||
|
||||
Bonus
|
||||
Deals stamina damage to the host
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weakness
|
||||
|
||||
name = "Weakness"
|
||||
stealth = -1
|
||||
resistance = -1
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 3
|
||||
severity = 3
|
||||
|
||||
/datum/symptom/weakness/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
M << "<span class='warning'>[pick("You feel weak.", "You feel lazy.")]</span>"
|
||||
if(3, 4)
|
||||
M << "<span class='warning'><b>[pick("You feel very frail.", "You think you might faint.")]</span>"
|
||||
M.adjustStaminaLoss(15)
|
||||
else
|
||||
M << "<span class='userdanger'>[pick("You feel tremendously weak!", "Your body trembles as exhaustion creeps over you.")]</span>"
|
||||
M.adjustStaminaLoss(30)
|
||||
if(M.getStaminaLoss() > 60 && !M.stat)
|
||||
M.visible_message("<span class='warning'>[M] faints!</span>", "<span class='userdanger'>You swoon and faint...</span>")
|
||||
M.AdjustSleeping(5)
|
||||
return
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Gain
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
Intense Level.
|
||||
|
||||
Bonus
|
||||
Increases the weight gain of the mob,
|
||||
forcing it to eventually turn fat.
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weight_gain
|
||||
|
||||
name = "Weight Gain"
|
||||
stealth = -3
|
||||
resistance = -3
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 4
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/weight_gain/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("You feel blubbery.", "Your stomach hurts.")]</span>"
|
||||
else
|
||||
M.overeatduration = min(M.overeatduration + 100, 600)
|
||||
M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL)
|
||||
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Loss
|
||||
|
||||
Very Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Reduced Transmittable.
|
||||
High level.
|
||||
|
||||
Bonus
|
||||
Decreases the weight of the mob,
|
||||
forcing it to be skinny.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weight_loss
|
||||
|
||||
name = "Weight Loss"
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 3
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3, 4)
|
||||
M << "<span class='warning'>[pick("You feel hungry.", "You crave for food.")]</span>"
|
||||
else
|
||||
M << "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>"
|
||||
M.overeatduration = max(M.overeatduration - 100, 0)
|
||||
M.nutrition = max(M.nutrition - 100, 0)
|
||||
|
||||
return
|
||||
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Weight Even
|
||||
|
||||
Very Noticable.
|
||||
Decreases resistance.
|
||||
Decreases stage speed.
|
||||
Reduced transmittable.
|
||||
High level.
|
||||
|
||||
Bonus
|
||||
Causes the weight of the mob to
|
||||
be even, meaning eating isn't
|
||||
required anymore.
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/weight_even
|
||||
|
||||
name = "Weight Even"
|
||||
stealth = -3
|
||||
resistance = -2
|
||||
stage_speed = -2
|
||||
transmittable = -2
|
||||
level = 4
|
||||
|
||||
/datum/symptom/weight_even/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
M.overeatduration = 0
|
||||
M.nutrition = NUTRITION_LEVEL_WELL_FED + 50
|
||||
|
||||
return
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
Eternal Youth
|
||||
|
||||
Moderate stealth boost.
|
||||
Increases resistance tremendously.
|
||||
Increases stage speed tremendously.
|
||||
Reduces transmission tremendously.
|
||||
Critical Level.
|
||||
|
||||
BONUS
|
||||
Gives you immortality and eternal youth!!!
|
||||
Can be used to buff your virus
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/youth
|
||||
|
||||
name = "Eternal Youth"
|
||||
stealth = 3
|
||||
resistance = 4
|
||||
stage_speed = 4
|
||||
transmittable = -4
|
||||
level = 5
|
||||
|
||||
/datum/symptom/youth/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 2))
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
switch(A.stage)
|
||||
if(1)
|
||||
if(H.age > 41)
|
||||
H.age = 41
|
||||
H << "<span class='notice'>You haven't had this much energy in years!</span>"
|
||||
if(2)
|
||||
if(H.age > 36)
|
||||
H.age = 36
|
||||
H << "<span class='notice'>You're suddenly in a good mood.</span>"
|
||||
if(3)
|
||||
if(H.age > 31)
|
||||
H.age = 31
|
||||
H << "<span class='notice'>You begin to feel more lithe.</span>"
|
||||
if(4)
|
||||
if(H.age > 26)
|
||||
H.age = 26
|
||||
H << "<span class='notice'>You feel reinvigorated.</span>"
|
||||
if(5)
|
||||
if(H.age > 21)
|
||||
H.age = 21
|
||||
H << "<span class='notice'>You feel like you can take on the world!</span>"
|
||||
|
||||
return
|
||||
@@ -0,0 +1,41 @@
|
||||
/datum/disease/anxiety
|
||||
name = "Severe Anxiety"
|
||||
form = "Infection"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Ethanol"
|
||||
cures = list("ethanol")
|
||||
agent = "Excess Lepidopticides"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate butterflies."
|
||||
severity = MEDIUM
|
||||
|
||||
/datum/disease/anxiety/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2) //also changes say, see say.dm
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='notice'>You feel anxious.</span>"
|
||||
if(3)
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='notice'>Your stomach flutters.</span>"
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='notice'>You feel panicky.</span>"
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You're overtaken with panic!</span>"
|
||||
affected_mob.confused += (rand(2,3))
|
||||
if(4)
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='danger'>You feel butterflies in your stomach.</span>"
|
||||
if(prob(5))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] stumbles around in a panic.</span>", \
|
||||
"<span class='userdanger'>You have a panic attack!</span>")
|
||||
affected_mob.confused += (rand(6,8))
|
||||
affected_mob.jitteriness += (rand(6,8))
|
||||
if(prob(2))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] coughs up butterflies!</span>", \
|
||||
"<span class='userdanger'>You cough up butterflies!</span>")
|
||||
new /mob/living/simple_animal/butterfly(affected_mob.loc)
|
||||
new /mob/living/simple_animal/butterfly(affected_mob.loc)
|
||||
return
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/disease/appendicitis
|
||||
form = "Condition"
|
||||
name = "Appendicitis"
|
||||
max_stages = 3
|
||||
cure_text = "Surgery"
|
||||
agent = "Shitty Appendix"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 1
|
||||
desc = "If left untreated the subject will become very weak, and may vomit often."
|
||||
severity = "Dangerous!"
|
||||
longevity = 1000
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
spread_flags = NON_CONTAGIOUS
|
||||
visibility_flags = HIDDEN_PANDEMIC
|
||||
required_organs = list(/obj/item/organ/appendix)
|
||||
|
||||
/datum/disease/appendicitis/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if(prob(5))
|
||||
affected_mob.emote("cough")
|
||||
if(2)
|
||||
var/obj/item/organ/appendix/A = affected_mob.getorgan(/obj/item/organ/appendix)
|
||||
if(A)
|
||||
A.inflamed = 1
|
||||
A.update_icon()
|
||||
if(prob(3))
|
||||
affected_mob << "<span class='warning'>You feel a stabbing pain in your abdomen!</span>"
|
||||
affected_mob.Stun(rand(2,3))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
if(3)
|
||||
if(prob(1))
|
||||
affected_mob.vomit(95)
|
||||
@@ -0,0 +1,40 @@
|
||||
/datum/disease/beesease
|
||||
name = "Beesease"
|
||||
form = "Infection"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Sugar"
|
||||
cures = list("sugar")
|
||||
agent = "Apidae Infection"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate bees."
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/beesease/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2) //also changes say, see say.dm
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='notice'>You taste honey in your mouth.</span>"
|
||||
if(3)
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='notice'>Your stomach rumbles.</span>"
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>Your stomach stings painfully.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(4)
|
||||
if(prob(10))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] buzzes.</span>", \
|
||||
"<span class='userdanger'>Your stomach buzzes violently!</span>")
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='danger'>You feel something moving in your throat.</span>"
|
||||
if(prob(1))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] coughs up a swarm of bees!</span>", \
|
||||
"<span class='userdanger'>You cough up a swarm of bees!</span>")
|
||||
new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc)
|
||||
//if(5)
|
||||
//Plus if you die, you explode into bees
|
||||
return
|
||||
@@ -0,0 +1,59 @@
|
||||
/datum/disease/brainrot
|
||||
name = "Brainrot"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Mannitol"
|
||||
cures = list("mannitol")
|
||||
agent = "Cryptococcus Cosmosis"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
cure_chance = 15//higher chance to cure, since two reagents are required
|
||||
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR
|
||||
..()
|
||||
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(2))
|
||||
affected_mob.emote("blink")
|
||||
if(prob(2))
|
||||
affected_mob.emote("yawn")
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You don't feel like yourself.</span>"
|
||||
if(prob(5))
|
||||
affected_mob.adjustBrainLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
if(3)
|
||||
if(prob(2))
|
||||
affected_mob.emote("stare")
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now
|
||||
affected_mob.adjustBrainLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>Your try to remember something important...but can't.</span>"
|
||||
|
||||
if(4)
|
||||
if(prob(2))
|
||||
affected_mob.emote("stare")
|
||||
if(prob(2))
|
||||
affected_mob.emote("drool")
|
||||
if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now
|
||||
affected_mob.adjustBrainLoss(3)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>Strange buzzing fills your head, removing all thoughts.</span>"
|
||||
if(prob(3))
|
||||
affected_mob << "<span class='danger'>You lose consciousness...</span>"
|
||||
affected_mob.visible_message("<span class='warning'>[affected_mob] suddenly collapses</span>")
|
||||
affected_mob.Paralyse(rand(5,10))
|
||||
if(prob(1))
|
||||
affected_mob.emote("snore")
|
||||
if(prob(15))
|
||||
affected_mob.stuttering += 3
|
||||
|
||||
return
|
||||
@@ -0,0 +1,66 @@
|
||||
/datum/disease/cold
|
||||
name = "The Cold"
|
||||
max_stages = 3
|
||||
spread_flags = AIRBORNE
|
||||
cure_text = "Rest & Spaceacillin"
|
||||
cures = list("spaceacillin")
|
||||
agent = "XY-rhinovirus"
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
permeability_mod = 0.5
|
||||
desc = "If left untreated the subject will contract the flu."
|
||||
severity = MINOR
|
||||
|
||||
/datum/disease/cold/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
/*
|
||||
if(affected_mob.sleeping && prob(40)) //removed until sleeping is fixed
|
||||
affected_mob << "\blue You feel better."
|
||||
cure()
|
||||
return
|
||||
*/
|
||||
if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if(prob(1) && prob(5))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your throat feels sore.</span>"
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Mucous runs down the back of your throat.</span>"
|
||||
if(3)
|
||||
/*
|
||||
if(affected_mob.sleeping && prob(25)) //removed until sleeping is fixed
|
||||
affected_mob << "\blue You feel better."
|
||||
cure()
|
||||
return
|
||||
*/
|
||||
if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if(prob(1) && prob(1))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your throat feels sore.</span>"
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Mucous runs down the back of your throat.</span>"
|
||||
if(prob(1) && prob(50))
|
||||
if(!affected_mob.resistances.Find(/datum/disease/flu))
|
||||
var/datum/disease/Flu = new /datum/disease/flu(0)
|
||||
affected_mob.ContractDisease(Flu)
|
||||
cure()
|
||||
@@ -0,0 +1,39 @@
|
||||
/datum/disease/cold9
|
||||
name = "The Cold"
|
||||
max_stages = 3
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Common Cold Anti-bodies & Spaceacillin"
|
||||
cures = list("spaceacillin")
|
||||
agent = "ICE9-rhinovirus"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
desc = "If left untreated the subject will slow, as if partly frozen."
|
||||
severity = MEDIUM
|
||||
|
||||
/datum/disease/cold9/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
affected_mob.bodytemperature -= 10
|
||||
if(prob(1) && prob(10))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your throat feels sore.</span>"
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='danger'>You feel stiff.</span>"
|
||||
if(3)
|
||||
affected_mob.bodytemperature -= 20
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your throat feels sore.</span>"
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='danger'>You feel stiff.</span>"
|
||||
@@ -0,0 +1,74 @@
|
||||
/datum/disease/dnaspread
|
||||
name = "Space Retrovirus"
|
||||
max_stages = 4
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Mutadone"
|
||||
cures = list("mutadone")
|
||||
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
|
||||
agent = "S4E1 retrovirus"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
var/datum/dna/original_dna = null
|
||||
var/transformed = 0
|
||||
desc = "This disease transplants the genetic code of the initial vector into new hosts."
|
||||
severity = MEDIUM
|
||||
|
||||
|
||||
/datum/disease/dnaspread/stage_act()
|
||||
..()
|
||||
if(!affected_mob.dna)
|
||||
cure()
|
||||
if(NOTRANSSTING in affected_mob.dna.species.specflags) //Only species that can be spread by transformation sting can be spread by the retrovirus
|
||||
cure()
|
||||
|
||||
if(!strain_data["dna"])
|
||||
//Absorbs the target DNA.
|
||||
strain_data["dna"] = new affected_mob.dna.type
|
||||
affected_mob.dna.copy_dna(strain_data["dna"])
|
||||
src.carrier = 1
|
||||
src.stage = 4
|
||||
return
|
||||
|
||||
switch(stage)
|
||||
if(2 || 3) //Pretend to be a cold and give time to spread.
|
||||
if(prob(8))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(8))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your muscles ache.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.take_organ_damage(1)
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(4)
|
||||
if(!transformed && !carrier)
|
||||
//Save original dna for when the disease is cured.
|
||||
original_dna = new affected_mob.dna.type
|
||||
affected_mob.dna.copy_dna(original_dna)
|
||||
|
||||
affected_mob << "<span class='danger'>You don't feel like yourself..</span>"
|
||||
var/datum/dna/transform_dna = strain_data["dna"]
|
||||
|
||||
transform_dna.transfer_identity(affected_mob, transfer_SE = 1)
|
||||
affected_mob.real_name = affected_mob.dna.real_name
|
||||
affected_mob.updateappearance(mutcolor_update=1)
|
||||
affected_mob.domutcheck()
|
||||
|
||||
transformed = 1
|
||||
carrier = 1 //Just chill out at stage 4
|
||||
|
||||
return
|
||||
|
||||
/datum/disease/dnaspread/Destroy()
|
||||
if (original_dna && transformed && affected_mob)
|
||||
original_dna.transfer_identity(affected_mob, transfer_SE = 1)
|
||||
affected_mob.real_name = affected_mob.dna.real_name
|
||||
affected_mob.updateappearance(mutcolor_update=1)
|
||||
affected_mob.domutcheck()
|
||||
|
||||
affected_mob << "<span class='notice'>You feel more like yourself.</span>"
|
||||
return ..()
|
||||
@@ -0,0 +1,32 @@
|
||||
/datum/disease/fake_gbs
|
||||
name = "GBS"
|
||||
max_stages = 5
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Synaptizine & Sulfur"
|
||||
cures = list("synaptizine","sulfur")
|
||||
agent = "Gravitokinetic Bipotential SADS-"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
desc = "If left untreated death will occur."
|
||||
severity = BIOHAZARD
|
||||
|
||||
/datum/disease/fake_gbs/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(3)
|
||||
if(prob(5))
|
||||
affected_mob.emote("cough")
|
||||
else if(prob(5))
|
||||
affected_mob.emote("gasp")
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='danger'>You're starting to feel very weak...</span>"
|
||||
if(4)
|
||||
if(prob(10))
|
||||
affected_mob.emote("cough")
|
||||
|
||||
if(5)
|
||||
if(prob(10))
|
||||
affected_mob.emote("cough")
|
||||
@@ -0,0 +1,54 @@
|
||||
/datum/disease/flu
|
||||
name = "The Flu"
|
||||
max_stages = 3
|
||||
spread_text = "Airborne"
|
||||
cure_text = "Spaceacillin"
|
||||
cures = list("spaceacillin")
|
||||
cure_chance = 10
|
||||
agent = "H13N1 flu virion"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
permeability_mod = 0.75
|
||||
desc = "If left untreated the subject will feel quite unwell."
|
||||
severity = MEDIUM
|
||||
|
||||
/datum/disease/flu/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(affected_mob.lying && prob(20))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
stage--
|
||||
return
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your muscles ache.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.take_organ_damage(1)
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
|
||||
if(3)
|
||||
if(affected_mob.lying && prob(15))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
stage--
|
||||
return
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your muscles ache.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.take_organ_damage(1)
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
return
|
||||
@@ -0,0 +1,36 @@
|
||||
/datum/disease/fluspanish
|
||||
name = "Spanish inquisition Flu"
|
||||
max_stages = 3
|
||||
spread_text = "Airborne"
|
||||
cure_text = "Spaceacillin & Anti-bodies to the common flu"
|
||||
cures = list("spaceacillin")
|
||||
cure_chance = 10
|
||||
agent = "1nqu1s1t10n flu virion"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 0.75
|
||||
desc = "If left untreated the subject will burn to death for being a heretic."
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/fluspanish/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
affected_mob.bodytemperature += 10
|
||||
if(prob(5))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(5))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>You're burning in your own skin!</span>"
|
||||
affected_mob.take_organ_damage(0,5)
|
||||
|
||||
if(3)
|
||||
affected_mob.bodytemperature += 20
|
||||
if(prob(5))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(5))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='danger'>You're burning in your own skin!</span>"
|
||||
affected_mob.take_organ_damage(0,5)
|
||||
return
|
||||
@@ -0,0 +1,41 @@
|
||||
/datum/disease/gbs
|
||||
name = "GBS"
|
||||
max_stages = 5
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Synaptizine & Sulfur"
|
||||
cures = list("synaptizine","sulfur")
|
||||
cure_chance = 15//higher chance to cure, since two reagents are required
|
||||
agent = "Gravitokinetic Bipotential SADS+"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
|
||||
permeability_mod = 1
|
||||
severity = BIOHAZARD
|
||||
|
||||
/datum/disease/gbs/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(45))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(3)
|
||||
if(prob(5))
|
||||
affected_mob.emote("cough")
|
||||
else if(prob(5))
|
||||
affected_mob.emote("gasp")
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='danger'>You're starting to feel very weak...</span>"
|
||||
if(4)
|
||||
if(prob(10))
|
||||
affected_mob.emote("cough")
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(5)
|
||||
affected_mob << "<span class='danger'>Your body feels as if it's trying to rip itself open...</span>"
|
||||
if(prob(50))
|
||||
affected_mob.gib()
|
||||
else
|
||||
return
|
||||
@@ -0,0 +1,63 @@
|
||||
/datum/disease/magnitis
|
||||
name = "Magnitis"
|
||||
max_stages = 4
|
||||
spread_text = "Airborne"
|
||||
cure_text = "Iron"
|
||||
cures = list("iron")
|
||||
agent = "Fukkos Miracos"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
|
||||
permeability_mod = 0.75
|
||||
desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field."
|
||||
severity = MEDIUM
|
||||
|
||||
/datum/disease/magnitis/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You feel a slight shock course through your body.</span>"
|
||||
if(prob(2))
|
||||
for(var/obj/M in orange(2,affected_mob))
|
||||
if(!M.anchored && (M.flags & CONDUCT))
|
||||
step_towards(M,affected_mob)
|
||||
for(var/mob/living/silicon/S in orange(2,affected_mob))
|
||||
if(istype(S, /mob/living/silicon/ai)) continue
|
||||
step_towards(S,affected_mob)
|
||||
if(3)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You feel a strong shock course through your body.</span>"
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You feel like clowning around.</span>"
|
||||
if(prob(4))
|
||||
for(var/obj/M in orange(4,affected_mob))
|
||||
if(!M.anchored && (M.flags & CONDUCT))
|
||||
var/i
|
||||
var/iter = rand(1,2)
|
||||
for(i=0,i<iter,i++)
|
||||
step_towards(M,affected_mob)
|
||||
for(var/mob/living/silicon/S in orange(4,affected_mob))
|
||||
if(istype(S, /mob/living/silicon/ai)) continue
|
||||
var/i
|
||||
var/iter = rand(1,2)
|
||||
for(i=0,i<iter,i++)
|
||||
step_towards(S,affected_mob)
|
||||
if(4)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You feel a powerful shock course through your body.</span>"
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You query upon the nature of miracles.</span>"
|
||||
if(prob(8))
|
||||
for(var/obj/M in orange(6,affected_mob))
|
||||
if(!M.anchored && (M.flags & CONDUCT))
|
||||
var/i
|
||||
var/iter = rand(1,3)
|
||||
for(i=0,i<iter,i++)
|
||||
step_towards(M,affected_mob)
|
||||
for(var/mob/living/silicon/S in orange(6,affected_mob))
|
||||
if(istype(S, /mob/living/silicon/ai)) continue
|
||||
var/i
|
||||
var/iter = rand(1,3)
|
||||
for(i=0,i<iter,i++)
|
||||
step_towards(S,affected_mob)
|
||||
return
|
||||
@@ -0,0 +1,25 @@
|
||||
/datum/disease/pierrot_throat
|
||||
name = "Pierrot's Throat"
|
||||
max_stages = 4
|
||||
spread_text = "Airborne"
|
||||
cure_text = "Banana products, especially banana bread."
|
||||
cures = list("banana")
|
||||
cure_chance = 75
|
||||
agent = "H0NI<42 Virus"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 0.75
|
||||
desc = "If left untreated the subject will probably drive others to insanity."
|
||||
severity = MEDIUM
|
||||
longevity = 400
|
||||
|
||||
/datum/disease/pierrot_throat/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if(prob(10)) affected_mob << "<span class='danger'>You feel a little silly.</span>"
|
||||
if(2)
|
||||
if(prob(10)) affected_mob << "<span class='danger'>You start seeing rainbows.</span>"
|
||||
if(3)
|
||||
if(prob(10)) affected_mob << "<span class='danger'>Your thoughts are interrupted by a loud <b>HONK!</b></span>"
|
||||
if(4)
|
||||
if(prob(5)) affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) )
|
||||
@@ -0,0 +1,83 @@
|
||||
/datum/disease/dna_retrovirus
|
||||
name = "Retrovirus"
|
||||
max_stages = 4
|
||||
spread_text = "Contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Rest or an injection of mutadone"
|
||||
cure_chance = 6
|
||||
agent = ""
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly."
|
||||
severity = DANGEROUS
|
||||
permeability_mod = 0.4
|
||||
stage_prob = 2
|
||||
var/SE
|
||||
var/UI
|
||||
var/restcure = 0
|
||||
|
||||
|
||||
/datum/disease/dna_retrovirus/New()
|
||||
..()
|
||||
agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]"
|
||||
if(prob(40))
|
||||
cures = list("mutadone")
|
||||
else
|
||||
restcure = 1
|
||||
|
||||
|
||||
/datum/disease/dna_retrovirus/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if(restcure)
|
||||
if(affected_mob.lying && prob(30))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if (prob(8))
|
||||
affected_mob << "<span class='danger'>Your head hurts.</span>"
|
||||
if (prob(9))
|
||||
affected_mob << "You feel a tingling sensation in your chest."
|
||||
if (prob(9))
|
||||
affected_mob << "<span class='danger'>You feel angry.</span>"
|
||||
if(2)
|
||||
if(restcure)
|
||||
if(affected_mob.lying && prob(20))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if (prob(8))
|
||||
affected_mob << "<span class='danger'>Your skin feels loose.</span>"
|
||||
if (prob(10))
|
||||
affected_mob << "You feel very strange."
|
||||
if (prob(4))
|
||||
affected_mob << "<span class='danger'>You feel a stabbing pain in your head!</span>"
|
||||
affected_mob.Paralyse(2)
|
||||
if (prob(4))
|
||||
affected_mob << "<span class='danger'>Your stomach churns.</span>"
|
||||
if(3)
|
||||
if(restcure)
|
||||
if(affected_mob.lying && prob(20))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if (prob(10))
|
||||
affected_mob << "<span class='danger'>Your entire body vibrates.</span>"
|
||||
|
||||
if (prob(35))
|
||||
if(prob(50))
|
||||
scramble_dna(affected_mob, 1, 0, rand(15,45))
|
||||
else
|
||||
scramble_dna(affected_mob, 0, 1, rand(15,45))
|
||||
|
||||
if(4)
|
||||
if(restcure)
|
||||
if(affected_mob.lying && prob(5))
|
||||
affected_mob << "<span class='notice'>You feel better.</span>"
|
||||
cure()
|
||||
return
|
||||
if (prob(60))
|
||||
if(prob(50))
|
||||
scramble_dna(affected_mob, 1, 0, rand(50,75))
|
||||
else
|
||||
scramble_dna(affected_mob, 0, 1, rand(50,75))
|
||||
@@ -0,0 +1,52 @@
|
||||
/datum/disease/rhumba_beat
|
||||
name = "The Rhumba Beat"
|
||||
max_stages = 5
|
||||
spread_text = "On contact"
|
||||
spread_flags = CONTACT_GENERAL
|
||||
cure_text = "Chick Chicky Boom!"
|
||||
cures = list("plasma")
|
||||
agent = "Unknown"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
permeability_mod = 1
|
||||
severity = BIOHAZARD
|
||||
|
||||
/datum/disease/rhumba_beat/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
if(2)
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
if(prob(45))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(1))
|
||||
affected_mob << "<span class='danger'>You feel strange...</span>"
|
||||
if(3)
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='danger'>You feel the urge to dance...</span>"
|
||||
else if(prob(5))
|
||||
affected_mob.emote("gasp")
|
||||
else if(prob(10))
|
||||
affected_mob << "<span class='danger'>You feel the need to chick chicky boom...</span>"
|
||||
if(4)
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
if(prob(10))
|
||||
affected_mob.emote("gasp")
|
||||
affected_mob << "<span class='danger'>You feel a burning beat inside...</span>"
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(5)
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
affected_mob << "<span class='danger'>Your body is unable to contain the Rhumba Beat...</span>"
|
||||
if(prob(50))
|
||||
affected_mob.gib()
|
||||
else
|
||||
return
|
||||
@@ -0,0 +1,242 @@
|
||||
/datum/disease/transformation
|
||||
name = "Transformation"
|
||||
max_stages = 5
|
||||
spread_text = "Acute"
|
||||
spread_flags = SPECIAL
|
||||
cure_text = "A coder's love (theoretical)."
|
||||
agent = "Shenanigans"
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
severity = HARMFUL
|
||||
stage_prob = 10
|
||||
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
|
||||
disease_flags = CURABLE
|
||||
var/list/stage1 = list("You feel unremarkable.")
|
||||
var/list/stage2 = list("You feel boring.")
|
||||
var/list/stage3 = list("You feel utterly plain.")
|
||||
var/list/stage4 = list("You feel white bread.")
|
||||
var/list/stage5 = list("Oh the humanity!")
|
||||
var/new_form = /mob/living/carbon/human
|
||||
|
||||
/datum/disease/transformation/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if (prob(stage_prob) && stage1)
|
||||
affected_mob << pick(stage1)
|
||||
if(2)
|
||||
if (prob(stage_prob) && stage2)
|
||||
affected_mob << pick(stage2)
|
||||
if(3)
|
||||
if (prob(stage_prob*2) && stage3)
|
||||
affected_mob << pick(stage3)
|
||||
if(4)
|
||||
if (prob(stage_prob*2) && stage4)
|
||||
affected_mob << pick(stage4)
|
||||
if(5)
|
||||
do_disease_transformation(affected_mob)
|
||||
|
||||
/datum/disease/transformation/proc/do_disease_transformation(mob/living/affected_mob)
|
||||
if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD)
|
||||
if(stage5)
|
||||
affected_mob << pick(stage5)
|
||||
if(jobban_isbanned(affected_mob, new_form))
|
||||
affected_mob.death(1)
|
||||
return
|
||||
if(affected_mob.notransform)
|
||||
return
|
||||
affected_mob.notransform = 1
|
||||
for(var/obj/item/W in affected_mob)
|
||||
if(istype(W, /obj/item/weapon/implant))
|
||||
qdel(W)
|
||||
continue
|
||||
W.layer = initial(W.layer)
|
||||
W.loc = affected_mob.loc
|
||||
W.dropped(affected_mob)
|
||||
var/mob/living/new_mob = new new_form(affected_mob.loc)
|
||||
if(istype(new_mob))
|
||||
new_mob.a_intent = "harm"
|
||||
if(affected_mob.mind)
|
||||
affected_mob.mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = affected_mob.key
|
||||
qdel(affected_mob)
|
||||
|
||||
|
||||
|
||||
/datum/disease/transformation/jungle_fever
|
||||
name = "Jungle Fever"
|
||||
cure_text = "Bananas"
|
||||
cures = list("banana")
|
||||
spread_text = "Monkey Bites"
|
||||
spread_flags = SPECIAL
|
||||
viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human)
|
||||
permeability_mod = 1
|
||||
cure_chance = 1
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
longevity = 30
|
||||
desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey."
|
||||
severity = BIOHAZARD
|
||||
stage_prob = 4
|
||||
visibility_flags = 0
|
||||
agent = "Kongey Vibrion M-909"
|
||||
new_form = /mob/living/carbon/monkey
|
||||
|
||||
stage1 = null
|
||||
stage2 = null
|
||||
stage3 = null
|
||||
stage4 = list("<span class='warning'>Your back hurts.</span>", "<span class='warning'>You breathe through your mouth.</span>",
|
||||
"<span class='warning'>You have a craving for bananas.</span>", "<span class='warning'>Your mind feels clouded.</span>")
|
||||
stage5 = list("<span class='warning'>You feel like monkeying around.</span>")
|
||||
|
||||
/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob)
|
||||
if(!ismonkey(affected_mob))
|
||||
ticker.mode.add_monkey(affected_mob.mind)
|
||||
affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/disease/transformation/jungle_fever/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='notice'>Your [pick("back", "arm", "leg", "elbow", "head")] itches.</span>"
|
||||
if(3)
|
||||
if(prob(4))
|
||||
affected_mob << "<span class='danger'>You feel a stabbing pain in your head.</span>"
|
||||
affected_mob.confused += 10
|
||||
if(4)
|
||||
if(prob(3))
|
||||
affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh."))
|
||||
|
||||
/datum/disease/transformation/jungle_fever/cure()
|
||||
ticker.mode.remove_monkey(affected_mob.mind)
|
||||
..()
|
||||
|
||||
|
||||
/datum/disease/transformation/robot
|
||||
|
||||
name = "Robotic Transformation"
|
||||
cure_text = "An injection of copper."
|
||||
cures = list("copper")
|
||||
cure_chance = 5
|
||||
agent = "R2D2 Nanomachines"
|
||||
desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg."
|
||||
severity = DANGEROUS
|
||||
visibility_flags = 0
|
||||
stage1 = null
|
||||
stage2 = list("Your joints feel stiff.", "<span class='danger'>Beep...boop..</span>")
|
||||
stage3 = list("<span class='danger'>Your joints feel very stiff.</span>", "Your skin feels loose.", "<span class='danger'>You can feel something move...inside.</span>")
|
||||
stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/silicon/robot
|
||||
|
||||
|
||||
/datum/disease/transformation/robot/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(3)
|
||||
if (prob(8))
|
||||
affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"))
|
||||
if (prob(4))
|
||||
affected_mob << "<span class='danger'>You feel a stabbing pain in your head.</span>"
|
||||
affected_mob.Paralyse(2)
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."))
|
||||
|
||||
|
||||
/datum/disease/transformation/xeno
|
||||
|
||||
name = "Xenomorph Transformation"
|
||||
cure_text = "Spaceacillin & Glycerol"
|
||||
cures = list("spaceacillin", "glycerol")
|
||||
cure_chance = 5
|
||||
agent = "Rip-LEY Alien Microbes"
|
||||
desc = "This disease changes the victim into a xenomorph."
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = null
|
||||
stage2 = list("Your throat feels scratchy.", "<span class='danger'>Kill...</span>")
|
||||
stage3 = list("<span class='danger'>Your throat feels very scratchy.</span>", "Your skin feels tight.", "<span class='danger'>You can feel something move...inside.</span>")
|
||||
stage4 = list("<span class='danger'>Your skin feels very tight.</span>", "<span class='danger'>Your blood boils!</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/carbon/alien/humanoid/hunter
|
||||
|
||||
/datum/disease/transformation/xeno/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(3)
|
||||
if (prob(4))
|
||||
affected_mob << "<span class='danger'>You feel a stabbing pain in your head.</span>"
|
||||
affected_mob.Paralyse(2)
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"))
|
||||
|
||||
|
||||
/datum/disease/transformation/slime
|
||||
name = "Advanced Mutation Transformation"
|
||||
cure_text = "frost oil"
|
||||
cures = list("frostoil")
|
||||
cure_chance = 80
|
||||
agent = "Advanced Mutation Toxin"
|
||||
desc = "This highly concentrated extract converts anything into more of itself."
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("You don't feel very well.")
|
||||
stage2 = list("Your skin feels a little slimy.")
|
||||
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
|
||||
stage4 = list("<span class='danger'>You are turning into a slime.</span>")
|
||||
stage5 = list("<span class='danger'>You have become a slime.</span>")
|
||||
new_form = /mob/living/simple_animal/slime
|
||||
|
||||
/datum/disease/transformation/slime/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(1)
|
||||
if(ishuman(affected_mob) && affected_mob.dna && affected_mob.dna.species.id == "slime")
|
||||
stage = 5
|
||||
if(3)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/human/human = affected_mob
|
||||
if(human.dna.species.id != "slime")
|
||||
human.set_species(/datum/species/jelly/slime)
|
||||
|
||||
/datum/disease/transformation/corgi
|
||||
name = "The Barkening"
|
||||
cure_text = "Death"
|
||||
cures = list("adminordrazine")
|
||||
agent = "Fell Doge Majicks"
|
||||
desc = "This disease transforms the victim into a corgi."
|
||||
visibility_flags = 0
|
||||
stage1 = list("BARK.")
|
||||
stage2 = list("You feel the need to wear silly hats.")
|
||||
stage3 = list("<span class='danger'>Must... eat... chocolate....</span>", "<span class='danger'>YAP</span>")
|
||||
stage4 = list("<span class='danger'>Visions of washing machines assail your mind!</span>")
|
||||
stage5 = list("<span class='danger'>AUUUUUU!!!</span>")
|
||||
new_form = /mob/living/simple_animal/pet/dog/corgi
|
||||
|
||||
/datum/disease/transformation/corgi/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(3)
|
||||
if (prob(8))
|
||||
affected_mob.say(pick("YAP", "Woof!"))
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("Bark!", "AUUUUUU"))
|
||||
|
||||
/datum/disease/transformation/morph
|
||||
name = "Gluttony's Blessing"
|
||||
cure_text = "nothing"
|
||||
cures = list("adminordrazine")
|
||||
agent = "Gluttony's Blessing"
|
||||
desc = "A 'gift' from somewhere terrible."
|
||||
stage_prob = 20
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your stomach rumbles.")
|
||||
stage2 = list("Your skin feels saggy.")
|
||||
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
|
||||
stage4 = list("<span class='danger'>You're ravenous.</span>")
|
||||
stage5 = list("<span class='danger'>You have become a morph.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/morph
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/disease/tuberculosis
|
||||
name = "Fungal tuberculosis"
|
||||
max_stages = 5
|
||||
spread_text = "Airborne"
|
||||
cure_text = "Spaceacillin & salbutamol"
|
||||
cures = list("spaceacillin", "salbutamol")
|
||||
agent = "Fungal Tubercle bacillus Cosmosis"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
cure_chance = 5//like hell are you getting out of hell
|
||||
desc = "A rare highly transmittable virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue."
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/tuberculosis/stage_act() //it begins
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(2))
|
||||
affected_mob.emote("cough")
|
||||
affected_mob << "<span class='danger'>Your chest hurts.</span>"
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>Your stomach violently rumbles!</span>"
|
||||
if(prob(5))
|
||||
affected_mob << "<span class='danger'>You feel a cold sweat form.</span>"
|
||||
if(4)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='userdanger'>You see four of everything</span>"
|
||||
affected_mob.Dizzy(5)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='danger'>You feel a sharp pain from your lower chest!</span>"
|
||||
affected_mob.adjustOxyLoss(5)
|
||||
affected_mob.emote("gasp")
|
||||
if(prob(10))
|
||||
affected_mob << "<span class='danger'>You feel air escape from your lungs painfully.</span>"
|
||||
affected_mob.adjustOxyLoss(25)
|
||||
affected_mob.emote("gasp")
|
||||
if(5)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='userdanger'>[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]</span>"
|
||||
affected_mob.adjustStaminaLoss(70)
|
||||
if(prob(10))
|
||||
affected_mob.adjustStaminaLoss(100)
|
||||
affected_mob.visible_message("<span class='warning'>[affected_mob] faints!</span>", "<span class='userdanger'>You surrender yourself and feel at peace...</span>")
|
||||
affected_mob.AdjustSleeping(5)
|
||||
if(prob(2))
|
||||
affected_mob << "<span class='userdanger'>You feel your mind relax and your thoughts drift!</span>"
|
||||
affected_mob.confused = min(100, affected_mob.confused + 8)
|
||||
if(prob(10))
|
||||
affected_mob.vomit(20)
|
||||
if(prob(3))
|
||||
affected_mob << "<span class='warning'><i>[pick("Your stomach silently rumbles...", "Your stomach seizes up and falls limp, muscles dead and lifeless.", "You could eat a crayon")]</i></span>"
|
||||
affected_mob.overeatduration = max(affected_mob.overeatduration - 100, 0)
|
||||
affected_mob.nutrition = max(affected_mob.nutrition - 100, 0)
|
||||
if(prob(15))
|
||||
affected_mob << "<span class='danger'>[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...")]</span>"
|
||||
affected_mob.bodytemperature += 40
|
||||
return
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/datum/disease/wizarditis
|
||||
name = "Wizarditis"
|
||||
max_stages = 4
|
||||
spread_text = "Airborne"
|
||||
cure_text = "The Manly Dorf"
|
||||
cures = list("manlydorf")
|
||||
cure_chance = 100
|
||||
agent = "Rincewindus Vulgaris"
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
|
||||
permeability_mod = 0.75
|
||||
desc = "Some speculate, that this virus is the cause of Wizard Federation existance. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
|
||||
severity = HARMFUL
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
|
||||
/*
|
||||
BIRUZ BENNAR
|
||||
SCYAR NILA - teleport
|
||||
NEC CANTIO - dis techno
|
||||
EI NATH - shocking grasp
|
||||
AULIE OXIN FIERA - knock
|
||||
TARCOL MINTI ZHERI - forcewall
|
||||
STI KALY - blind
|
||||
*/
|
||||
|
||||
/datum/disease/wizarditis/stage_act()
|
||||
..()
|
||||
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"))
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob << "<span class='danger'>You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].</span>"
|
||||
|
||||
|
||||
if(3)
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"))
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob << "<span class='danger'>You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].</span>"
|
||||
|
||||
if(4)
|
||||
|
||||
if(prob(1))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"))
|
||||
return
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob << "<span class='danger'>You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].</span>"
|
||||
spawn_wizard_clothes(50)
|
||||
if(prob(1)&&prob(1))
|
||||
teleport()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0)
|
||||
if(istype(affected_mob, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = affected_mob
|
||||
if(prob(chance))
|
||||
if(!istype(H.head, /obj/item/clothing/head/wizard))
|
||||
if(!H.unEquip(H.head))
|
||||
qdel(H.head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head)
|
||||
return
|
||||
if(prob(chance))
|
||||
if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe))
|
||||
if(!H.unEquip(H.wear_suit))
|
||||
qdel(H.wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit)
|
||||
return
|
||||
if(prob(chance))
|
||||
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
|
||||
if(!H.unEquip(H.shoes))
|
||||
qdel(H.shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
|
||||
return
|
||||
else
|
||||
var/mob/living/carbon/H = affected_mob
|
||||
if(prob(chance))
|
||||
if(!istype(H.r_hand, /obj/item/weapon/staff))
|
||||
H.drop_r_hand()
|
||||
H.put_in_r_hand( new /obj/item/weapon/staff(H) )
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
|
||||
/datum/disease/wizarditis/proc/teleport()
|
||||
var/list/theareas = get_areas_in_range(80, affected_mob)
|
||||
for(var/area/space/S in theareas)
|
||||
theareas -= S
|
||||
|
||||
if(!theareas||!theareas.len)
|
||||
return
|
||||
|
||||
var/area/thearea = pick(theareas)
|
||||
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(T.z != affected_mob.z) continue
|
||||
if(T.name == "space") continue
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
|
||||
if(!L)
|
||||
return
|
||||
|
||||
affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!")
|
||||
affected_mob.loc = pick(L)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,361 @@
|
||||
|
||||
/////////////////////////// DNA DATUM
|
||||
/datum/dna
|
||||
var/unique_enzymes
|
||||
var/struc_enzymes
|
||||
var/uni_identity
|
||||
var/blood_type
|
||||
var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man)
|
||||
var/list/features = list("FFF") //first value is mutant color
|
||||
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
|
||||
var/list/mutations = list() //All mutations are from now on here
|
||||
var/list/temporary_mutations = list() //Timers for temporary mutations
|
||||
var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
|
||||
var/mob/living/carbon/holder
|
||||
|
||||
/datum/dna/New(mob/living/carbon/new_holder)
|
||||
if(new_holder)
|
||||
holder = new_holder
|
||||
|
||||
/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
|
||||
destination.dna.unique_enzymes = unique_enzymes
|
||||
destination.dna.uni_identity = uni_identity
|
||||
destination.dna.blood_type = blood_type
|
||||
destination.set_species(species.type, icon_update=0)
|
||||
destination.dna.features = features.Copy()
|
||||
destination.dna.real_name = real_name
|
||||
destination.dna.temporary_mutations = temporary_mutations.Copy()
|
||||
if(transfer_SE)
|
||||
destination.dna.struc_enzymes = struc_enzymes
|
||||
|
||||
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
||||
new_dna.unique_enzymes = unique_enzymes
|
||||
new_dna.struc_enzymes = struc_enzymes
|
||||
new_dna.uni_identity = uni_identity
|
||||
new_dna.blood_type = blood_type
|
||||
new_dna.features = features.Copy()
|
||||
new_dna.species = new species.type
|
||||
new_dna.real_name = real_name
|
||||
new_dna.mutations = mutations.Copy()
|
||||
|
||||
/datum/dna/proc/add_mutation(mutation_name)
|
||||
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
||||
HM.on_acquiring(holder)
|
||||
|
||||
/datum/dna/proc/remove_mutation(mutation_name)
|
||||
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
||||
HM.on_losing(holder)
|
||||
|
||||
/datum/dna/proc/check_mutation(mutation_name)
|
||||
var/datum/mutation/human/HM = mutations_list[mutation_name]
|
||||
return mutations.Find(HM)
|
||||
|
||||
/datum/dna/proc/remove_all_mutations()
|
||||
remove_mutation_group(mutations)
|
||||
|
||||
/datum/dna/proc/remove_mutation_group(list/group)
|
||||
if(!group)
|
||||
return
|
||||
for(var/datum/mutation/human/HM in group)
|
||||
HM.force_lose(holder)
|
||||
|
||||
/datum/dna/proc/generate_uni_identity()
|
||||
. = ""
|
||||
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
|
||||
|
||||
L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2)
|
||||
if(ishuman(holder))
|
||||
var/mob/living/carbon/human/H = holder
|
||||
if(!hair_styles_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list)
|
||||
L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len)
|
||||
L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color)
|
||||
if(!facial_hair_styles_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, facial_hair_styles_list, facial_hair_styles_male_list, facial_hair_styles_female_list)
|
||||
L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len)
|
||||
L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
|
||||
L[DNA_SKIN_TONE_BLOCK] = construct_block(skin_tones.Find(H.skin_tone), skin_tones.len)
|
||||
L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
|
||||
|
||||
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
||||
if(L[i])
|
||||
. += L[i]
|
||||
else
|
||||
. += random_string(DNA_BLOCK_SIZE,hex_characters)
|
||||
return .
|
||||
|
||||
/datum/dna/proc/generate_struc_enzymes()
|
||||
var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS)
|
||||
var/result = ""
|
||||
for(var/datum/mutation/human/A in good_mutations + bad_mutations + not_good_mutations)
|
||||
if(A.name == RACEMUT && ismonkey(holder))
|
||||
sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE)
|
||||
mutations |= A
|
||||
else
|
||||
sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6"))
|
||||
|
||||
for(var/B in sorting)
|
||||
result += B
|
||||
return result
|
||||
|
||||
/datum/dna/proc/generate_unique_enzymes()
|
||||
. = ""
|
||||
if(istype(holder))
|
||||
real_name = holder.real_name
|
||||
. += md5(holder.real_name)
|
||||
else
|
||||
. += random_string(DNA_UNIQUE_ENZYMES_LEN, hex_characters)
|
||||
return .
|
||||
|
||||
/datum/dna/proc/update_ui_block(blocknumber)
|
||||
if(!blocknumber || !ishuman(holder))
|
||||
return
|
||||
var/mob/living/carbon/human/H = holder
|
||||
switch(blocknumber)
|
||||
if(DNA_HAIR_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color))
|
||||
if(DNA_FACIAL_HAIR_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
|
||||
if(DNA_SKIN_TONE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(skin_tones.Find(H.skin_tone), skin_tones.len))
|
||||
if(DNA_EYE_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
|
||||
if(DNA_GENDER_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2))
|
||||
if(DNA_FACIAL_HAIR_STYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(facial_hair_styles_list.Find(H.facial_hair_style), facial_hair_styles_list.len))
|
||||
if(DNA_HAIR_STYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len))
|
||||
|
||||
/datum/dna/proc/mutations_say_mods(message)
|
||||
if(message)
|
||||
for(var/datum/mutation/human/M in mutations)
|
||||
message = M.say_mod(message)
|
||||
return message
|
||||
|
||||
/datum/dna/proc/mutations_get_spans()
|
||||
var/list/spans = list()
|
||||
for(var/datum/mutation/human/M in mutations)
|
||||
spans |= M.get_spans()
|
||||
return spans
|
||||
|
||||
/datum/dna/proc/species_get_spans()
|
||||
var/list/spans = list()
|
||||
if(species)
|
||||
spans |= species.get_spans()
|
||||
return spans
|
||||
|
||||
|
||||
/datum/dna/proc/is_same_as(datum/dna/D)
|
||||
if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
|
||||
if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//used to update dna UI, UE, and dna.real_name.
|
||||
/datum/dna/proc/update_dna_identity()
|
||||
uni_identity = generate_uni_identity()
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
|
||||
/datum/dna/proc/initialize_dna(newblood_type)
|
||||
if(newblood_type)
|
||||
blood_type = newblood_type
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
uni_identity = generate_uni_identity()
|
||||
struc_enzymes = generate_struc_enzymes()
|
||||
features = random_features()
|
||||
|
||||
|
||||
|
||||
/////////////////////////// DNA MOB-PROCS //////////////////////
|
||||
|
||||
/mob/proc/set_species(datum/species/mrace, icon_update = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
|
||||
if(mrace && has_dna())
|
||||
dna.species.on_species_loss(src)
|
||||
var/old_species = dna.species
|
||||
if(ispath(mrace))
|
||||
dna.species = new mrace()
|
||||
else
|
||||
dna.species = mrace
|
||||
dna.species.on_species_gain(src, old_species)
|
||||
|
||||
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
|
||||
..()
|
||||
if(icon_update)
|
||||
update_body()
|
||||
update_hair()
|
||||
update_body_parts()
|
||||
update_mutations_overlay()// no lizard with human hulk overlay please.
|
||||
|
||||
|
||||
/mob/proc/has_dna()
|
||||
return
|
||||
|
||||
/mob/living/carbon/has_dna()
|
||||
return dna
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures)
|
||||
|
||||
if(newfeatures)
|
||||
dna.features = newfeatures
|
||||
|
||||
if(mrace)
|
||||
set_species(mrace, icon_update=0)
|
||||
|
||||
if(newreal_name)
|
||||
real_name = newreal_name
|
||||
dna.generate_unique_enzymes()
|
||||
|
||||
if(newblood_type)
|
||||
dna.blood_type = newblood_type
|
||||
|
||||
if(ui)
|
||||
dna.uni_identity = ui
|
||||
updateappearance(icon_update=0)
|
||||
|
||||
if(se)
|
||||
dna.struc_enzymes = se
|
||||
domutcheck()
|
||||
|
||||
if(mrace || newfeatures || ui)
|
||||
update_body()
|
||||
update_hair()
|
||||
update_body_parts()
|
||||
update_mutations_overlay()
|
||||
|
||||
|
||||
/mob/living/carbon/proc/create_dna()
|
||||
dna = new /datum/dna(src)
|
||||
if(!dna.species)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
dna.species = new rando_race()
|
||||
|
||||
//proc used to update the mob's appearance after its dna UI has been changed
|
||||
/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
|
||||
if(!has_dna())
|
||||
return
|
||||
gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
|
||||
|
||||
mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
|
||||
..()
|
||||
var/structure = dna.uni_identity
|
||||
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
|
||||
facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
|
||||
skin_tone = skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), skin_tones.len)]
|
||||
eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
|
||||
facial_hair_style = facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), facial_hair_styles_list.len)]
|
||||
hair_style = hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), hair_styles_list.len)]
|
||||
if(icon_update)
|
||||
update_body()
|
||||
update_hair()
|
||||
if(mutcolor_update)
|
||||
update_body_parts()
|
||||
if(mutations_overlay_update)
|
||||
update_mutations_overlay()
|
||||
|
||||
|
||||
/mob/proc/domutcheck()
|
||||
return
|
||||
|
||||
/mob/living/carbon/domutcheck()
|
||||
if(!has_dna())
|
||||
return
|
||||
|
||||
for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations)
|
||||
if(ismob(A.check_block(src)))
|
||||
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
|
||||
|
||||
update_mutations_overlay()
|
||||
|
||||
|
||||
|
||||
/////////////////////////// DNA HELPER-PROCS //////////////////////////////
|
||||
/proc/getleftblocks(input,blocknumber,blocksize)
|
||||
if(blocknumber > 1)
|
||||
return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
|
||||
|
||||
/proc/getrightblocks(input,blocknumber,blocksize)
|
||||
if(blocknumber < (length(input)/blocksize))
|
||||
return copytext(input,blocksize*blocknumber+1,length(input)+1)
|
||||
|
||||
/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE)
|
||||
return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
|
||||
|
||||
/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE)
|
||||
if(!istring || !blocknumber || !replacement || !blocksize)
|
||||
return 0
|
||||
return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
|
||||
|
||||
/proc/randmut(mob/living/carbon/M, list/candidates, difficulty = 2)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
var/datum/mutation/human/num = pick(candidates)
|
||||
. = num.force_give(M)
|
||||
return
|
||||
|
||||
/proc/randmutb(mob/living/carbon/M)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
var/datum/mutation/human/HM = pick((bad_mutations | not_good_mutations) - mutations_list[RACEMUT])
|
||||
. = HM.force_give(M)
|
||||
|
||||
/proc/randmutg(mob/living/carbon/M)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
var/datum/mutation/human/HM = pick(good_mutations)
|
||||
. = HM.force_give(M)
|
||||
|
||||
/proc/randmuti(mob/living/carbon/M)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
|
||||
var/newdna = setblock(M.dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters))
|
||||
M.dna.uni_identity = newdna
|
||||
return
|
||||
|
||||
/proc/clean_dna(mob/living/carbon/M)
|
||||
if(!M.has_dna())
|
||||
return
|
||||
M.dna.remove_all_mutations()
|
||||
|
||||
/proc/clean_randmut(mob/living/carbon/M, list/candidates, difficulty = 2)
|
||||
clean_dna(M)
|
||||
randmut(M, candidates, difficulty)
|
||||
|
||||
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
|
||||
if(!M.has_dna())
|
||||
return 0
|
||||
if(se)
|
||||
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
|
||||
if(prob(probability))
|
||||
M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, hex_characters))
|
||||
M.domutcheck()
|
||||
if(ui)
|
||||
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
||||
if(prob(probability))
|
||||
M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, hex_characters))
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
return 1
|
||||
|
||||
//value in range 1 to values. values must be greater than 0
|
||||
//all arguments assumed to be positive integers
|
||||
/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE)
|
||||
var/width = round((16**blocksize)/values)
|
||||
if(value < 1)
|
||||
value = 1
|
||||
value = (value * width) - rand(1,width)
|
||||
return num2hex(value, blocksize)
|
||||
|
||||
//value is hex
|
||||
/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE)
|
||||
var/width = round((16**blocksize)/values)
|
||||
value = round(hex2num(value) / width) + 1
|
||||
if(value > values)
|
||||
value = values
|
||||
return value
|
||||
|
||||
/////////////////////////// DNA HELPER-PROCS
|
||||
@@ -0,0 +1,173 @@
|
||||
/datum/dog_fashion
|
||||
var/name
|
||||
var/desc
|
||||
var/emote_see
|
||||
var/emote_hear
|
||||
var/speak
|
||||
var/speak_emote
|
||||
|
||||
// This isn't applied to the dog, but stores the icon_state of the
|
||||
// sprite that the associated item uses
|
||||
var/icon_file
|
||||
var/icon_state
|
||||
|
||||
/datum/dog_fashion/New(mob/M)
|
||||
name = replacetext(name, "REAL_NAME", M.real_name)
|
||||
desc = replacetext(desc, "NAME", name)
|
||||
|
||||
/datum/dog_fashion/proc/apply(mob/living/simple_animal/pet/dog/D)
|
||||
if(name)
|
||||
D.name = name
|
||||
if(desc)
|
||||
D.desc = desc
|
||||
if(emote_see)
|
||||
D.emote_see = emote_see
|
||||
if(emote_hear)
|
||||
D.emote_hear = emote_hear
|
||||
if(speak)
|
||||
D.speak = speak
|
||||
if(speak_emote)
|
||||
D.speak_emote = speak_emote
|
||||
|
||||
/datum/dog_fashion/proc/get_image(var/dir)
|
||||
if(icon_file && icon_state)
|
||||
return image(icon_file, icon_state = icon_state, dir = dir)
|
||||
|
||||
|
||||
/datum/dog_fashion/head
|
||||
icon_file = 'icons/mob/corgi_head.dmi'
|
||||
|
||||
/datum/dog_fashion/back
|
||||
icon_file = 'icons/mob/corgi_back.dmi'
|
||||
|
||||
/datum/dog_fashion/head
|
||||
|
||||
/datum/dog_fashion/head/helmet
|
||||
name = "Sergeant REAL_NAME"
|
||||
desc = "The ever-loyal, the ever-vigilant."
|
||||
|
||||
/datum/dog_fashion/head/chef
|
||||
name = "Sous chef REAL_NAME"
|
||||
desc = "Your food will be taste-tested. All of it."
|
||||
|
||||
|
||||
/datum/dog_fashion/head/captain
|
||||
name = "Captain REAL_NAME"
|
||||
desc = "Probably better than the last captain."
|
||||
|
||||
/datum/dog_fashion/head/kitty
|
||||
name = "Runtime"
|
||||
emote_see = list("coughs up a furball", "stretches")
|
||||
emote_hear = list("purrs")
|
||||
speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW")
|
||||
desc = "It's a cute little kitty-cat! ... wait ... what the hell?"
|
||||
|
||||
/datum/dog_fashion/head/rabbit
|
||||
name = "Hoppy"
|
||||
emote_see = list("twitches its nose", "hops around a bit")
|
||||
desc = "This is Hoppy. It's a corgi-...urmm... bunny rabbit."
|
||||
|
||||
/datum/dog_fashion/head/beret
|
||||
name = "Yann"
|
||||
desc = "Mon dieu! C'est un chien!"
|
||||
speak = list("le woof!", "le bark!", "JAPPE!!")
|
||||
emote_see = list("cowers in fear.", "surrenders.", "plays dead.","looks as though there is a wall in front of him.")
|
||||
|
||||
|
||||
/datum/dog_fashion/head/detective
|
||||
name = "Detective REAL_NAME"
|
||||
desc = "NAME sees through your lies..."
|
||||
emote_see = list("investigates the area.","sniffs around for clues.","searches for scooby snacks.","takes a candycorn from the hat.")
|
||||
|
||||
|
||||
/datum/dog_fashion/head/nurse
|
||||
name = "Nurse REAL_NAME"
|
||||
desc = "NAME needs 100cc of beef jerky... STAT!"
|
||||
|
||||
/datum/dog_fashion/head/pirate
|
||||
name = "Pirate-title Pirate-name"
|
||||
desc = "Yaarghh!! Thar' be a scurvy dog!"
|
||||
emote_see = list("hunts for treasure.","stares coldly...","gnashes his tiny corgi teeth!")
|
||||
emote_hear = list("growls ferociously!", "snarls.")
|
||||
speak = list("Arrrrgh!!","Grrrrrr!")
|
||||
|
||||
/datum/dog_fashion/head/pirate/New(mob/M)
|
||||
..()
|
||||
name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]"
|
||||
|
||||
/datum/dog_fashion/head/ushanka
|
||||
name = "Communist-title Realname"
|
||||
desc = "A follower of Karl Barx."
|
||||
emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vanguardism.")
|
||||
|
||||
/datum/dog_fashion/head/ushanka/New(mob/M)
|
||||
..()
|
||||
name = "[pick("Comrade","Commissar","Glorious Leader")] [M.real_name]"
|
||||
|
||||
/datum/dog_fashion/head/warden
|
||||
name = "Officer REAL_NAME"
|
||||
emote_see = list("drools.","looks for donuts.")
|
||||
desc = "Stop right there criminal scum!"
|
||||
|
||||
/datum/dog_fashion/head/blue_wizard
|
||||
name = "Grandwizard REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!")
|
||||
|
||||
/datum/dog_fashion/head/red_wizard
|
||||
name = "Pyromancer REAL_NAME"
|
||||
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "ONI SOMA!")
|
||||
|
||||
/datum/dog_fashion/head/cardborg
|
||||
name = "Borgi"
|
||||
speak = list("Ping!","Beep!","Woof!")
|
||||
emote_see = list("goes rogue.", "sniffs out non-humans.")
|
||||
desc = "Result of robotics budget cuts."
|
||||
|
||||
/datum/dog_fashion/head/ghost
|
||||
name = "\improper Ghost"
|
||||
speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU")
|
||||
emote_see = list("stumbles around.", "shivers.")
|
||||
emote_hear = list("howls!","groans.")
|
||||
desc = "Spooky!"
|
||||
icon_state = "sheet"
|
||||
|
||||
/datum/dog_fashion/head/santa
|
||||
name = "Santa's Corgi Helper"
|
||||
emote_hear = list("barks Christmas songs.", "yaps merrily!")
|
||||
emote_see = list("looks for presents.", "checks his list.")
|
||||
desc = "He's very fond of milk and cookies."
|
||||
|
||||
/datum/dog_fashion/head/cargo_tech
|
||||
name = "Corgi Tech REAL_NAME"
|
||||
desc = "The reason your yellow gloves have chew-marks."
|
||||
|
||||
/datum/dog_fashion/head/reindeer
|
||||
name = "REAL_NAME the red-nosed Corgi"
|
||||
emote_hear = list("lights the way!", "illuminates.", "yaps!")
|
||||
desc = "He has a very shiny nose."
|
||||
|
||||
/datum/dog_fashion/head/sombrero
|
||||
name = "Segnor REAL_NAME"
|
||||
desc = "You must respect Elder Dogname"
|
||||
|
||||
/datum/dog_fashion/head/sombrero/New(mob/M)
|
||||
..()
|
||||
desc = "You must respect Elder [M.real_name]."
|
||||
|
||||
/datum/dog_fashion/head/hop
|
||||
name = "Lieutenant REAL_NAME"
|
||||
desc = "Can actually be trusted to not run off on his own."
|
||||
|
||||
/datum/dog_fashion/head/deathsquad
|
||||
name = "Trooper REAL_NAME"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
|
||||
/datum/dog_fashion/head/clown
|
||||
name = "REAL_NAME the Clown"
|
||||
desc = "Honkman's best friend."
|
||||
speak = list("HONK!", "Honk!")
|
||||
emote_see = list("plays tricks.", "slips.")
|
||||
|
||||
/datum/dog_fashion/back/deathsquad
|
||||
name = "Trooper REAL_NAME"
|
||||
desc = "That's not red paint. That's real corgi blood."
|
||||
@@ -0,0 +1,103 @@
|
||||
#define FORWARD -1
|
||||
#define BACKWARD 1
|
||||
|
||||
/datum/construction
|
||||
var/list/steps
|
||||
var/atom/holder
|
||||
var/result
|
||||
var/list/steps_desc
|
||||
|
||||
/datum/construction/New(atom)
|
||||
..()
|
||||
holder = atom
|
||||
if(!holder) //don't want this without a holder
|
||||
qdel(src)
|
||||
set_desc(steps.len)
|
||||
return
|
||||
|
||||
/datum/construction/proc/next_step()
|
||||
steps.len--
|
||||
if(!steps.len)
|
||||
spawn_result()
|
||||
else
|
||||
set_desc(steps.len)
|
||||
return
|
||||
|
||||
/datum/construction/proc/action(atom/used_atom,mob/user)
|
||||
return
|
||||
|
||||
/datum/construction/proc/check_step(atom/used_atom,mob/user) //check last step only
|
||||
var/valid_step = is_right_key(used_atom)
|
||||
if(valid_step)
|
||||
if(custom_action(valid_step, used_atom, user))
|
||||
next_step()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/construction/proc/is_right_key(atom/used_atom) // returns current step num if used_atom is of the right type.
|
||||
var/list/L = steps[steps.len]
|
||||
if(istype(used_atom, L["key"]))
|
||||
return steps.len
|
||||
return 0
|
||||
|
||||
/datum/construction/proc/custom_action(step, used_atom, user)
|
||||
return 1
|
||||
|
||||
/datum/construction/proc/check_all_steps(atom/used_atom,mob/user) //check all steps, remove matching one.
|
||||
for(var/i=1;i<=steps.len;i++)
|
||||
var/list/L = steps[i];
|
||||
if(istype(used_atom, L["key"]))
|
||||
if(custom_action(i, used_atom, user))
|
||||
steps[i]=null;//stupid byond list from list removal...
|
||||
listclearnulls(steps);
|
||||
if(!steps.len)
|
||||
spawn_result()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/construction/proc/spawn_result()
|
||||
if(result)
|
||||
new result(get_turf(holder))
|
||||
qdel(holder)
|
||||
return
|
||||
|
||||
/datum/construction/proc/set_desc(index as num)
|
||||
var/list/step = steps[index]
|
||||
holder.desc = step["desc"]
|
||||
return
|
||||
|
||||
/datum/construction/reversible
|
||||
var/index
|
||||
|
||||
/datum/construction/reversible/New(atom)
|
||||
..()
|
||||
index = steps.len
|
||||
return
|
||||
|
||||
/datum/construction/reversible/proc/update_index(diff as num)
|
||||
index+=diff
|
||||
if(index==0)
|
||||
spawn_result()
|
||||
else
|
||||
set_desc(index)
|
||||
return
|
||||
|
||||
/datum/construction/reversible/is_right_key(atom/used_atom) // returns index step
|
||||
var/list/L = steps[index]
|
||||
if(istype(used_atom, L["key"]))
|
||||
return FORWARD //to the first step -> forward
|
||||
else if(L["backkey"] && istype(used_atom, L["backkey"]))
|
||||
return BACKWARD //to the last step -> backwards
|
||||
return 0
|
||||
|
||||
/datum/construction/reversible/check_step(atom/used_atom,mob/user)
|
||||
var/diff = is_right_key(used_atom)
|
||||
if(diff)
|
||||
if(custom_action(index, diff, used_atom, user))
|
||||
update_index(diff)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/construction/reversible/custom_action(index, diff, used_atom, user)
|
||||
return 1
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* WARRANTY VOID IF CODE USED
|
||||
*/
|
||||
|
||||
|
||||
/datum/events
|
||||
var/list/events
|
||||
|
||||
/datum/events/New()
|
||||
..()
|
||||
events = new
|
||||
|
||||
/datum/events/proc/addEventType(event_type as text)
|
||||
if(!(event_type in events) || !islist(events[event_type]))
|
||||
events[event_type] = list()
|
||||
return 1
|
||||
return
|
||||
|
||||
|
||||
// Arguments: event_type as text, proc_holder as datum, proc_name as text
|
||||
// Returns: New event, null on error.
|
||||
/datum/events/proc/addEvent(event_type as text, proc_holder, proc_name as text)
|
||||
if(!event_type || !proc_holder || !proc_name)
|
||||
return
|
||||
addEventType(event_type)
|
||||
var/list/event = events[event_type]
|
||||
var/datum/event/E = new /datum/event(proc_holder,proc_name)
|
||||
event += E
|
||||
return E
|
||||
|
||||
// Arguments: event_type as text, any number of additional arguments to pass to event handler
|
||||
// Returns: null
|
||||
/datum/events/proc/fireEvent()
|
||||
//world << "Events in [args[1]] called"
|
||||
var/list/event = listgetindex(events,args[1])
|
||||
if(istype(event))
|
||||
spawn(0)
|
||||
for(var/datum/event/E in event)
|
||||
if(!E.Fire(arglist(args.Copy(2))))
|
||||
clearEvent(args[1],E)
|
||||
return
|
||||
|
||||
// Arguments: event_type as text, E as /datum/event
|
||||
// Returns: 1 if event cleared, null on error
|
||||
|
||||
/datum/events/proc/clearEvent(event_type as text, datum/event/E)
|
||||
if(!event_type || !E)
|
||||
return
|
||||
var/list/event = listgetindex(events,event_type)
|
||||
event -= E
|
||||
return 1
|
||||
|
||||
|
||||
/datum/event
|
||||
var/listener
|
||||
var/proc_name
|
||||
|
||||
/datum/event/New(tlistener,tprocname)
|
||||
listener = tlistener
|
||||
proc_name = tprocname
|
||||
return ..()
|
||||
|
||||
/datum/event/proc/Fire()
|
||||
//world << "Event fired"
|
||||
if(listener)
|
||||
call(listener,proc_name)(arglist(args))
|
||||
return 1
|
||||
return
|
||||
@@ -0,0 +1,61 @@
|
||||
var/global/datum/getrev/revdata = new()
|
||||
|
||||
/datum/getrev
|
||||
var/parentcommit
|
||||
var/commit
|
||||
var/list/testmerge = list()
|
||||
var/date
|
||||
|
||||
/datum/getrev/New()
|
||||
var/head_file = return_file_text(".git/logs/HEAD")
|
||||
var/regex/head_log = new("(\\w{40}) (\\w{40}).+> (\\d{10}).+\n\\Z")
|
||||
head_log.Find(head_file)
|
||||
parentcommit = head_log.group[1]
|
||||
commit = head_log.group[2]
|
||||
var/unix_time = text2num(head_log.group[3])
|
||||
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
|
||||
testmerge = file2list("..\\prtestjob.lk")
|
||||
date = unix2date(unix_time)
|
||||
world.log << "Running /tg/ revision:"
|
||||
world.log << "[date]"
|
||||
world.log << commit
|
||||
if(testmerge.len)
|
||||
for(var/line in testmerge)
|
||||
if(line)
|
||||
world.log << "Test merge active of PR #[line]"
|
||||
world.log << "Based off master commit [parentcommit]"
|
||||
world.log << "Current map - [MAP_NAME]" //can't think of anywhere better to put it
|
||||
|
||||
/client/verb/showrevinfo()
|
||||
set category = "OOC"
|
||||
set name = "Show Server Revision"
|
||||
set desc = "Check the current server code revision"
|
||||
|
||||
if(revdata.commit)
|
||||
src << "<b>Server revision compiled on:</b> [revdata.date]"
|
||||
if(revdata.testmerge.len)
|
||||
for(var/line in revdata.testmerge)
|
||||
if(line)
|
||||
src << "Test merge active of PR <a href='[config.githuburl]/pull/[line]'>#[line]</a>"
|
||||
src << "Based off master commit <a href='[config.githuburl]/commit/[revdata.parentcommit]'>[revdata.parentcommit]</a>"
|
||||
else
|
||||
src << "<a href='[config.githuburl]/commit/[revdata.commit]'>[revdata.commit]</a>"
|
||||
else
|
||||
src << "Revision unknown"
|
||||
src << "<b>Current Infomational Settings:</b>"
|
||||
src << "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]"
|
||||
src << "Protect Assistant Role From Traitor: [config.protect_assistant_from_antagonist]"
|
||||
src << "Enforce Human Authority: [config.enforce_human_authority]"
|
||||
src << "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]"
|
||||
src << "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes"
|
||||
src << "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes"
|
||||
if(config.show_game_type_odds)
|
||||
src <<"<b>Game Mode Odds:</b>"
|
||||
var/sum = 0
|
||||
for(var/i=1,i<=config.probabilities.len,i++)
|
||||
sum += config.probabilities[config.probabilities[i]]
|
||||
for(var/i=1,i<=config.probabilities.len,i++)
|
||||
if(config.probabilities[config.probabilities[i]] > 0)
|
||||
var/percentage = round(config.probabilities[config.probabilities[i]] / sum * 100, 0.1)
|
||||
src << "[config.probabilities[i]] [percentage]%"
|
||||
return
|
||||
@@ -0,0 +1,15 @@
|
||||
/datum/icon_snapshot
|
||||
var/name
|
||||
var/icon
|
||||
var/icon_state
|
||||
var/list/overlays
|
||||
|
||||
/datum/icon_snapshot/proc/makeImg()
|
||||
if(!icon || !icon_state)
|
||||
return
|
||||
var/obj/temp = new
|
||||
temp.icon = icon
|
||||
temp.icon_state = icon_state
|
||||
temp.overlays = overlays.Copy()
|
||||
var/icon/tempicon = getFlatIcon(temp) // TODO Actually write something less heavy-handed for this
|
||||
return tempicon
|
||||
@@ -0,0 +1,138 @@
|
||||
/datum/map_template
|
||||
var/name = "Default Template Name"
|
||||
var/width = 0
|
||||
var/height = 0
|
||||
var/mappath = null
|
||||
var/mapfile = null
|
||||
var/loaded = 0 // Times loaded this round
|
||||
|
||||
/datum/map_template/New(path = null, map = null, rename = null)
|
||||
if(path)
|
||||
mappath = path
|
||||
if(mappath)
|
||||
preload_size(mappath)
|
||||
if(map)
|
||||
mapfile = map
|
||||
if(rename)
|
||||
name = rename
|
||||
|
||||
/datum/map_template/proc/preload_size(path)
|
||||
var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE)
|
||||
if(bounds)
|
||||
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
|
||||
height = bounds[MAP_MAXY]
|
||||
return bounds
|
||||
|
||||
/proc/initTemplateBounds(var/list/bounds)
|
||||
var/list/obj/machinery/atmospherics/atmos_machines = list()
|
||||
var/list/obj/structure/cable/cables = list()
|
||||
var/list/atom/atoms = list()
|
||||
|
||||
for(var/L in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]),
|
||||
locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/B = L
|
||||
for(var/A in B)
|
||||
atoms += A
|
||||
if(istype(A,/obj/structure/cable))
|
||||
cables += A
|
||||
continue
|
||||
if(istype(A,/obj/machinery/atmospherics))
|
||||
atmos_machines += A
|
||||
continue
|
||||
|
||||
SSobj.setup_template_objects(atoms)
|
||||
SSmachine.setup_template_powernets(cables)
|
||||
SSair.setup_template_machinery(atmos_machines)
|
||||
|
||||
/datum/map_template/proc/load(turf/T, centered = FALSE)
|
||||
if(centered)
|
||||
T = locate(T.x - round(width/2) , T.y - round(height/2) , T.z)
|
||||
if(!T)
|
||||
return
|
||||
if(T.x+width > world.maxx)
|
||||
return
|
||||
if(T.y+height > world.maxy)
|
||||
return
|
||||
|
||||
var/list/bounds = maploader.load_map(get_file(), T.x, T.y, T.z, cropMap=TRUE)
|
||||
if(!bounds)
|
||||
return 0
|
||||
|
||||
//initialize things that are normally initialized after map load
|
||||
initTemplateBounds(bounds)
|
||||
|
||||
log_game("[name] loaded at at [T.x],[T.y],[T.z]")
|
||||
return 1
|
||||
|
||||
/datum/map_template/proc/get_file()
|
||||
if(mapfile)
|
||||
. = mapfile
|
||||
else if(mappath)
|
||||
. = file(mappath)
|
||||
|
||||
if(!.)
|
||||
world.log << "The file of [src] appears to be empty/non-existent."
|
||||
|
||||
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
|
||||
var/turf/placement = T
|
||||
if(centered)
|
||||
var/turf/corner = locate(placement.x - round(width/2), placement.y - round(height/2), placement.z)
|
||||
if(corner)
|
||||
placement = corner
|
||||
return block(placement, locate(placement.x+width-1, placement.y+height-1, placement.z))
|
||||
|
||||
|
||||
/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
|
||||
var/list/filelist = flist(path)
|
||||
for(var/map in filelist)
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
map_templates[T.name] = T
|
||||
|
||||
preloadRuinTemplates()
|
||||
preloadShuttleTemplates()
|
||||
preloadShelterTemplates()
|
||||
|
||||
/proc/preloadRuinTemplates()
|
||||
// Still supporting bans by filename
|
||||
var/list/banned = generateMapList("config/lavaRuinBlacklist.txt")
|
||||
banned += generateMapList("config/spaceRuinBlacklist.txt")
|
||||
|
||||
for(var/item in subtypesof(/datum/map_template/ruin))
|
||||
var/datum/map_template/ruin/ruin_type = item
|
||||
// screen out the abstract subtypes
|
||||
if(!initial(ruin_type.id))
|
||||
continue
|
||||
var/datum/map_template/ruin/R = new ruin_type()
|
||||
|
||||
if(banned.Find(R.mappath))
|
||||
continue
|
||||
|
||||
map_templates[R.name] = R
|
||||
ruins_templates[R.name] = R
|
||||
|
||||
if(istype(R, /datum/map_template/ruin/lavaland))
|
||||
lava_ruins_templates[R.name] = R
|
||||
else if(istype(R, /datum/map_template/ruin/space))
|
||||
space_ruins_templates[R.name] = R
|
||||
|
||||
|
||||
/proc/preloadShuttleTemplates()
|
||||
for(var/item in subtypesof(/datum/map_template/shuttle))
|
||||
var/datum/map_template/shuttle/shuttle_type = item
|
||||
if(!(initial(shuttle_type.suffix)))
|
||||
continue
|
||||
|
||||
var/datum/map_template/shuttle/S = new shuttle_type()
|
||||
|
||||
shuttle_templates[S.shuttle_id] = S
|
||||
map_templates[S.shuttle_id] = S
|
||||
|
||||
/proc/preloadShelterTemplates()
|
||||
for(var/item in subtypesof(/datum/map_template/shelter))
|
||||
var/datum/map_template/shelter/shelter_type = item
|
||||
if(!(initial(shelter_type.mappath)))
|
||||
continue
|
||||
var/datum/map_template/shelter/S = new shelter_type()
|
||||
|
||||
shelter_templates[S.shelter_id] = S
|
||||
map_templates[S.shelter_id] = S
|
||||
@@ -0,0 +1,219 @@
|
||||
//wrapper
|
||||
/proc/do_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
var/datum/teleport/instant/science/D = new
|
||||
if(D.start(arglist(args)))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/teleport
|
||||
var/atom/movable/teleatom //atom to teleport
|
||||
var/atom/destination //destination to teleport to
|
||||
var/precision = 0 //teleport precision
|
||||
var/datum/effect_system/effectin //effect to show right before teleportation
|
||||
var/datum/effect_system/effectout //effect to show right after teleportation
|
||||
var/soundin //soundfile to play before teleportation
|
||||
var/soundout //soundfile to play after teleportation
|
||||
var/force_teleport = 1 //if false, teleport will use Move() proc (dense objects will prevent teleportation)
|
||||
|
||||
|
||||
/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(!initTeleport(arglist(args)))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/teleport/proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout)
|
||||
if(!setTeleatom(ateleatom))
|
||||
return 0
|
||||
if(!setDestination(adestination))
|
||||
return 0
|
||||
if(!setPrecision(aprecision))
|
||||
return 0
|
||||
setEffects(aeffectin,aeffectout)
|
||||
setForceTeleport(afteleport)
|
||||
setSounds(asoundin,asoundout)
|
||||
return 1
|
||||
|
||||
//must succeed
|
||||
/datum/teleport/proc/setPrecision(aprecision)
|
||||
if(isnum(aprecision))
|
||||
precision = aprecision
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//must succeed
|
||||
/datum/teleport/proc/setDestination(atom/adestination)
|
||||
if(istype(adestination))
|
||||
destination = adestination
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//must succeed in most cases
|
||||
/datum/teleport/proc/setTeleatom(atom/movable/ateleatom)
|
||||
if(istype(ateleatom, /obj/effect) && !istype(ateleatom, /obj/effect/dummy/chameleon))
|
||||
qdel(ateleatom)
|
||||
return 0
|
||||
if(istype(ateleatom))
|
||||
teleatom = ateleatom
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//custom effects must be properly set up first for instant-type teleports
|
||||
//optional
|
||||
/datum/teleport/proc/setEffects(datum/effect_system/aeffectin=null,datum/effect_system/aeffectout=null)
|
||||
effectin = istype(aeffectin) ? aeffectin : null
|
||||
effectout = istype(aeffectout) ? aeffectout : null
|
||||
return 1
|
||||
|
||||
//optional
|
||||
/datum/teleport/proc/setForceTeleport(afteleport)
|
||||
force_teleport = afteleport
|
||||
return 1
|
||||
|
||||
//optional
|
||||
/datum/teleport/proc/setSounds(asoundin=null,asoundout=null)
|
||||
soundin = isfile(asoundin) ? asoundin : null
|
||||
soundout = isfile(asoundout) ? asoundout : null
|
||||
return 1
|
||||
|
||||
//placeholder
|
||||
/datum/teleport/proc/teleportChecks()
|
||||
return 1
|
||||
|
||||
/datum/teleport/proc/playSpecials(atom/location,datum/effect_system/effect,sound)
|
||||
if(location)
|
||||
if(effect)
|
||||
addtimer(src, "do_effect", 0, FALSE, location, effect)
|
||||
if(sound)
|
||||
addtimer(src, "do_sound", 0, FALSE, location, sound)
|
||||
|
||||
/datum/teleport/proc/do_effect(atom/location, datum/effect_system/effect)
|
||||
src = null
|
||||
effect.attach(location)
|
||||
effect.start()
|
||||
|
||||
/datum/teleport/proc/do_sound(atom/location, sound)
|
||||
src = null
|
||||
playsound(location, sound, 60, 1)
|
||||
|
||||
//do the monkey dance
|
||||
/datum/teleport/proc/doTeleport()
|
||||
|
||||
var/turf/destturf
|
||||
var/turf/curturf = get_turf(teleatom)
|
||||
if(precision)
|
||||
var/list/posturfs = list()
|
||||
var/center = get_turf(destination)
|
||||
if(!center)
|
||||
center = destination
|
||||
for(var/turf/T in range(precision,center))
|
||||
var/area/A = T.loc
|
||||
if(!A.noteleport)
|
||||
posturfs.Add(T)
|
||||
|
||||
destturf = safepick(posturfs)
|
||||
else
|
||||
destturf = get_turf(destination)
|
||||
|
||||
if(!destturf || !curturf)
|
||||
return 0
|
||||
|
||||
var/area/A = get_area(curturf)
|
||||
if(A.noteleport)
|
||||
return 0
|
||||
|
||||
playSpecials(curturf,effectin,soundin)
|
||||
|
||||
if(force_teleport)
|
||||
teleatom.forceMove(destturf)
|
||||
playSpecials(destturf,effectout,soundout)
|
||||
else
|
||||
if(teleatom.Move(destturf))
|
||||
playSpecials(destturf,effectout,soundout)
|
||||
return 1
|
||||
|
||||
/datum/teleport/proc/teleport()
|
||||
if(teleportChecks())
|
||||
return doTeleport()
|
||||
return 0
|
||||
|
||||
/datum/teleport/instant //teleports when datum is created
|
||||
|
||||
start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
|
||||
if(..())
|
||||
if(teleport())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/teleport/instant/science
|
||||
|
||||
/datum/teleport/instant/science/setEffects(datum/effect_system/aeffectin,datum/effect_system/aeffectout)
|
||||
if(aeffectin==null || aeffectout==null)
|
||||
var/datum/effect_system/spark_spread/aeffect = new
|
||||
aeffect.set_up(5, 1, teleatom)
|
||||
effectin = effectin || aeffect
|
||||
effectout = effectout || aeffect
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/datum/teleport/instant/science/setPrecision(aprecision)
|
||||
..()
|
||||
if(istype(teleatom, /obj/item/weapon/storage/backpack/holding))
|
||||
precision = rand(1,100)
|
||||
|
||||
var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding)
|
||||
if(bagholding.len)
|
||||
precision = max(rand(1,100)*bagholding.len,100)
|
||||
if(istype(teleatom, /mob/living))
|
||||
var/mob/living/MM = teleatom
|
||||
MM << "<span class='warning'>The bluespace interface on your bag of holding interferes with the teleport!</span>"
|
||||
return 1
|
||||
|
||||
// Safe location finder
|
||||
|
||||
/proc/find_safe_turf(zlevel = ZLEVEL_STATION, list/zlevels)
|
||||
if(!zlevels)
|
||||
zlevels = list(zlevel)
|
||||
var/cycles = 1000
|
||||
for(var/cycle in 1 to cycles)
|
||||
// DRUNK DIALLING WOOOOOOOOO
|
||||
var/x = rand(1, world.maxx)
|
||||
var/y = rand(1, world.maxy)
|
||||
var/z = pick(zlevels)
|
||||
var/random_location = locate(x,y,z)
|
||||
|
||||
if(!(istype(random_location, /turf/open/floor)))
|
||||
continue
|
||||
var/turf/open/floor/F = random_location
|
||||
if(!F.air)
|
||||
continue
|
||||
|
||||
var/datum/gas_mixture/A = F.air
|
||||
var/list/A_gases = A.gases
|
||||
var/trace_gases
|
||||
for(var/id in A_gases)
|
||||
if(id in hardcoded_gases)
|
||||
continue
|
||||
trace_gases = TRUE
|
||||
break
|
||||
|
||||
// Can most things breathe?
|
||||
if(trace_gases)
|
||||
continue
|
||||
if(!(A_gases["o2"] && A_gases["o2"][MOLES] >= 16))
|
||||
continue
|
||||
if(A_gases["plasma"])
|
||||
continue
|
||||
if(A_gases["co2"] && A_gases["co2"][MOLES] >= 10)
|
||||
continue
|
||||
|
||||
// Aim for goldilocks temperatures and pressure
|
||||
if((A.temperature <= 270) || (A.temperature >= 360))
|
||||
continue
|
||||
var/pressure = A.return_pressure()
|
||||
if((pressure <= 20) || (pressure >= 550))
|
||||
continue
|
||||
|
||||
// DING! You have passed the gauntlet, and are "probably" safe.
|
||||
return F
|
||||
@@ -0,0 +1,62 @@
|
||||
/datum/topic_input
|
||||
var/href
|
||||
var/list/href_list
|
||||
|
||||
/datum/topic_input/New(thref,list/thref_list)
|
||||
href = thref
|
||||
href_list = thref_list.Copy()
|
||||
return
|
||||
|
||||
/datum/topic_input/proc/get(i)
|
||||
return listgetindex(href_list,i)
|
||||
|
||||
/datum/topic_input/proc/getAndLocate(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = locate(t)
|
||||
if (istext(t))
|
||||
t = null
|
||||
return t || null
|
||||
|
||||
/datum/topic_input/proc/getNum(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2num(t)
|
||||
return isnum(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getObj(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isobj(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getMob(i)
|
||||
var/t = getAndLocate(i)
|
||||
return ismob(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getTurf(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isturf(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getAtom(i)
|
||||
return getType(i,/atom)
|
||||
|
||||
/datum/topic_input/proc/getArea(i)
|
||||
var/t = getAndLocate(i)
|
||||
return isarea(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getStr(i)//params should always be text, but...
|
||||
var/t = get(i)
|
||||
return istext(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getType(i,type)
|
||||
var/t = getAndLocate(i)
|
||||
return istype(t,type) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getPath(i)
|
||||
var/t = get(i)
|
||||
if(t)
|
||||
t = text2path(t)
|
||||
return ispath(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getList(i)
|
||||
var/t = getAndLocate(i)
|
||||
return islist(t) ? t : null
|
||||
@@ -0,0 +1,93 @@
|
||||
/* HUD DATUMS */
|
||||
|
||||
//GLOBAL HUD LIST
|
||||
var/datum/atom_hud/huds = list( \
|
||||
DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), \
|
||||
DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), \
|
||||
DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), \
|
||||
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), \
|
||||
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), \
|
||||
ANTAG_HUD_CULT = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_REV = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_HOG_BLUE = new/datum/atom_hud/antag(),\
|
||||
ANTAG_HUD_HOG_RED = new/datum/atom_hud/antag(),\
|
||||
ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(),\
|
||||
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),\
|
||||
)
|
||||
|
||||
/datum/atom_hud
|
||||
var/list/atom/hudatoms = list() //list of all atoms which display this hud
|
||||
var/list/mob/hudusers = list() //list with all mobs who can see the hud
|
||||
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
|
||||
|
||||
/datum/atom_hud/proc/remove_hud_from(mob/M)
|
||||
if(!M)
|
||||
return
|
||||
if(src in M.permanent_huds)
|
||||
return
|
||||
for(var/atom/A in hudatoms)
|
||||
remove_from_single_hud(M, A)
|
||||
hudusers -= M
|
||||
|
||||
/datum/atom_hud/proc/remove_from_hud(atom/A)
|
||||
if(!A)
|
||||
return
|
||||
for(var/mob/M in hudusers)
|
||||
remove_from_single_hud(M, A)
|
||||
hudatoms -= A
|
||||
|
||||
/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
|
||||
if(!M || !M.client || !A)
|
||||
return
|
||||
for(var/i in hud_icons)
|
||||
M.client.images -= A.hud_list[i]
|
||||
|
||||
/datum/atom_hud/proc/add_hud_to(mob/M)
|
||||
if(!M)
|
||||
return
|
||||
hudusers |= M
|
||||
for(var/atom/A in hudatoms)
|
||||
add_to_single_hud(M, A)
|
||||
|
||||
/datum/atom_hud/proc/add_to_hud(atom/A)
|
||||
if(!A)
|
||||
return
|
||||
hudatoms |= A
|
||||
for(var/mob/M in hudusers)
|
||||
add_to_single_hud(M, A)
|
||||
|
||||
/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
|
||||
if(!M || !M.client || !A)
|
||||
return
|
||||
for(var/i in hud_icons)
|
||||
if(A.hud_list[i])
|
||||
M.client.images |= A.hud_list[i]
|
||||
|
||||
//MOB PROCS
|
||||
/mob/proc/reload_huds()
|
||||
var/gang_huds = list()
|
||||
if(ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
gang_huds += G.ganghud
|
||||
|
||||
for(var/datum/atom_hud/hud in (huds|gang_huds))
|
||||
if(src in hud.hudusers)
|
||||
hud.add_hud_to(src)
|
||||
|
||||
/mob/new_player/reload_huds()
|
||||
return
|
||||
|
||||
/mob/proc/add_click_catcher()
|
||||
client.screen += client.void
|
||||
|
||||
/mob/new_player/add_click_catcher()
|
||||
return
|
||||
@@ -0,0 +1,519 @@
|
||||
/datum/martial_art
|
||||
var/name = "Martial Art"
|
||||
var/streak = ""
|
||||
var/max_streak_length = 6
|
||||
var/current_target = null
|
||||
var/temporary = 0
|
||||
var/datum/martial_art/base = null // The permanent style
|
||||
var/deflection_chance = 0 //Chance to deflect projectiles
|
||||
var/help_verb = null
|
||||
|
||||
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
return 0
|
||||
|
||||
/datum/martial_art/proc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
return 0
|
||||
|
||||
/datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
return 0
|
||||
|
||||
/datum/martial_art/proc/add_to_streak(element,mob/living/carbon/human/D)
|
||||
if(D != current_target)
|
||||
current_target = D
|
||||
streak = ""
|
||||
streak = streak+element
|
||||
if(length(streak) > max_streak_length)
|
||||
streak = copytext(streak,2)
|
||||
return
|
||||
|
||||
/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A,mob/living/carbon/human/D)
|
||||
|
||||
A.do_attack_animation(D)
|
||||
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
|
||||
|
||||
var/atk_verb = A.dna.species.attack_verb
|
||||
if(D.lying)
|
||||
atk_verb = "kick"
|
||||
|
||||
if(!damage)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>")
|
||||
add_logs(A, D, "attempted to [atk_verb]")
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>")
|
||||
|
||||
D.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
add_logs(A, D, "punched")
|
||||
|
||||
if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold)
|
||||
D.visible_message("<span class='danger'>[A] has weakened [D]!!</span>", \
|
||||
"<span class='userdanger'>[A] has weakened [D]!</span>")
|
||||
D.apply_effect(4, WEAKEN, armor_block)
|
||||
D.forcesay(hit_appends)
|
||||
else if(D.lying)
|
||||
D.forcesay(hit_appends)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0)
|
||||
if(help_verb)
|
||||
H.verbs += help_verb
|
||||
if(make_temporary)
|
||||
temporary = 1
|
||||
if(H.martial_art && temporary)
|
||||
base = H.martial_art
|
||||
H.martial_art = src
|
||||
|
||||
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
|
||||
if(H.martial_art != src)
|
||||
return
|
||||
H.martial_art = base
|
||||
if(help_verb)
|
||||
H.verbs -= help_verb
|
||||
|
||||
/datum/martial_art/boxing
|
||||
name = "Boxing"
|
||||
|
||||
/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A << "<span class='warning'>Can't disarm while boxing!</span>"
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A << "<span class='warning'>Can't grab while boxing!</span>"
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
A.do_attack_animation(D)
|
||||
|
||||
var/atk_verb = pick("left hook","right hook","straight punch")
|
||||
|
||||
var/damage = rand(5, 8) + A.dna.species.punchdamagelow
|
||||
if(!damage)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to hit [D] with a [atk_verb]!</span>")
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
|
||||
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with a [atk_verb]!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with a [atk_verb]!</span>")
|
||||
|
||||
D.apply_damage(damage, STAMINA, affecting, armor_block)
|
||||
add_logs(A, D, "punched")
|
||||
if(D.getStaminaLoss() > 50)
|
||||
var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
|
||||
if((D.stat != DEAD) && prob(knockout_prob))
|
||||
D.visible_message("<span class='danger'>[A] has knocked [D] out with a haymaker!</span>", \
|
||||
"<span class='userdanger'>[A] has knocked [D] out with a haymaker!</span>")
|
||||
D.apply_effect(10,WEAKEN,armor_block)
|
||||
D.SetSleeping(5)
|
||||
D.forcesay(hit_appends)
|
||||
else if(D.lying)
|
||||
D.forcesay(hit_appends)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/wrestling_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember how to wrestle."
|
||||
set category = "Wrestling"
|
||||
|
||||
usr << "<b><i>You flex your muscles and have a revelation...</i></b>"
|
||||
usr << "<span class='notice'>Clinch</span>: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful."
|
||||
usr << "<span class='notice'>Suplex</span>: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor."
|
||||
usr << "<span class='notice'>Advanced grab</span>: Grab. Passively causes stamina damage when grabbing someone."
|
||||
|
||||
#define TORNADO_COMBO "HHD"
|
||||
#define THROWBACK_COMBO "DHD"
|
||||
#define PLASMA_COMBO "HDDDH"
|
||||
|
||||
/datum/martial_art/plasma_fist
|
||||
name = "Plasma Fist"
|
||||
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
|
||||
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,TORNADO_COMBO))
|
||||
streak = ""
|
||||
Tornado(A,D)
|
||||
return 1
|
||||
if(findtext(streak,THROWBACK_COMBO))
|
||||
streak = ""
|
||||
Throwback(A,D)
|
||||
return 1
|
||||
if(findtext(streak,PLASMA_COMBO))
|
||||
streak = ""
|
||||
Plasma(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.say("TORNADO SWEEP!")
|
||||
spawn(0)
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
A.setDir(i)
|
||||
playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1)
|
||||
sleep(1)
|
||||
var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in range(1,A))
|
||||
turfs.Add(T)
|
||||
R.cast(turfs)
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with Plasma Punch!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with Plasma Punch!</span>")
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
|
||||
D.throw_at(throw_target, 200, 4,A)
|
||||
A.say("HYAH!")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.do_attack_animation(D)
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
A.say("PLASMA FIST!")
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>")
|
||||
D.gib()
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/plasma_fist_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Plasma Fist."
|
||||
set category = "Plasma Fist"
|
||||
|
||||
usr << "<b><i>You clench your fists and have a flashback of knowledge...</i></b>"
|
||||
usr << "<span class='notice'>Tornado Sweep</span>: Harm Harm Disarm. Repulses target and everyone back."
|
||||
usr << "<span class='notice'>Throwback</span>: Disarm Harm Disarm. Throws the target and an item at them."
|
||||
usr << "<span class='notice'>The Plasma Fist</span>: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body."
|
||||
|
||||
//Used by the gang of the same name. Uses combos. Basic attacks bypass armor and never miss
|
||||
#define WRIST_WRENCH_COMBO "DD"
|
||||
#define BACK_KICK_COMBO "HG"
|
||||
#define STOMACH_KNEE_COMBO "GH"
|
||||
#define HEAD_KICK_COMBO "DHH"
|
||||
#define ELBOW_DROP_COMBO "HDHDH"
|
||||
/datum/martial_art/the_sleeping_carp
|
||||
name = "The Sleeping Carp"
|
||||
deflection_chance = 100
|
||||
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,WRIST_WRENCH_COMBO))
|
||||
streak = ""
|
||||
wristWrench(A,D)
|
||||
return 1
|
||||
if(findtext(streak,BACK_KICK_COMBO))
|
||||
streak = ""
|
||||
backKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,STOMACH_KNEE_COMBO))
|
||||
streak = ""
|
||||
kneeStomach(A,D)
|
||||
return 1
|
||||
if(findtext(streak,HEAD_KICK_COMBO))
|
||||
streak = ""
|
||||
headKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,ELBOW_DROP_COMBO))
|
||||
streak = ""
|
||||
elbowDrop(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.stunned && !D.weakened)
|
||||
A.do_attack_animation(D)
|
||||
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
|
||||
"<span class='userdanger'>[A] grabs your wrist and violently wrenches it to the side!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
D.emote("scream")
|
||||
D.drop_item()
|
||||
D.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
|
||||
D.Stun(3)
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(A.dir == D.dir && !D.stat && !D.weakened)
|
||||
A.do_attack_animation(D)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
|
||||
step_to(D,get_step(D,D.dir),1)
|
||||
D.Weaken(4)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D)
|
||||
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
|
||||
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
|
||||
D.audible_message("<b>[D]</b> gags!")
|
||||
D.losebreath += 3
|
||||
D.Stun(2)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
|
||||
D.apply_damage(20, BRUTE, "head")
|
||||
D.drop_item()
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.Stun(4)
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(D.weakened || D.resting || D.stat)
|
||||
A.do_attack_animation(D)
|
||||
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
|
||||
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
|
||||
if(D.stat)
|
||||
D.death() //FINISH HIM!
|
||||
D.apply_damage(50, BRUTE, "chest")
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.grab_state >= GRAB_AGGRESSIVE)
|
||||
D.grabbedby(A, 1)
|
||||
else
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.drop_r_hand()
|
||||
D.drop_l_hand()
|
||||
D.stop_pulling()
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
return 1
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
A.do_attack_animation(D)
|
||||
var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams")
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you!</span>")
|
||||
D.apply_damage(rand(10,15), BRUTE)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1)
|
||||
if(prob(D.getBruteLoss()) && !D.lying)
|
||||
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
|
||||
D.Weaken(4)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/sleeping_carp_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Sleeping Carp clan."
|
||||
set category = "Sleeping Carp"
|
||||
|
||||
usr << "<b><i>You retreat inward and recall the teachings of the Sleeping Carp...</i></b>"
|
||||
|
||||
usr << "<span class='notice'>Wrist Wrench</span>: Disarm Disarm. Forces opponent to drop item in hand."
|
||||
usr << "<span class='notice'>Back Kick</span>: Harm Grab. Opponent must be facing away. Knocks down."
|
||||
usr << "<span class='notice'>Stomach Knee</span>: Grab Harm. Knocks the wind out of opponent and stuns."
|
||||
usr << "<span class='notice'>Head Kick</span>: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand."
|
||||
usr << "<span class='notice'>Elbow Drop</span>: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition."
|
||||
|
||||
//ITEMS
|
||||
|
||||
/obj/item/clothing/gloves/boxing
|
||||
var/datum/martial_art/boxing/style = new
|
||||
|
||||
/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_gloves)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/boxing/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_gloves) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling
|
||||
name = "Wrestling Belt"
|
||||
var/datum/martial_art/wrestling/style = new
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_belt)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_belt) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll
|
||||
name = "frayed scroll"
|
||||
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
var/used = 0
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(!used)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
|
||||
F.teach(H)
|
||||
H << "<span class='boldannounce'>You have learned the ancient martial art of Plasma Fist.</span>"
|
||||
used = 1
|
||||
desc = "It's completely blank."
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll
|
||||
name = "mysterious scroll"
|
||||
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
user << "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
|
||||
directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
|
||||
var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null)
|
||||
theSleepingCarp.teach(user)
|
||||
user.drop_item()
|
||||
visible_message("<span class='warning'>[src] lights up in fire and quickly burns to ash.</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff
|
||||
name = "bo staff"
|
||||
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
|
||||
force = 10
|
||||
w_class = 4
|
||||
slot_flags = SLOT_BACK
|
||||
force_unwielded = 10
|
||||
force_wielded = 24
|
||||
throwforce = 20
|
||||
throw_speed = 2
|
||||
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "bostaff0"
|
||||
block_chance = 50
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/update_icon()
|
||||
icon_state = "bostaff[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if((CLUMSY in user.disabilities) && prob(50))
|
||||
user << "<span class ='warning'>You club yourself over the head with [src].</span>"
|
||||
user.Weaken(3)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, "head")
|
||||
else
|
||||
user.take_organ_damage(2*force)
|
||||
return
|
||||
if(isrobot(target))
|
||||
return ..()
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.stat)
|
||||
user << "<span class='warning'>It would be dishonorable to attack a foe while they cannot retaliate.</span>"
|
||||
return
|
||||
if(user.a_intent == "disarm")
|
||||
if(!wielded)
|
||||
return ..()
|
||||
if(!ishuman(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/list/fluffmessages = list("[user] clubs [H] with [src]!", \
|
||||
"[user] smacks [H] with the butt of [src]!", \
|
||||
"[user] broadsides [H] with [src]!", \
|
||||
"[user] smashes [H]'s head with [src]!", \
|
||||
"[user] beats [H] with front of [src]!", \
|
||||
"[user] twirls and slams [H] with [src]!")
|
||||
H.visible_message("<span class='warning'>[pick(fluffmessages)]</span>", \
|
||||
"<span class='userdanger'>[pick(fluffmessages)]</span>")
|
||||
playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
H.adjustStaminaLoss(rand(13,20))
|
||||
if(prob(10))
|
||||
H.visible_message("<span class='warning'>[H] collapses!</span>", \
|
||||
"<span class='userdanger'>Your legs give out!</span>")
|
||||
H.Weaken(4)
|
||||
if(H.staminaloss && !H.sleeping)
|
||||
var/total_health = (H.health - H.staminaloss)
|
||||
if(total_health <= config.health_threshold_crit && !H.stat)
|
||||
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking them out cold!</span>", \
|
||||
"<span class='userdanger'>[user] knocks you unconscious!</span>")
|
||||
H.SetSleeping(30)
|
||||
H.adjustBrainLoss(25)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
|
||||
if(wielded)
|
||||
return ..()
|
||||
return 0
|
||||
@@ -0,0 +1,171 @@
|
||||
/datum/martial_art/krav_maga
|
||||
name = "Krav Maga"
|
||||
var/datum/action/neck_chop/neckchop = new/datum/action/neck_chop()
|
||||
var/datum/action/leg_sweep/legsweep = new/datum/action/leg_sweep()
|
||||
var/datum/action/lung_punch/lungpunch = new/datum/action/lung_punch()
|
||||
|
||||
/datum/action/neck_chop
|
||||
name = "Neck Chop - Injures the neck, stopping the victim from speaking for a while."
|
||||
button_icon_state = "neckchop"
|
||||
|
||||
/datum/action/neck_chop/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Neck Chop stance!</span>", "<b><i>Your next attack will be a Neck Chop.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "neck_chop"
|
||||
|
||||
/datum/action/leg_sweep
|
||||
name = "Leg Sweep - Trips the victim, rendering them prone and unable to move for a short time."
|
||||
button_icon_state = "legsweep"
|
||||
|
||||
/datum/action/leg_sweep/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Leg Sweep stance!</span>", "<b><i>Your next attack will be a Leg Sweep.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "leg_sweep"
|
||||
|
||||
/datum/action/lung_punch//referred to internally as 'quick choke'
|
||||
name = "Lung Punch - Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time."
|
||||
button_icon_state = "lungpunch"
|
||||
|
||||
/datum/action/lung_punch/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Lung Punch stance!</span>", "<b><i>Your next attack will be a Lung Punch.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "quick_choke"//internal name for lung punch
|
||||
|
||||
/datum/martial_art/krav_maga/teach(var/mob/living/carbon/human/H,var/make_temporary=0)
|
||||
..()
|
||||
H << "<span class = 'userdanger'>You know the arts of Krav Maga!</span>"
|
||||
H << "<span class = 'danger'>Place your cursor over a move at the top of the screen to see what it does.</span>"
|
||||
neckchop.Grant(H)
|
||||
legsweep.Grant(H)
|
||||
lungpunch.Grant(H)
|
||||
|
||||
/datum/martial_art/krav_maga/remove(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
H << "<span class = 'userdanger'>You suddenly forget the arts of Krav Maga...</span>"
|
||||
neckchop.Remove(H)
|
||||
legsweep.Remove(H)
|
||||
lungpunch.Remove(H)
|
||||
|
||||
/datum/martial_art/krav_maga/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
switch(streak)
|
||||
if("neck_chop")
|
||||
streak = ""
|
||||
neck_chop(A,D)
|
||||
return 1
|
||||
if("leg_sweep")
|
||||
streak = ""
|
||||
leg_sweep(A,D)
|
||||
return 1
|
||||
if("quick_choke")//is actually lung punch
|
||||
streak = ""
|
||||
quick_choke(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(D.stat || D.weakened)
|
||||
return 0
|
||||
D.visible_message("<span class='warning'>[A] leg sweeps [D]!</span>", \
|
||||
"<span class='userdanger'>[A] leg sweeps you!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE)
|
||||
D.Weaken(2)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch
|
||||
D.visible_message("<span class='warning'>[A] pounds [D] on the chest!</span>", \
|
||||
"<span class='userdanger'>[A] slams your chest! You can't breathe!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
|
||||
D.losebreath += 5
|
||||
D.adjustOxyLoss(10)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='warning'>[A] karate chops [D]'s neck!</span>", \
|
||||
"<span class='userdanger'>[A] karate chops your neck, rendering you unable to speak!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE)
|
||||
D.silent += 10
|
||||
return 1
|
||||
|
||||
datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
..()
|
||||
|
||||
/datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "punched")
|
||||
A.do_attack_animation(D)
|
||||
var/picked_hit_type = pick("punches", "kicks")
|
||||
var/bonus_damage = 10
|
||||
if(D.weakened || D.resting || D.lying)
|
||||
bonus_damage += 5
|
||||
picked_hit_type = "stomps on"
|
||||
D.apply_damage(bonus_damage, BRUTE)
|
||||
if(picked_hit_type == "kicks" || picked_hit_type == "stomps")
|
||||
playsound(get_turf(D), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
else
|
||||
playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(prob(60))
|
||||
if(D.hand)
|
||||
if(istype(D.l_hand, /obj/item))
|
||||
var/obj/item/I = D.l_hand
|
||||
D.drop_item()
|
||||
A.put_in_hands(I)
|
||||
else
|
||||
if(istype(D.r_hand, /obj/item))
|
||||
var/obj/item/I = D.r_hand
|
||||
D.drop_item()
|
||||
A.put_in_hands(I)
|
||||
D.visible_message("<span class='danger'>[A] has disarmed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has disarmed [D]!</span>")
|
||||
playsound(D, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
else
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
return 1
|
||||
|
||||
//Krav Maga Gloves
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga
|
||||
can_be_cut = 0
|
||||
var/datum/martial_art/krav_maga/style = new
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_gloves)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_gloves) == src)
|
||||
style.remove(H)
|
||||
|
||||
/obj/item/clothing/gloves/color/black/krav_maga/sec//more obviously named, given to sec
|
||||
name = "krav maga gloves"
|
||||
desc = "These gloves can teach you to perform Krav Maga using nanochips."
|
||||
icon_state = "fightgloves"
|
||||
item_state = "fightgloves"
|
||||
@@ -0,0 +1,421 @@
|
||||
/datum/martial_art/wrestling
|
||||
name = "Wrestling"
|
||||
var/datum/action/slam/slam = new/datum/action/slam()
|
||||
var/datum/action/throw_wrassle/throw_wrassle = new/datum/action/throw_wrassle()
|
||||
var/datum/action/kick/kick = new/datum/action/kick()
|
||||
var/datum/action/strike/strike = new/datum/action/strike()
|
||||
var/datum/action/drop/drop = new/datum/action/drop()
|
||||
|
||||
/datum/martial_art/wrestling/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
switch(streak)
|
||||
if("drop")
|
||||
streak = ""
|
||||
drop(A,D)
|
||||
return 1
|
||||
if("strike")
|
||||
streak = ""
|
||||
strike(A,D)
|
||||
return 1
|
||||
if("kick")
|
||||
streak = ""
|
||||
kick(A,D)
|
||||
return 1
|
||||
if("throw")
|
||||
streak = ""
|
||||
throw_wrassle(A,D)
|
||||
return 1
|
||||
if("slam")
|
||||
streak = ""
|
||||
slam(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/slam
|
||||
name = "Slam (Cinch) - Slam a grappled opponent into the floor."
|
||||
button_icon_state = "wrassle_slam"
|
||||
|
||||
/datum/action/slam/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't WRESTLE while you're OUT FOR THE COUNT.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to BODY SLAM!</span>", "<b><i>Your next attack will be a BODY SLAM.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "slam"
|
||||
|
||||
/datum/action/throw_wrassle
|
||||
name = "Throw (Cinch) - Spin a cinched opponent around and throw them."
|
||||
button_icon_state = "wrassle_throw"
|
||||
|
||||
/datum/action/throw_wrassle/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't WRESTLE while you're OUT FOR THE COUNT.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to THROW!</span>", "<b><i>Your next attack will be a THROW.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "throw"
|
||||
|
||||
/datum/action/kick
|
||||
name = "Kick - A powerful kick, sends people flying away from you. Also useful for escaping from bad situations."
|
||||
button_icon_state = "wrassle_kick"
|
||||
|
||||
/datum/action/kick/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't WRESTLE while you're OUT FOR THE COUNT.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to KICK!</span>", "<b><i>Your next attack will be a KICK.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "kick"
|
||||
|
||||
/datum/action/strike
|
||||
name = "Strike - Hit a neaby opponent with a quick attack."
|
||||
button_icon_state = "wrassle_strike"
|
||||
|
||||
/datum/action/strike/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't WRESTLE while you're OUT FOR THE COUNT.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to STRIKE!</span>", "<b><i>Your next attack will be a STRIKE.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "strike"
|
||||
|
||||
/datum/action/drop
|
||||
name = "Drop - Smash down onto an opponent."
|
||||
button_icon_state = "wrassle_drop"
|
||||
|
||||
/datum/action/drop/Trigger()
|
||||
if(owner.incapacitated())
|
||||
owner << "<span class='warning'>You can't WRESTLE while you're OUT FOR THE COUNT.</span>"
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to LEG DROP!</span>", "<b><i>Your next attack will be a LEG DROP.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "drop"
|
||||
|
||||
/datum/martial_art/wrestling/teach(var/mob/living/carbon/human/H,var/make_temporary=0)
|
||||
..()
|
||||
H << "<span class = 'userdanger'>SNAP INTO A THIN TIM!</span>"
|
||||
H << "<span class = 'danger'>Place your cursor over a move at the top of the screen to see what it does.</span>"
|
||||
drop.Grant(H)
|
||||
kick.Grant(H)
|
||||
slam.Grant(H)
|
||||
throw_wrassle.Grant(H)
|
||||
strike.Grant(H)
|
||||
|
||||
/datum/martial_art/wrestling/remove(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
H << "<span class = 'userdanger'>You no longer feel that the tower of power is too sweet to be sour...</span>"
|
||||
drop.Remove(H)
|
||||
kick.Remove(H)
|
||||
slam.Remove(H)
|
||||
throw_wrassle.Remove(H)
|
||||
strike.Remove(H)
|
||||
|
||||
/datum/martial_art/wrestling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
..()
|
||||
|
||||
/datum/martial_art/wrestling/proc/throw_wrassle(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
return
|
||||
if(!A.pulling || A.pulling != D)
|
||||
A << "You need to have [D] in a cinch!"
|
||||
return
|
||||
D.forceMove(A.loc)
|
||||
D.setDir(get_dir(D, A))
|
||||
|
||||
D.Stun(4)
|
||||
A.visible_message("<span class = 'danger'><B>[A] starts spinning around with [D]!</B></span>")
|
||||
A.emote("scream")
|
||||
|
||||
for (var/i = 0, i < 20, i++)
|
||||
var/delay = 5
|
||||
switch (i)
|
||||
if (17 to INFINITY)
|
||||
delay = 0.25
|
||||
if (14 to 16)
|
||||
delay = 0.5
|
||||
if (9 to 13)
|
||||
delay = 1
|
||||
if (5 to 8)
|
||||
delay = 2
|
||||
if (0 to 4)
|
||||
delay = 3
|
||||
|
||||
if (A && D)
|
||||
|
||||
if (get_dist(A, D) > 1)
|
||||
A << "[D] is too far away!"
|
||||
return 0
|
||||
|
||||
if (!isturf(A.loc) || !isturf(D.loc))
|
||||
A << "You can't throw [D] from here!"
|
||||
return 0
|
||||
|
||||
A.setDir(turn(A.dir, 90))
|
||||
var/turf/T = get_step(A, A.dir)
|
||||
var/turf/S = D.loc
|
||||
if ((S && isturf(S) && S.Exit(D)) && (T && isturf(T) && T.Enter(A)))
|
||||
D.forceMove(T)
|
||||
D.setDir(get_dir(D, A))
|
||||
else
|
||||
return 0
|
||||
|
||||
sleep(delay)
|
||||
|
||||
if (A && D)
|
||||
// These are necessary because of the sleep call.
|
||||
|
||||
if (get_dist(A, D) > 1)
|
||||
A << "[D] is too far away!"
|
||||
return 0
|
||||
|
||||
if (!isturf(A.loc) || !isturf(D.loc))
|
||||
A << "You can't throw [D] from here!"
|
||||
return 0
|
||||
|
||||
D.forceMove(A.loc) // Maybe this will help with the wallthrowing bug.
|
||||
|
||||
A.visible_message("<span class = 'danger'><B>[A] throws [D]!</B></span>")
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
var/turf/T = get_edge_target_turf(A, A.dir)
|
||||
if (T && isturf(T))
|
||||
if (!D.stat)
|
||||
D.emote("scream")
|
||||
D.throw_at(T, 10, 4)
|
||||
D.Weaken(2)
|
||||
|
||||
return 0
|
||||
|
||||
/datum/martial_art/wrestling/proc/slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
return
|
||||
if(!A.pulling || A.pulling != D)
|
||||
A << "You need to have [D] in a cinch!"
|
||||
return
|
||||
D.forceMove(A.loc)
|
||||
A.setDir(get_dir(A, D))
|
||||
D.setDir(get_dir(D, A))
|
||||
|
||||
A.visible_message("<span class = 'danger'><B>[A] lifts [D] up!</B></span>")
|
||||
|
||||
spawn (0)
|
||||
if (D)
|
||||
animate(D, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0)
|
||||
sleep (15)
|
||||
if (D)
|
||||
animate(D, transform = null, time = 1, loop = 0)
|
||||
|
||||
for (var/i = 0, i < 3, i++)
|
||||
if (A && D)
|
||||
A.pixel_y += 3
|
||||
D.pixel_y += 3
|
||||
A.setDir(turn(A.dir, 90))
|
||||
D.setDir(turn(D.dir, 90))
|
||||
|
||||
switch (A.dir)
|
||||
if (NORTH)
|
||||
D.pixel_x = A.pixel_x
|
||||
if (SOUTH)
|
||||
D.pixel_x = A.pixel_x
|
||||
if (EAST)
|
||||
D.pixel_x = A.pixel_x - 8
|
||||
if (WEST)
|
||||
D.pixel_x = A.pixel_x + 8
|
||||
|
||||
if (get_dist(A, D) > 1)
|
||||
A << "[D] is too far away!"
|
||||
A.pixel_x = 0
|
||||
A.pixel_y = 0
|
||||
D.pixel_x = 0
|
||||
D.pixel_y = 0
|
||||
return 0
|
||||
|
||||
if (!isturf(A.loc) || !isturf(D.loc))
|
||||
A << "You can't slam [D] here!"
|
||||
A.pixel_x = 0
|
||||
A.pixel_y = 0
|
||||
D.pixel_x = 0
|
||||
D.pixel_y = 0
|
||||
return 0
|
||||
else
|
||||
if (A)
|
||||
A.pixel_x = 0
|
||||
A.pixel_y = 0
|
||||
if (D)
|
||||
D.pixel_x = 0
|
||||
D.pixel_y = 0
|
||||
return 0
|
||||
|
||||
sleep (1)
|
||||
|
||||
if (A && D)
|
||||
A.pixel_x = 0
|
||||
A.pixel_y = 0
|
||||
D.pixel_x = 0
|
||||
D.pixel_y = 0
|
||||
|
||||
if (get_dist(A, D) > 1)
|
||||
A << "[D] is too far away!"
|
||||
return 0
|
||||
|
||||
if (!isturf(A.loc) || !isturf(D.loc))
|
||||
A << "You can't slam [D] here!"
|
||||
return 0
|
||||
|
||||
D.forceMove(A.loc)
|
||||
|
||||
var/fluff = "body-slam"
|
||||
switch(pick(2,3))
|
||||
if (2)
|
||||
fluff = "turbo [fluff]"
|
||||
if (3)
|
||||
fluff = "atomic [fluff]"
|
||||
|
||||
A.visible_message("<span class = 'danger'><B>[A] [fluff] [D]!</B></span>")
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
if (!D.stat)
|
||||
D.emote("scream")
|
||||
D.weakened += 2
|
||||
D.stunned += 2
|
||||
|
||||
switch(rand(1,3))
|
||||
if (2)
|
||||
D.adjustBruteLoss(rand(20,30))
|
||||
if (3)
|
||||
D.ex_act(3)
|
||||
else
|
||||
D.adjustBruteLoss(rand(10,20))
|
||||
else
|
||||
D.ex_act(3)
|
||||
|
||||
else
|
||||
if (A)
|
||||
A.pixel_x = 0
|
||||
A.pixel_y = 0
|
||||
if (D)
|
||||
D.pixel_x = 0
|
||||
D.pixel_y = 0
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
/datum/martial_art/wrestling/proc/strike(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
return
|
||||
var/turf/T = get_turf(A)
|
||||
if (T && isturf(T) && D && isturf(D.loc))
|
||||
for (var/i = 0, i < 4, i++)
|
||||
A.setDir(turn(A.dir, 90))
|
||||
|
||||
A.forceMove(D.loc)
|
||||
spawn (4)
|
||||
if (A && (T && isturf(T) && get_dist(A, T) <= 1))
|
||||
A.forceMove(T)
|
||||
|
||||
A.visible_message("<span class = 'danger'><b>[A] headbutts [D]!</b></span>")
|
||||
D.adjustBruteLoss(rand(10,20))
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
D.Paralyse(1)
|
||||
|
||||
/datum/martial_art/wrestling/proc/kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
return
|
||||
A.emote("scream")
|
||||
A.emote("flip")
|
||||
A.setDir(turn(A.dir, 90))
|
||||
|
||||
A.visible_message("<span class = 'danger'><B>[A] roundhouse-kicks [D]!</B></span>")
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
D.adjustBruteLoss(rand(10,20))
|
||||
|
||||
var/turf/T = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
|
||||
if (T && isturf(T))
|
||||
D.Weaken(1)
|
||||
D.throw_at(T, 3, 2)
|
||||
|
||||
/datum/martial_art/wrestling/proc/drop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
return
|
||||
var/obj/surface = null
|
||||
var/turf/ST = null
|
||||
var/falling = 0
|
||||
|
||||
for (var/obj/O in oview(1, A))
|
||||
if (O.density == 1)
|
||||
if (O == A) continue
|
||||
if (O == D) continue
|
||||
if (O.opacity) continue
|
||||
else
|
||||
surface = O
|
||||
ST = get_turf(O)
|
||||
break
|
||||
|
||||
if (surface && (ST && isturf(ST)))
|
||||
A.forceMove(ST)
|
||||
A.visible_message("<span class = 'danger'><B>[A] climbs onto [surface]!</b></span>")
|
||||
A.pixel_y = 10
|
||||
falling = 1
|
||||
sleep(10)
|
||||
|
||||
if (A && D)
|
||||
// These are necessary because of the sleep call.
|
||||
|
||||
if ((falling == 0 && get_dist(A, D) > 1) || (falling == 1 && get_dist(A, D) > 2)) // We climbed onto stuff.
|
||||
A.pixel_y = 0
|
||||
if (falling == 1)
|
||||
A.visible_message("<span class = 'danger'><B>...and dives head-first into the ground, ouch!</b></span>")
|
||||
A.adjustBruteLoss(rand(10,20))
|
||||
A.Weaken(3)
|
||||
A << "[D] is too far away!"
|
||||
return 0
|
||||
|
||||
if (!isturf(A.loc) || !isturf(D.loc))
|
||||
A.pixel_y = 0
|
||||
A << "You can't drop onto [D] from here!"
|
||||
return 0
|
||||
|
||||
if(A)
|
||||
animate(A, transform = matrix(90, MATRIX_ROTATE), time = 1, loop = 0)
|
||||
sleep(10)
|
||||
if(A)
|
||||
animate(A, transform = null, time = 1, loop = 0)
|
||||
|
||||
A.forceMove(D.loc)
|
||||
|
||||
A.visible_message("<span class = 'danger'><B>[A] leg-drops [D]!</B></span>")
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
A.emote("scream")
|
||||
|
||||
if (falling == 1)
|
||||
if (prob(33) || D.stat)
|
||||
D.ex_act(3)
|
||||
else
|
||||
D.adjustBruteLoss(rand(20,30))
|
||||
else
|
||||
D.adjustBruteLoss(rand(20,30))
|
||||
|
||||
D.Weaken(1)
|
||||
D.Stun(2)
|
||||
|
||||
A.pixel_y = 0
|
||||
|
||||
else
|
||||
if (A)
|
||||
A.pixel_y = 0
|
||||
return
|
||||
|
||||
/datum/martial_art/wrestling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
..()
|
||||
|
||||
/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.pulling == D)
|
||||
return 1
|
||||
A.start_pulling(D)
|
||||
D.visible_message("<span class='danger'>[A] gets [D] in a cinch!</span>", \
|
||||
"<span class='userdanger'>[A] gets [D] in a cinch!</span>")
|
||||
D.Stun(rand(3,5))
|
||||
return 1
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
|
||||
|
||||
Variables:
|
||||
amount - raw amount of the mineral this container is holding, calculated by the defined value MINERAL_MATERIAL_AMOUNT=2000.
|
||||
max_amount - max raw amount of mineral this container can hold.
|
||||
sheet_type - type of the mineral sheet the container handles, used for output.
|
||||
owner - object that this container is being used by, used for output.
|
||||
MAX_STACK_SIZE - size of a stack of mineral sheets. Constant.
|
||||
*/
|
||||
|
||||
/datum/material_container
|
||||
var/total_amount = 0
|
||||
var/max_amount
|
||||
var/sheet_type
|
||||
var/obj/owner
|
||||
var/list/materials = list()
|
||||
//MAX_STACK_SIZE = 50
|
||||
//MINERAL_MATERIAL_AMOUNT = 2000
|
||||
|
||||
/datum/material_container/New(obj/O, list/mat_list, max_amt = 0)
|
||||
owner = O
|
||||
max_amount = max(0, max_amt)
|
||||
|
||||
var/list/possible_mats = list()
|
||||
for(var/mat_type in subtypesof(/datum/material))
|
||||
var/datum/material/MT = mat_type
|
||||
possible_mats[initial(MT.id)] = mat_type
|
||||
|
||||
for(var/id in mat_list)
|
||||
if(possible_mats[id])
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
|
||||
/datum/material_container/Destroy()
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
//For inserting an amount of material
|
||||
/datum/material_container/proc/insert_amount(amt, id = null)
|
||||
if(amt > 0 && has_space(amt))
|
||||
var/total_amount_saved = total_amount
|
||||
if(id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M)
|
||||
M.amount += amt
|
||||
total_amount += amt
|
||||
else
|
||||
for(var/i in materials)
|
||||
var/datum/material/M = materials[i]
|
||||
M.amount += amt
|
||||
total_amount += amt
|
||||
return (total_amount - total_amount_saved)
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/insert_stack(obj/item/stack/S, amt = 0)
|
||||
if(amt <= 0)
|
||||
return 0
|
||||
if(amt > S.amount)
|
||||
amt = S.amount
|
||||
|
||||
var/material_amt = get_item_material_amount(S)
|
||||
if(!material_amt)
|
||||
return 0
|
||||
|
||||
amt = min(amt, round(((max_amount - total_amount) / material_amt)))
|
||||
if(!amt)
|
||||
return 0
|
||||
|
||||
insert_materials(S,amt)
|
||||
S.use(amt)
|
||||
return amt
|
||||
|
||||
/datum/material_container/proc/insert_item(obj/item/I, multiplier = 1)
|
||||
if(!I)
|
||||
return 0
|
||||
if(istype(I,/obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
return insert_stack(I, S.amount)
|
||||
|
||||
var/material_amount = get_item_material_amount(I)
|
||||
if(!material_amount || !has_space(material_amount))
|
||||
return 0
|
||||
|
||||
insert_materials(I, multiplier)
|
||||
return material_amount
|
||||
|
||||
/datum/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
M.amount += I.materials[MAT] * multiplier
|
||||
total_amount += I.materials[MAT] * multiplier
|
||||
|
||||
//For consuming material
|
||||
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
|
||||
/datum/material_container/proc/use_amount(list/mats, multiplier=1)
|
||||
if(!mats || !mats.len)
|
||||
return 0
|
||||
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
if(M.amount < (mats[MAT] * multiplier))
|
||||
return 0
|
||||
|
||||
var/total_amount_save = total_amount
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
M.amount -= mats[MAT] * multiplier
|
||||
total_amount -= mats[MAT] * multiplier
|
||||
|
||||
return total_amount_save - total_amount
|
||||
|
||||
|
||||
/datum/material_container/proc/use_amount_type(amt, id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M)
|
||||
if(M.amount >= amt)
|
||||
M.amount -= amt
|
||||
total_amount -= amt
|
||||
return amt
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/can_use_amount(amt, id, list/mats)
|
||||
if(amt && id)
|
||||
var/datum/material/M = materials[id]
|
||||
if(M && M.amount >= amt)
|
||||
return TRUE
|
||||
else if(istype(mats))
|
||||
for(var/M in mats)
|
||||
if(materials[M] && (mats[M] <= materials[M]))
|
||||
continue
|
||||
else
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//For spawning mineral sheets; internal use only
|
||||
/datum/material_container/proc/retrieve(sheet_amt, datum/material/M)
|
||||
if(sheet_amt > 0)
|
||||
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
new M.sheet_type(get_turf(owner), MAX_STACK_SIZE)
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
|
||||
if(round(M.amount / MINERAL_MATERIAL_AMOUNT))
|
||||
new M.sheet_type(get_turf(owner), sheet_amt)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
return count
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/retrieve_sheets(sheet_amt, id)
|
||||
if(materials[id])
|
||||
return retrieve(sheet_amt, materials[id])
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/retrieve_amount(amt, id)
|
||||
return retrieve_sheets(amount2sheet(amt), id)
|
||||
|
||||
/datum/material_container/proc/retrieve_all()
|
||||
var/result = 0
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(M.amount), MAT)
|
||||
return result
|
||||
|
||||
/datum/material_container/proc/has_space(amt = 0)
|
||||
return (total_amount + amt) <= max_amount
|
||||
|
||||
/datum/material_container/proc/has_materials(list/mats, multiplier=1)
|
||||
if(!mats || !mats.len)
|
||||
return 0
|
||||
|
||||
var/datum/material/M
|
||||
for(var/MAT in mats)
|
||||
M = materials[MAT]
|
||||
if(M.amount < (mats[MAT] * multiplier))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/material_container/proc/amount2sheet(amt)
|
||||
if(amt >= MINERAL_MATERIAL_AMOUNT)
|
||||
return round(amt / MINERAL_MATERIAL_AMOUNT)
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/sheet2amount(sheet_amt)
|
||||
if(sheet_amt > 0)
|
||||
return sheet_amt * MINERAL_MATERIAL_AMOUNT
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/amount(id)
|
||||
var/datum/material/M = materials[id]
|
||||
return M ? M.amount : 0
|
||||
|
||||
//returns the amount of material relevant to this container;
|
||||
//if this container does not support glass, any glass in 'I' will not be taken into account
|
||||
/datum/material_container/proc/get_item_material_amount(obj/item/I)
|
||||
if(!istype(I))
|
||||
return 0
|
||||
var/material_amount = 0
|
||||
for(var/MAT in materials)
|
||||
material_amount += I.materials[MAT]
|
||||
return material_amount
|
||||
|
||||
|
||||
/datum/material
|
||||
var/name
|
||||
var/amount = 0
|
||||
var/id = null
|
||||
var/sheet_type = null
|
||||
|
||||
/datum/material/metal
|
||||
name = "Metal"
|
||||
id = MAT_METAL
|
||||
sheet_type = /obj/item/stack/sheet/metal
|
||||
|
||||
/datum/material/glass
|
||||
name = "Glass"
|
||||
id = MAT_GLASS
|
||||
sheet_type = /obj/item/stack/sheet/glass
|
||||
|
||||
/datum/material/silver
|
||||
name = "Silver"
|
||||
id = MAT_SILVER
|
||||
sheet_type = /obj/item/stack/sheet/mineral/silver
|
||||
|
||||
/datum/material/gold
|
||||
name = "Gold"
|
||||
id = MAT_GOLD
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
|
||||
/datum/material/diamond
|
||||
name = "Diamond"
|
||||
id = MAT_DIAMOND
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
|
||||
/datum/material/uranium
|
||||
name = "Uranium"
|
||||
id = MAT_URANIUM
|
||||
sheet_type = /obj/item/stack/sheet/mineral/uranium
|
||||
|
||||
/datum/material/plasma
|
||||
name = "Solid Plasma"
|
||||
id = MAT_PLASMA
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
|
||||
/datum/material/bananium
|
||||
name = "Bananium"
|
||||
id = MAT_BANANIUM
|
||||
sheet_type = /obj/item/stack/sheet/mineral/bananium
|
||||
+1789
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,642 @@
|
||||
/var/global/list/mutations_list = list()
|
||||
|
||||
/datum/mutation/
|
||||
|
||||
var/name
|
||||
|
||||
/datum/mutation/New()
|
||||
mutations_list[name] = src
|
||||
|
||||
/datum/mutation/human
|
||||
|
||||
var/dna_block
|
||||
var/quality
|
||||
var/get_chance = 100
|
||||
var/lowest_value = 256 * 8
|
||||
var/text_gain_indication = ""
|
||||
var/text_lose_indication = ""
|
||||
var/list/visual_indicators = list()
|
||||
var/layer_used = MUTATIONS_LAYER //which mutation layer to use
|
||||
var/list/species_allowed = list() //to restrict mutation to only certain species
|
||||
var/health_req //minimum health required to acquire the mutation
|
||||
var/limb_req //required limbs to acquire this mutation
|
||||
var/time_coeff = 1 //coefficient for timed mutations
|
||||
|
||||
/datum/mutation/human/proc/force_give(mob/living/carbon/human/owner)
|
||||
set_block(owner)
|
||||
. = on_acquiring(owner)
|
||||
|
||||
/datum/mutation/human/proc/force_lose(mob/living/carbon/human/owner)
|
||||
set_block(owner, 0)
|
||||
. = on_losing(owner)
|
||||
|
||||
/datum/mutation/human/proc/set_se(se_string, on = 1)
|
||||
if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE)
|
||||
return
|
||||
var/before = copytext(se_string, 1, ((dna_block - 1) * DNA_BLOCK_SIZE) + 1)
|
||||
var/injection = num2hex(on ? rand(lowest_value, (256 * 16) - 1) : rand(0, lowest_value - 1), DNA_BLOCK_SIZE)
|
||||
var/after = copytext(se_string, (dna_block * DNA_BLOCK_SIZE) + 1, 0)
|
||||
return before + injection + after
|
||||
|
||||
/datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1)
|
||||
if(owner && owner.has_dna())
|
||||
owner.dna.struc_enzymes = set_se(owner.dna.struc_enzymes, on)
|
||||
|
||||
/datum/mutation/human/proc/check_block_string(se_string)
|
||||
if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE)
|
||||
return 0
|
||||
if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
|
||||
return 1
|
||||
|
||||
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner)
|
||||
if(check_block_string(owner.dna.struc_enzymes))
|
||||
if(prob(get_chance))
|
||||
. = on_acquiring(owner)
|
||||
else
|
||||
. = on_losing(owner)
|
||||
|
||||
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(!owner || !istype(owner) || owner.stat == DEAD || (src in owner.dna.mutations))
|
||||
return 1
|
||||
if(species_allowed.len && !species_allowed.Find(owner.dna.species.id))
|
||||
return 1
|
||||
if(health_req && owner.health < health_req)
|
||||
return 1
|
||||
if(limb_req && !owner.get_bodypart(limb_req))
|
||||
return 1
|
||||
owner.dna.mutations.Add(src)
|
||||
if(text_gain_indication)
|
||||
owner << text_gain_indication
|
||||
if(visual_indicators.len)
|
||||
var/list/mut_overlay = list(get_visual_indicator(owner))
|
||||
if(owner.overlays_standing[layer_used])
|
||||
mut_overlay = owner.overlays_standing[layer_used]
|
||||
mut_overlay |= get_visual_indicator(owner)
|
||||
owner.remove_overlay(layer_used)
|
||||
owner.overlays_standing[layer_used] = mut_overlay
|
||||
owner.apply_overlay(layer_used)
|
||||
|
||||
/datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/on_move(mob/living/carbon/human/owner, new_loc)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/on_life(mob/living/carbon/human/owner)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/on_losing(mob/living/carbon/human/owner)
|
||||
if(owner && istype(owner) && (owner.dna.mutations.Remove(src)))
|
||||
if(text_lose_indication && owner.stat != DEAD)
|
||||
owner << text_lose_indication
|
||||
if(visual_indicators.len)
|
||||
var/list/mut_overlay = list()
|
||||
if(owner.overlays_standing[layer_used])
|
||||
mut_overlay = owner.overlays_standing[layer_used]
|
||||
owner.remove_overlay(layer_used)
|
||||
mut_overlay.Remove(get_visual_indicator(owner))
|
||||
owner.overlays_standing[layer_used] = mut_overlay
|
||||
owner.apply_overlay(layer_used)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/mutation/human/proc/say_mod(message)
|
||||
if(message)
|
||||
return message
|
||||
|
||||
/datum/mutation/human/proc/get_spans()
|
||||
return list()
|
||||
|
||||
/datum/mutation/human/hulk
|
||||
|
||||
name = "Hulk"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
|
||||
species_allowed = list("human") //no skeleton/lizard hulk
|
||||
health_req = 25
|
||||
|
||||
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
|
||||
owner.status_flags &= ~status
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target)
|
||||
return target.attack_hulk(owner)
|
||||
|
||||
/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.health < 0)
|
||||
on_losing(owner)
|
||||
owner << "<span class='danger'>You suddenly feel very weak.</span>"
|
||||
|
||||
/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
|
||||
owner.update_body_parts()
|
||||
|
||||
/datum/mutation/human/hulk/say_mod(message)
|
||||
if(message)
|
||||
message = "[uppertext(replacetext(message, ".", "!"))]!!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/telekinesis
|
||||
|
||||
name = "Telekinesis"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel smarter!</span>"
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/telekinesis/New()
|
||||
..()
|
||||
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="telekinesishead_s", "layer"=-MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
target.attack_tk(owner)
|
||||
|
||||
/datum/mutation/human/cold_resistance
|
||||
|
||||
name = "Cold Resistance"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your body feels warm!</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/cold_resistance/New()
|
||||
..()
|
||||
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="fire_s", "layer"=-MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
|
||||
if(owner.getFireLoss())
|
||||
if(prob(1))
|
||||
owner.heal_organ_damage(0,1) //Is this really needed?
|
||||
|
||||
/datum/mutation/human/x_ray
|
||||
|
||||
name = "X Ray Vision"
|
||||
quality = POSITIVE
|
||||
get_chance = 25
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>The walls suddenly disappear!</span>"
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
|
||||
owner.update_sight()
|
||||
|
||||
/datum/mutation/human/x_ray/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.update_sight()
|
||||
|
||||
/datum/mutation/human/nearsight
|
||||
|
||||
name = "Near Sightness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't see very well.</span>"
|
||||
|
||||
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_nearsighted()
|
||||
|
||||
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_nearsighted()
|
||||
|
||||
/datum/mutation/human/epilepsy
|
||||
|
||||
name = "Epilepsy"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You get a headache.</span>"
|
||||
|
||||
/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(1) && !owner.paralysis)
|
||||
owner.visible_message("<span class='danger'>[owner] starts having a seizure!</span>", "<span class='userdanger'>You have a seizure!</span>")
|
||||
owner.Paralyse(10)
|
||||
owner.Jitter(1000)
|
||||
addtimer(src, "jitter_less", 90, FALSE, owner)
|
||||
|
||||
/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner)
|
||||
if(owner)
|
||||
owner.jitteriness = 10
|
||||
|
||||
/datum/mutation/human/bad_dna
|
||||
name = "Unstable DNA"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel strange.</span>"
|
||||
|
||||
/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner)
|
||||
owner << text_gain_indication
|
||||
var/mob/new_mob
|
||||
if(prob(95))
|
||||
if(prob(50))
|
||||
new_mob = randmutb(owner)
|
||||
else
|
||||
new_mob = randmuti(owner)
|
||||
else
|
||||
new_mob = randmutg(owner)
|
||||
if(new_mob && ismob(new_mob))
|
||||
owner = new_mob
|
||||
. = owner
|
||||
on_losing(owner)
|
||||
|
||||
/datum/mutation/human/cough
|
||||
name = "Cough"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You start coughing.</span>"
|
||||
|
||||
/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
|
||||
if((prob(5) && owner.paralysis <= 1))
|
||||
owner.drop_item()
|
||||
owner.emote("cough")
|
||||
|
||||
/datum/mutation/human/dwarfism
|
||||
name = "Dwarfism"
|
||||
quality = POSITIVE
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
|
||||
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 0.8
|
||||
owner.update_transform()
|
||||
owner.pass_flags |= PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
|
||||
|
||||
/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.resize = 1.25
|
||||
owner.update_transform()
|
||||
owner.pass_flags &= ~PASSTABLE
|
||||
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
|
||||
|
||||
/datum/mutation/human/clumsy
|
||||
|
||||
name = "Clumsiness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel lightheaded.</span>"
|
||||
|
||||
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= CLUMSY
|
||||
|
||||
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~CLUMSY
|
||||
|
||||
/datum/mutation/human/tourettes
|
||||
name = "Tourettes Syndrome"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You twitch.</span>"
|
||||
|
||||
/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner)
|
||||
if((prob(10) && owner.paralysis <= 1))
|
||||
owner.Stun(10)
|
||||
switch(rand(1, 3))
|
||||
if(1)
|
||||
owner.emote("twitch")
|
||||
if(2 to 3)
|
||||
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
|
||||
var/x_offset_old = owner.pixel_x
|
||||
var/y_offset_old = owner.pixel_y
|
||||
var/x_offset = owner.pixel_x + rand(-2,2)
|
||||
var/y_offset = owner.pixel_y + rand(-1,1)
|
||||
animate(owner, pixel_x = x_offset, pixel_y = y_offset, time = 1)
|
||||
animate(owner, pixel_x = x_offset_old, pixel_y = y_offset_old, time = 1)
|
||||
|
||||
/datum/mutation/human/nervousness
|
||||
name = "Nervousness"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel nervous.</span>"
|
||||
|
||||
/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner)
|
||||
if(prob(10))
|
||||
owner.stuttering = max(10, owner.stuttering)
|
||||
|
||||
/datum/mutation/human/deaf
|
||||
name = "Deafness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to hear anything.</span>"
|
||||
|
||||
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= DEAF
|
||||
|
||||
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~DEAF
|
||||
|
||||
/datum/mutation/human/blind
|
||||
name = "Blindness"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to see anything.</span>"
|
||||
|
||||
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.become_blind()
|
||||
|
||||
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.cure_blind()
|
||||
|
||||
|
||||
/datum/mutation/human/race
|
||||
name = "Monkified"
|
||||
quality = NEGATIVE
|
||||
time_coeff = 2
|
||||
|
||||
/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
. = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner)
|
||||
if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src)))
|
||||
. = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
/datum/mutation/human/chameleon
|
||||
name = "Chameleon"
|
||||
quality = POSITIVE
|
||||
get_chance = 20
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>You feel one with your surroundings.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel oddly exposed.</span>"
|
||||
time_coeff = 5
|
||||
|
||||
/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner)
|
||||
owner.alpha = max(0, owner.alpha - 25)
|
||||
|
||||
/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
|
||||
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
|
||||
|
||||
/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.alpha = 255
|
||||
|
||||
/datum/mutation/human/wacky
|
||||
name = "Wacky"
|
||||
quality = MINOR_NEGATIVE
|
||||
text_gain_indication = "<span class='sans'>You feel an off sensation in your voicebox.</span>"
|
||||
text_lose_indication = "<span class='notice'>The off sensation passes.</span>"
|
||||
|
||||
/datum/mutation/human/wacky/get_spans()
|
||||
return list(SPAN_SANS)
|
||||
|
||||
/datum/mutation/human/mute
|
||||
name = "Mute"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You feel unable to express yourself at all.</span>"
|
||||
text_lose_indication = "<span class='danger'>You feel able to speak freely again.</span>"
|
||||
|
||||
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities |= MUTE
|
||||
|
||||
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.disabilities &= ~MUTE
|
||||
|
||||
/datum/mutation/human/smile
|
||||
name = "Smile"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel so happy. Nothing can be wrong with anything. :)</span>"
|
||||
text_lose_indication = "<span class='notice'>Everything is terrible again. :(</span>"
|
||||
|
||||
/datum/mutation/human/smile/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
//Time for a friendly game of SS13
|
||||
message = replacetext(message," stupid "," smart ")
|
||||
message = replacetext(message," retard "," genius ")
|
||||
message = replacetext(message," unrobust "," robust ")
|
||||
message = replacetext(message," dumb "," smart ")
|
||||
message = replacetext(message," awful "," great ")
|
||||
message = replacetext(message," gay ",pick(" nice "," ok "," alright "))
|
||||
message = replacetext(message," horrible "," fun ")
|
||||
message = replacetext(message," terrible "," terribly fun ")
|
||||
message = replacetext(message," terrifying "," wonderful ")
|
||||
message = replacetext(message," gross "," cool ")
|
||||
message = replacetext(message," disgusting "," amazing ")
|
||||
message = replacetext(message," loser "," winner ")
|
||||
message = replacetext(message," useless "," useful ")
|
||||
message = replacetext(message," oh god "," cheese and crackers ")
|
||||
message = replacetext(message," jesus "," gee wiz ")
|
||||
message = replacetext(message," weak "," strong ")
|
||||
message = replacetext(message," kill "," hug ")
|
||||
message = replacetext(message," murder "," tease ")
|
||||
message = replacetext(message," ugly "," beautiful ")
|
||||
message = replacetext(message," douchbag "," nice guy ")
|
||||
message = replacetext(message," whore "," lady ")
|
||||
message = replacetext(message," nerd "," smart guy ")
|
||||
message = replacetext(message," moron "," fun person ")
|
||||
message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ")
|
||||
message = replacetext(message," sex "," hug fight ")
|
||||
message = replacetext(message," idiot "," genius ")
|
||||
message = replacetext(message," fat "," thin ")
|
||||
message = replacetext(message," beer "," water with ice ")
|
||||
message = replacetext(message," drink "," water ")
|
||||
message = replacetext(message," feminist "," empowered woman ")
|
||||
message = replacetext(message," i hate you "," you're mean ")
|
||||
message = replacetext(message," nigger "," african american ")
|
||||
message = replacetext(message," jew "," jewish ")
|
||||
message = replacetext(message," shit "," shiz ")
|
||||
message = replacetext(message," crap "," poo ")
|
||||
message = replacetext(message," slut "," tease ")
|
||||
message = replacetext(message," ass "," butt ")
|
||||
message = replacetext(message," damn "," dang ")
|
||||
message = replacetext(message," fuck "," ")
|
||||
message = replacetext(message," penis "," privates ")
|
||||
message = replacetext(message," cunt "," privates ")
|
||||
message = replacetext(message," dick "," jerk ")
|
||||
message = replacetext(message," vagina "," privates ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/unintelligable
|
||||
name = "Unintelligable"
|
||||
quality = NEGATIVE
|
||||
text_gain_indication = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
|
||||
text_lose_indication = "<span class='danger'>Your mind feels more clear.</span>"
|
||||
|
||||
/datum/mutation/human/unintelligable/say_mod(message)
|
||||
if(message)
|
||||
var/prefix=copytext(message,1,2)
|
||||
if(prefix == ";")
|
||||
message = copytext(message,2)
|
||||
else if(prefix in list(":","#"))
|
||||
prefix += copytext(message,2,3)
|
||||
message = copytext(message,3)
|
||||
else
|
||||
prefix=""
|
||||
|
||||
var/list/words = splittext(message," ")
|
||||
var/list/rearranged = list()
|
||||
for(var/i=1;i<=words.len;i++)
|
||||
var/cword = pick(words)
|
||||
words.Remove(cword)
|
||||
var/suffix = copytext(cword,length(cword)-1,length(cword))
|
||||
while(length(cword)>0 && suffix in list(".",",",";","!",":","?"))
|
||||
cword = copytext(cword,1 ,length(cword)-1)
|
||||
suffix = copytext(cword,length(cword)-1,length(cword) )
|
||||
if(length(cword))
|
||||
rearranged += cword
|
||||
message = "[prefix][uppertext(jointext(rearranged," "))]!!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/swedish
|
||||
name = "Swedish"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel Swedish, however that works.</span>"
|
||||
text_lose_indication = "<span class='notice'>The feeling of Swedishness passes.</span>"
|
||||
|
||||
/datum/mutation/human/swedish/say_mod(message)
|
||||
if(message)
|
||||
message = replacetext(message,"w","v")
|
||||
if(prob(30))
|
||||
message += " Bork[pick("",", bork",", bork, bork")]!"
|
||||
return message
|
||||
|
||||
/datum/mutation/human/chav
|
||||
name = "Chav"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>Ye feel like a reet prat like, innit?</span>"
|
||||
text_lose_indication = "<span class='notice'>You no longer feel like being rude and sassy.</span>"
|
||||
|
||||
/datum/mutation/human/chav/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," looking at "," gawpin' at ")
|
||||
message = replacetext(message," great "," bangin' ")
|
||||
message = replacetext(message," man "," mate ")
|
||||
message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin "))
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," drink "," wet ")
|
||||
message = replacetext(message," get "," giz ")
|
||||
message = replacetext(message," what "," wot ")
|
||||
message = replacetext(message," no thanks "," wuddent fukken do one ")
|
||||
message = replacetext(message," i don't know "," wot mate ")
|
||||
message = replacetext(message," no "," naw ")
|
||||
message = replacetext(message," robust "," chin ")
|
||||
message = replacetext(message," hi "," how what how ")
|
||||
message = replacetext(message," hello "," sup bruv ")
|
||||
message = replacetext(message," kill "," bang ")
|
||||
message = replacetext(message," murder "," bang ")
|
||||
message = replacetext(message," windows "," windies ")
|
||||
message = replacetext(message," window "," windy ")
|
||||
message = replacetext(message," break "," do ")
|
||||
message = replacetext(message," your "," yer ")
|
||||
message = replacetext(message," security "," coppers ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/elvis
|
||||
name = "Elvis"
|
||||
quality = MINOR_NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pretty good, honeydoll.</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel a little less conversation would be great.</span>"
|
||||
|
||||
/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner)
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
if(prob(15))
|
||||
var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing")
|
||||
var/dancemoves = pick(dancetypes)
|
||||
owner.visible_message("<b>[owner]</b> busts out some [dancemoves] moves!")
|
||||
if(2)
|
||||
if(prob(15))
|
||||
owner.visible_message("<b>[owner]</b> [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
|
||||
|
||||
/datum/mutation/human/elvis/say_mod(message)
|
||||
if(message)
|
||||
message = " [message] "
|
||||
message = replacetext(message," i'm not "," I aint ")
|
||||
message = replacetext(message," girl ",pick(" honey "," baby "," baby doll "))
|
||||
message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo "))
|
||||
message = replacetext(message," out of "," outta ")
|
||||
message = replacetext(message," thank you "," thank you, thank you very much ")
|
||||
message = replacetext(message," what are you "," whatcha ")
|
||||
message = replacetext(message," yes ",pick(" sure", "yea "))
|
||||
message = replacetext(message," faggot "," square ")
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/laser_eyes
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pressure building up behind your eyes.</span>"
|
||||
layer_used = FRONT_MUTATIONS_LAYER
|
||||
limb_req = "head"
|
||||
|
||||
/datum/mutation/human/laser_eyes/New()
|
||||
..()
|
||||
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes_s", "layer"=-FRONT_MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
if(owner.a_intent == "harm")
|
||||
owner.LaserEyes(target)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/update_mutations_overlay()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/update_mutations_overlay()
|
||||
for(var/datum/mutation/human/CM in dna.mutations)
|
||||
if(CM.species_allowed.len && !CM.species_allowed.Find(dna.species.id))
|
||||
CM.force_lose(src) //shouldn't have that mutation at all
|
||||
continue
|
||||
if(CM.visual_indicators.len)
|
||||
var/list/mut_overlay = list()
|
||||
if(overlays_standing[CM.layer_used])
|
||||
mut_overlay = overlays_standing[CM.layer_used]
|
||||
var/image/V = CM.get_visual_indicator(src)
|
||||
if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
|
||||
remove_overlay(CM.layer_used)
|
||||
for(var/image/I in CM.visual_indicators)
|
||||
mut_overlay.Remove(I)
|
||||
mut_overlay |= V
|
||||
overlays_standing[CM.layer_used] = mut_overlay
|
||||
apply_overlay(CM.layer_used)
|
||||
@@ -0,0 +1,75 @@
|
||||
/datum/outfit
|
||||
var/name = "Naked"
|
||||
|
||||
var/uniform = null
|
||||
var/suit = null
|
||||
var/back = null
|
||||
var/belt = null
|
||||
var/gloves = null
|
||||
var/shoes = null
|
||||
var/head = null
|
||||
var/mask = null
|
||||
var/ears = null
|
||||
var/glasses = null
|
||||
var/id = null
|
||||
var/l_pocket = null
|
||||
var/r_pocket = null
|
||||
var/suit_store = null
|
||||
var/r_hand = null
|
||||
var/l_hand = null
|
||||
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
|
||||
|
||||
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overriden for customization depending on client prefs,species etc
|
||||
return
|
||||
|
||||
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overriden for toggling internals, id binding, access etc
|
||||
return
|
||||
|
||||
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
pre_equip(H, visualsOnly)
|
||||
|
||||
//Start with uniform,suit,backpack for additional slots
|
||||
if(uniform)
|
||||
H.equip_to_slot_or_del(new uniform(H),slot_w_uniform)
|
||||
if(suit)
|
||||
H.equip_to_slot_or_del(new suit(H),slot_wear_suit)
|
||||
if(back)
|
||||
H.equip_to_slot_or_del(new back(H),slot_back)
|
||||
if(belt)
|
||||
H.equip_to_slot_or_del(new belt(H),slot_belt)
|
||||
if(gloves)
|
||||
H.equip_to_slot_or_del(new gloves(H),slot_gloves)
|
||||
if(shoes)
|
||||
H.equip_to_slot_or_del(new shoes(H),slot_shoes)
|
||||
if(head)
|
||||
H.equip_to_slot_or_del(new head(H),slot_head)
|
||||
if(mask)
|
||||
H.equip_to_slot_or_del(new mask(H),slot_wear_mask)
|
||||
if(ears)
|
||||
H.equip_to_slot_or_del(new ears(H),slot_ears)
|
||||
if(glasses)
|
||||
H.equip_to_slot_or_del(new glasses(H),slot_glasses)
|
||||
if(id)
|
||||
H.equip_to_slot_or_del(new id(H),slot_wear_id)
|
||||
if(l_pocket)
|
||||
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
|
||||
if(r_pocket)
|
||||
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
|
||||
if(suit_store)
|
||||
H.equip_to_slot_or_del(new suit_store(H),slot_s_store)
|
||||
|
||||
if(l_hand)
|
||||
H.put_in_l_hand(new l_hand(H))
|
||||
if(r_hand)
|
||||
H.put_in_r_hand(new r_hand(H))
|
||||
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
for(var/i=0,i<number,i++)
|
||||
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
|
||||
|
||||
post_equip(H, visualsOnly)
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,42 @@
|
||||
/datum/progressbar
|
||||
var/goal = 1
|
||||
var/image/bar
|
||||
var/shown = 0
|
||||
var/mob/user
|
||||
var/client/client
|
||||
|
||||
/datum/progressbar/New(mob/User, goal_number, atom/target)
|
||||
. = ..()
|
||||
if (!istype(target))
|
||||
EXCEPTION("Invalid target given")
|
||||
if (goal_number)
|
||||
goal = goal_number
|
||||
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0")
|
||||
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
bar.pixel_y = 32
|
||||
user = User
|
||||
if(user)
|
||||
client = user.client
|
||||
|
||||
/datum/progressbar/proc/update(progress)
|
||||
//world << "Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]"
|
||||
if (!user || !user.client)
|
||||
shown = 0
|
||||
return
|
||||
if (user.client != client)
|
||||
if (client)
|
||||
client.images -= bar
|
||||
if (user.client)
|
||||
user.client.images += bar
|
||||
|
||||
progress = Clamp(progress, 0, goal)
|
||||
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
|
||||
if (!shown)
|
||||
user.client.images += bar
|
||||
shown = 1
|
||||
|
||||
/datum/progressbar/Destroy()
|
||||
if (client)
|
||||
client.images -= bar
|
||||
qdel(bar)
|
||||
. = ..()
|
||||
@@ -0,0 +1,120 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* /datum/recipe by rastaf0 13 apr 2011 *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* This is powerful and flexible recipe system.
|
||||
* It exists not only for food.
|
||||
* supports both reagents and objects as prerequisites.
|
||||
* In order to use this system you have to define a deriative from /datum/recipe
|
||||
* * reagents are reagents. Acid, milc, booze, etc.
|
||||
* * items are objects. Fruits, tools, circuit boards.
|
||||
* * result is type to create as new object
|
||||
* * time is optional parameter, you shall use in in your machine,
|
||||
default /datum/recipe/ procs does not rely on this parameter.
|
||||
*
|
||||
* Functions you need:
|
||||
* /datum/recipe/proc/make(var/obj/container as obj)
|
||||
* Creates result inside container,
|
||||
* deletes prerequisite reagents,
|
||||
* transfers reagents from prerequisite objects,
|
||||
* deletes all prerequisite objects (even not needed for recipe at the moment).
|
||||
*
|
||||
* /proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj as obj, exact = 1)
|
||||
* Wonderful function that select suitable recipe for you.
|
||||
* obj is a machine (or magik hat) with prerequisites,
|
||||
* exact = 0 forces algorithm to ignore superfluous stuff.
|
||||
*
|
||||
*
|
||||
* Functions you do not need to call directly but could:
|
||||
* /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents)
|
||||
* //1=precisely, 0=insufficiently, -1=superfluous
|
||||
*
|
||||
* /datum/recipe/proc/check_items(var/obj/container as obj)
|
||||
* //1=precisely, 0=insufficiently, -1=superfluous
|
||||
*
|
||||
* */
|
||||
|
||||
/datum/recipe
|
||||
var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice
|
||||
var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo
|
||||
var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut
|
||||
var/time = 100 // 1/10 part of second
|
||||
|
||||
|
||||
/datum/recipe/proc/check_reagents(datum/reagents/avail_reagents) //1=precisely, 0=insufficiently, -1=superfluous
|
||||
. = 1
|
||||
for (var/r_r in reagents)
|
||||
var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r)
|
||||
if (!(abs(aval_r_amnt - reagents[r_r])<0.5)) //if NOT equals
|
||||
if (aval_r_amnt>reagents[r_r])
|
||||
. = -1
|
||||
else
|
||||
return 0
|
||||
if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len)
|
||||
return -1
|
||||
return .
|
||||
|
||||
/datum/recipe/proc/check_items(obj/container) //1=precisely, 0=insufficiently, -1=superfluous
|
||||
if (!items)
|
||||
if (locate(/obj/) in container)
|
||||
return -1
|
||||
else
|
||||
return 1
|
||||
. = 1
|
||||
var/list/checklist = items.Copy()
|
||||
for (var/obj/O in container)
|
||||
var/found = 0
|
||||
for (var/type in checklist)
|
||||
if (istype(O,type))
|
||||
checklist-=type
|
||||
found = 1
|
||||
break
|
||||
if (!found)
|
||||
. = -1
|
||||
if (checklist.len)
|
||||
return 0
|
||||
return .
|
||||
|
||||
//general version
|
||||
/datum/recipe/proc/make(obj/container)
|
||||
var/obj/result_obj = new result(container)
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
O.reagents.trans_to(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
// food-related
|
||||
/datum/recipe/proc/make_food(obj/container)
|
||||
var/obj/result_obj = new result(container)
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
if (O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
/proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj, exact = 1 as num)
|
||||
if (!exact)
|
||||
exact = -1
|
||||
var/list/datum/recipe/possible_recipes = new
|
||||
for (var/datum/recipe/recipe in avaiable_recipes)
|
||||
if (recipe.check_reagents(obj.reagents)==exact && recipe.check_items(obj)==exact)
|
||||
possible_recipes+=recipe
|
||||
if (possible_recipes.len==0)
|
||||
return null
|
||||
else if (possible_recipes.len==1)
|
||||
return possible_recipes[1]
|
||||
else //okay, let's select the most complicated recipe
|
||||
var/r_count = 0
|
||||
var/i_count = 0
|
||||
. = possible_recipes[1]
|
||||
for (var/datum/recipe/recipe in possible_recipes)
|
||||
var/N_i = (recipe.items)?(recipe.items.len):0
|
||||
var/N_r = (recipe.reagents)?(recipe.reagents.len):0
|
||||
if (N_i > i_count || (N_i== i_count && N_r > r_count ))
|
||||
r_count = N_r
|
||||
i_count = N_i
|
||||
. = recipe
|
||||
return .
|
||||
@@ -0,0 +1,22 @@
|
||||
/datum/map_template/ruin
|
||||
//name = "A Chest of Doubloons"
|
||||
name = null
|
||||
var/id = null // For blacklisting purposes, all ruins need an id
|
||||
var/description = "In the middle of a clearing in the rockface, there's a \
|
||||
chest filled with gold coins with Spanish engravings. How is there a \
|
||||
wooden container filled with 18th century coinage in the middle of a \
|
||||
lavawracked hellscape? It is clearly a mystery."
|
||||
|
||||
var/cost = null
|
||||
var/allow_duplicates = TRUE
|
||||
|
||||
var/prefix = null
|
||||
var/suffix = null
|
||||
|
||||
/datum/map_template/ruin/New()
|
||||
if(!name && id)
|
||||
name = id
|
||||
|
||||
mappath = prefix + suffix
|
||||
..(path = mappath)
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
/datum/map_template/ruin/lavaland
|
||||
prefix = "_maps/RandomRuins/LavaRuins/"
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome
|
||||
cost = 5
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome/beach
|
||||
name = "Biodome Beach"
|
||||
id = "biodome-beach"
|
||||
description = "Seemingly plucked from a tropical destination, this beach \
|
||||
is calm and cool, with the salty waves roaring softly in the \
|
||||
background. Comes with a rustic wooden bar and suicidal bartender."
|
||||
suffix = "lavaland_biodome_beach.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome/winter
|
||||
name = "Biodome Winter"
|
||||
id = "biodome-winter"
|
||||
description = "For those getaways where you want to get back to nature, \
|
||||
but you don't want to leave the fortified military compound where you \
|
||||
spend your days. Includes a unique(*) laser pistol display case, \
|
||||
and the recently introduced I.C.E(tm)."
|
||||
suffix = "lavaland_surface_biodome_winter.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/biodome/clown
|
||||
name = "Biodome Clown Planet"
|
||||
id = "biodome-clown"
|
||||
description = "WELCOME TO CLOWN PLANET! HONK HONK HONK etc.!"
|
||||
suffix = "lavaland_biodome_clown_planet.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/cube
|
||||
name = "The Wishgranter Cube"
|
||||
id = "wishgranter-cube"
|
||||
description = "Nothing good can come from this. Learn from their mistakes \
|
||||
and turn around."
|
||||
suffix = "lavaland_surface_cube.dmm"
|
||||
cost = 10
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/prisoners
|
||||
name = "Prisoner Crash"
|
||||
id = "prisoner-crash"
|
||||
description = "This incredibly high security shuttle clearly didn't have \
|
||||
'avoiding lavafilled hellscapes' as a design priority. As such, it \
|
||||
has crashed, waking the prisoners from their cryostasis, and setting \
|
||||
them loose on the wastes. If they live long enough, that is."
|
||||
suffix = "lavaland_surface_prisoner_crash.dmm"
|
||||
cost = 15
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/seed_vault
|
||||
name = "Seed Vault"
|
||||
id = "seed-vault"
|
||||
description = "The creators of these vaults were a highly advanced and \
|
||||
benevolent race, and launched many into the stars, hoping to aid \
|
||||
fledgling civilizations. However, all the inhabitants seem to do is \
|
||||
grow drugs and guns."
|
||||
suffix = "lavaland_surface_seed_vault.dmm"
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/ruin/lavaland/ash_walker
|
||||
name = "Ash Walker Nest"
|
||||
id = "ash-walker"
|
||||
description = "A race of unbreathing lizards live here, that run faster \
|
||||
than a human can, worship a broken dead city, and are capable of \
|
||||
reproducing by something involving tentacles? Probably best to \
|
||||
stay clear."
|
||||
suffix = "lavaland_surface_ash_walker1.dmm"
|
||||
cost = 20
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/free_golem
|
||||
name = "Free Golem Ship"
|
||||
id = "golem-ship"
|
||||
description = "Lumbering humanoids, made out of precious metals, move \
|
||||
inside this ship. They frequently leave to mine more minerals, \
|
||||
which they somehow turn into more of them. Seem very intent on \
|
||||
research and individual liberty, and also geology based naming?"
|
||||
cost = 20
|
||||
suffix = "lavaland_surface_golem_ship.dmm"
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/animal_hospital
|
||||
name = "Animal Hospital"
|
||||
id = "animal-hospital"
|
||||
description = "Rats with cancer do not live very long. And the ones that \
|
||||
wake up from cryostasis seem to commit suicide out of boredom."
|
||||
cost = 5
|
||||
suffix = "lavaland_surface_animal_hospital.dmm"
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin/envy
|
||||
name = "Ruin of Envy"
|
||||
id = "envy"
|
||||
description = "When you get what they have, then you'll finally be happy."
|
||||
suffix = "lavaland_surface_envy.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin/gluttony
|
||||
name = "Ruin of Gluttony"
|
||||
id = "gluttony"
|
||||
description = "If you eat enough, then eating will be all that you do."
|
||||
suffix = "lavaland_surface_gluttony.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin/greed
|
||||
name = "Ruin of Greed"
|
||||
id = "greed"
|
||||
description = "Sure you don't need magical powers, but you WANT them, and \
|
||||
that's what's important."
|
||||
suffix = "lavaland_surface_greed.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin/pride
|
||||
name = "Ruin of Pride"
|
||||
id = "pride"
|
||||
description = "Wormhole lifebelts are for LOSERS, who you are better than."
|
||||
suffix = "lavaland_surface_pride.dmm"
|
||||
|
||||
/datum/map_template/ruin/lavaland/sin/sloth
|
||||
name = "Ruin of Sloth"
|
||||
id = "sloth"
|
||||
description = "..."
|
||||
suffix = "lavaland_surface_sloth.dmm"
|
||||
// Generates nothing but atmos runtimes and salt
|
||||
cost = 0
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/ato
|
||||
name = "Automated Trade Outpost"
|
||||
id = "ato"
|
||||
description = "A sign at the front says 'Stealing is bad.'"
|
||||
suffix = "lavaland_surface_automated_trade_outpost.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/ufo_crash
|
||||
name = "UFO Crash"
|
||||
id = "ufo-crash"
|
||||
description = "Turns out that keeping your abductees unconcious is really \
|
||||
important. Who knew?"
|
||||
suffix = "lavaland_surface_ufo_crash.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/ww_vault
|
||||
name = "Wishgranter Vault"
|
||||
id = "ww-vault"
|
||||
description = "Scrawled on the large double doors is both a message and a \
|
||||
warning: 'meat grinder requires sacri...'. You're not so sure about \
|
||||
this anymore."
|
||||
suffix = "lavaland_surface_ww_vault.dmm"
|
||||
cost = 20
|
||||
|
||||
/datum/map_template/ruin/lavaland/xeno_nest
|
||||
name = "Xenomorph Nest"
|
||||
id = "xeno-nest"
|
||||
description = "These xenomorphs got bored of horrifically slaughtering \
|
||||
people on space stations, and have settled down on a nice lava filled \
|
||||
hellscape to focus on what's really important in life. Quality memes."
|
||||
suffix = "lavaland_surface_xeno_nest.dmm"
|
||||
cost = 20
|
||||
|
||||
/datum/map_template/ruin/lavaland/fountain
|
||||
name = "Fountain Hall"
|
||||
id = "fountain"
|
||||
description = "The fountain has a warning on the side. DANGER: May have \
|
||||
undeclared side effects that only become obvious when implemented."
|
||||
suffix = "lavaland_surface_fountain_hall.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/survivalcapsule
|
||||
name = "Survival Capsule Ruins"
|
||||
id = "survivalcapsule"
|
||||
description = "What was once sanctuary to the common miner, \
|
||||
is now their tomb."
|
||||
suffix = "lavaland_surface_survivalpod.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/tomb
|
||||
name = "Strange Outpost"
|
||||
id = "tomb"
|
||||
description = "A strange tomb, housing the dead of whatever strange civilization \
|
||||
lived here before. You swear you hear rattling coming from the inside."
|
||||
suffix = "lavaland_surface_tomb.dmm"
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/ruin/lavaland/pizza
|
||||
name = "Ruined Pizza Party"
|
||||
id = "pizza"
|
||||
description = "Little Timmy's birthday pizza-bash took a turn for the worse \
|
||||
when a bluespace anomaly passed by."
|
||||
suffix = "lavaland_surface_pizzaparty.dmm"
|
||||
allow_duplicates = FALSE
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/cultaltar
|
||||
name = "Summoning Ritual"
|
||||
id = "cultaltar"
|
||||
description = "A place of vile worship, the scrawling of blood in the middle glowing eerily.\
|
||||
A demonic laugh echoes throughout the caverns"
|
||||
suffix = "lavaland_surface_cultaltar.dmm"
|
||||
allow_duplicates = FALSE
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/ruin/lavaland/hermit
|
||||
name = "Makeshift Shelter"
|
||||
id = "hermitcave"
|
||||
description = "A place of shelter for a lone hermit, scraping by to live another day."
|
||||
suffix = "lavaland_surface_hermit.dmm"
|
||||
allow_duplicates = FALSE
|
||||
cost = 10
|
||||
|
||||
/datum/map_template/ruin/lavaland/cult_shuttle
|
||||
name = "Crashed Cult Hive"
|
||||
id = "cultshuttle"
|
||||
description = "A once-bustling home for zealots of the blood-worshiping type. Turns out practicing \
|
||||
dark rituals mid-jump isn't the best idea."
|
||||
suffix = "lavaland_surface_cultcrash.dmm"
|
||||
cost = 10
|
||||
@@ -0,0 +1,248 @@
|
||||
/datum/map_template/ruin/space
|
||||
prefix = "_maps/RandomRuins/SpaceRuins/"
|
||||
cost = 1
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/space/zoo
|
||||
id = "zoo"
|
||||
suffix = "abandonedzoo.dmm"
|
||||
name = "Biological Storage Facility"
|
||||
description = "In case society crumbles, we will be able to restore our \
|
||||
zoos to working order with the breeding stock kept in these 100% \
|
||||
secure and unbreachable storage facilities. At no point has anything \
|
||||
escaped. That's our story, and we're sticking to it."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid1
|
||||
id = "asteroid1"
|
||||
suffix = "asteroid1.dmm"
|
||||
name = "Asteroid 1"
|
||||
description = "I-spy with my little eye, something beginning with R."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid2
|
||||
id = "asteroid2"
|
||||
suffix = "asteroid2.dmm"
|
||||
name = "Asteroid 2"
|
||||
description = "Oh my god, a giant rock!"
|
||||
|
||||
/datum/map_template/ruin/space/asteroid3
|
||||
id = "asteroid3"
|
||||
suffix = "asteroid3.dmm"
|
||||
name = "Asteroid 3"
|
||||
description = "This asteroid floating in space has no official \
|
||||
designation, because the scientist that discovered it deemed it \
|
||||
'super dull'."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid4
|
||||
id = "asteroid4"
|
||||
suffix = "asteroid4.dmm"
|
||||
name = "Asteroid 4"
|
||||
description = "Nanotrasen Escape Pods have a 100%* success rate, and a \
|
||||
99%* customer satisfaction rate. *Please note that these statistics, \
|
||||
are taken from pods that have successfully docked with a recovery \
|
||||
vessel."
|
||||
|
||||
/datum/map_template/ruin/space/asteroid5
|
||||
id = "asteroid5"
|
||||
suffix = "asteroid5.dmm"
|
||||
name = "Asteroid 5"
|
||||
description = "Oh my god, another giant rock!"
|
||||
|
||||
/datum/map_template/ruin/space/deep_storage
|
||||
id = "deep-storage"
|
||||
suffix = "deepstorage.dmm"
|
||||
name = "Survivalist Bunker"
|
||||
description = "Assume the best, prepare for the worst. Generally, you \
|
||||
should do so by digging a three man heavily fortified bunker into \
|
||||
a giant unused asteroid. Then make it self sufficient, mask any \
|
||||
evidence of construction, hook it covertly into the \
|
||||
telecommunications network and hope for the best."
|
||||
|
||||
/datum/map_template/ruin/space/derelict1
|
||||
id = "derelict1"
|
||||
suffix = "derelict1.dmm"
|
||||
name = "Derelict 1"
|
||||
description = "Nothing to see here citizen, move along, certainly no \
|
||||
xeno outbreaks on this piece of station debris. That purple stuff? \
|
||||
It's uh... station nectar. It's a top secret research installation."
|
||||
|
||||
/datum/map_template/ruin/space/derelict2
|
||||
id = "derelict2"
|
||||
suffix = "derelict2.dmm"
|
||||
name = "Dinner for Two"
|
||||
description = "Oh this is the night\n\
|
||||
It's a beautiful night\n\
|
||||
And we call it bella notte"
|
||||
|
||||
/datum/map_template/ruin/space/derelict3
|
||||
id = "derelict3"
|
||||
suffix = "derelict3.dmm"
|
||||
name = "Derelict 3"
|
||||
description = "These hulks were once part of a larger structure, where \
|
||||
the three great \[REDACTED\] were forged."
|
||||
|
||||
/datum/map_template/ruin/space/derelict4
|
||||
id = "derelict4"
|
||||
suffix = "derelict4.dmm"
|
||||
name = "Derelict 4"
|
||||
description = "Centcom ferries have never crashed, will never crash, \
|
||||
there is no current investigation into a crashed ferry, and we \
|
||||
will not let Internal Affairs trample over high security information \
|
||||
in the name of this baseless witchhunt."
|
||||
|
||||
/datum/map_template/ruin/space/derelict5
|
||||
id = "derelict5"
|
||||
suffix = "derelict5.dmm"
|
||||
name = "Derelict 5"
|
||||
description = "The plan is, we put a whole bunch of crates full of \
|
||||
treasure in this disused warehouse, launch it into space, and then \
|
||||
ignore it. Forever."
|
||||
|
||||
/datum/map_template/ruin/space/derelict6
|
||||
id = "derelict6"
|
||||
suffix = "derelict6.dmm"
|
||||
name = "Derelict 6"
|
||||
description = "The hush-hush of Nanotrasen when it comes to stations seemingly vanishing off the radar is an interesting topic, \
|
||||
theories of nuclear destruction float about while Nanotrasen flat-out denies said stations ever existing."
|
||||
|
||||
/datum/map_template/ruin/space/empty_shell
|
||||
id = "empty-shell"
|
||||
suffix = "emptyshell.dmm"
|
||||
name = "Empty Shell"
|
||||
description = "Cosy, rural property availible for young professional \
|
||||
couple. Only twelve parsecs from the nearest hyperspace lane!"
|
||||
|
||||
/datum/map_template/ruin/space/gas_the_lizards
|
||||
id = "gas-the-lizards"
|
||||
suffix = "gasthelizards.dmm"
|
||||
name = "Disposal Facility 17"
|
||||
description = "Gas efficiency at 95.6%, fluid elimination at 96.2%. \
|
||||
Will require renewed supplies of 'carpet' before the end of the \
|
||||
quarter."
|
||||
|
||||
/datum/map_template/ruin/space/intact_empty_ship
|
||||
id = "intact-empty-ship"
|
||||
suffix = "intactemptyship.dmm"
|
||||
name = "Authorship"
|
||||
description = "Just somewhere quiet, where I can focus on my work with \
|
||||
no interruptions."
|
||||
|
||||
/datum/map_template/ruin/space/mech_transport
|
||||
id = "mech-transport"
|
||||
suffix = "mechtransport.dmm"
|
||||
name = "CF Corsair"
|
||||
description = "Well, when is it getting here? I have bills to pay; very \
|
||||
well-armed clients who want their shipments as soon as possible! I \
|
||||
don't care, just find it!"
|
||||
|
||||
/datum/map_template/ruin/space/onehalf
|
||||
id = "onehalf"
|
||||
suffix = "onehalf.dmm"
|
||||
name = "DK Excavator 453"
|
||||
description = "Based on the trace elements we've detected on the \
|
||||
gutted asteroids, we suspect that a mining ship using a restricted \
|
||||
engine is somewhere in the area. We'd like to request a patrol vessel \
|
||||
to investigate."
|
||||
|
||||
/datum/map_template/ruin/space/spacebar
|
||||
id = "spacebar"
|
||||
suffix = "spacebar.dmm"
|
||||
name = "The Rampant Golem and Yellow Hound"
|
||||
description = "No questions asked. No shoes/foot protection, no service. \
|
||||
No tabs. No violence in the inside areas. That's it. Welcome to the \
|
||||
Rampant Golem and Yellow Hound. Can I take your order?"
|
||||
|
||||
/datum/map_template/ruin/space/turreted_outpost
|
||||
id = "turreted-outpost"
|
||||
suffix = "turretedoutpost.dmm"
|
||||
name = "Unnamed Turreted Outpost"
|
||||
description = "We'd ask them to stop blaring that ruskiepop music, but \
|
||||
none of us are brave enough to go near those death turrets they have."
|
||||
|
||||
/datum/map_template/ruin/space/way_home
|
||||
id = "way-home"
|
||||
suffix = "way_home.dmm"
|
||||
name = "Salvation"
|
||||
description = "In the darkest times, we will find our way home."
|
||||
|
||||
/datum/map_template/ruin/space/djstation
|
||||
id = "djstation"
|
||||
suffix = "djstation.dmm"
|
||||
name = "DJ Station"
|
||||
description = "Until very recently this pirate radio station was used \
|
||||
to harangue local space stations over a variety of perceived \
|
||||
\"ethics violations\". It seems like someone finally got sick of \
|
||||
it, but the equipment still works."
|
||||
|
||||
/datum/map_template/ruin/space/thederelict
|
||||
id = "thederelict"
|
||||
suffix = "thederelict.dmm"
|
||||
name = "Kosmicheskaya Stantsiya 13"
|
||||
description = "The true fate of Kosmicheskaya Stantsiya 13 is an open \
|
||||
question to this day. Most corporations deny its existence, \
|
||||
for fear of questioning on what became of its crew."
|
||||
|
||||
/datum/map_template/ruin/space/abandonedteleporter
|
||||
id = "abandonedteleporter"
|
||||
suffix = "abandonedteleporter.dmm"
|
||||
name = "Abandoned Teleporter"
|
||||
description = "In space construction the teleporter is often the \
|
||||
first system brought online. This lonely half built teleporter \
|
||||
is a sign of a proposed structure that for one reason or another \
|
||||
just never got built."
|
||||
|
||||
/datum/map_template/ruin/space/crashedclownship
|
||||
id = "crashedclownship"
|
||||
suffix = "crashedclownship.dmm"
|
||||
name = "Crashed Clown Ship"
|
||||
description = "For centuries the promise of a new clown homeworld \
|
||||
has been the siren call for countless clown vessels. Alas the \
|
||||
clown's lust for shinanagans means that successful voyages \
|
||||
are almost unheard of, with most vessels falling to hilarious \
|
||||
consequences almost immediately."
|
||||
|
||||
/datum/map_template/ruin/space/crashedship
|
||||
id = "crashedship"
|
||||
suffix = "crashedship.dmm"
|
||||
name = "Crashed Ship"
|
||||
description = "Among civilian vessels the most common cause of \
|
||||
tragedy is lack of food. This ship was outfited with a \
|
||||
multitude of food generating features, then summarily ran \
|
||||
into an asteroid shortly after takeoff."
|
||||
|
||||
/datum/map_template/ruin/space/listeningstation
|
||||
id = "listeningstation"
|
||||
suffix = "listeningstation.dmm"
|
||||
name = "Syndicate Listening Station"
|
||||
description = "Listening stations form the backbone of the \
|
||||
syndicate's information gathering operations. Assignment to \
|
||||
these stations is dreaded by most agents, as it entails long \
|
||||
and lonely shifts listening to nearby stations chatter \
|
||||
incessently about the most meaningless things."
|
||||
|
||||
/datum/map_template/ruin/space/oldAIsat
|
||||
id = "oldAIsat"
|
||||
suffix = "oldAIsat.dmm"
|
||||
name = "Abandoned Telecommunications Satellite"
|
||||
description = "When the inspector told the employees that they \
|
||||
were all fired, and that their jobs \"could be done by \
|
||||
trained lizards anyway\", they reacted badly. This event and \
|
||||
others is the reason why Central always sends an ERT squad with \
|
||||
their competent inspectors. Incompetent inspectors are told \
|
||||
they can \"do it alone\" because they're \"that pro\". \
|
||||
Incompetent inspectors believe this."
|
||||
|
||||
/datum/map_template/ruin/space/oldteleporter
|
||||
id = "oldteleporter"
|
||||
suffix = "oldteleporter.dmm"
|
||||
name = "Detached Teleporter"
|
||||
description = "The structure of this surprisingly intact \
|
||||
teleporter suggests that it was once part of a larger structure, \
|
||||
but what remains of said structure, if anything, can \
|
||||
only be guessed at."
|
||||
|
||||
/datum/map_template/ruin/space/puzzle1
|
||||
id = "puzzle1"
|
||||
suffix = "puzzle1.dmm"
|
||||
name = "Strange Structure"
|
||||
description = "A strange, free-floating structure that has been aimlessly drifting through the void \
|
||||
of space for who knows how long. Seems like whatever built it was really bored."
|
||||
@@ -0,0 +1,203 @@
|
||||
/datum/map_template/shuttle
|
||||
name = "Base Shuttle Template"
|
||||
var/prefix = "_maps/shuttles/"
|
||||
var/suffix
|
||||
var/port_id
|
||||
var/shuttle_id
|
||||
|
||||
var/description
|
||||
var/admin_notes
|
||||
|
||||
/datum/map_template/shuttle/New()
|
||||
shuttle_id = "[port_id]_[suffix]"
|
||||
mappath = "[prefix][shuttle_id].dmm"
|
||||
. = ..()
|
||||
|
||||
/datum/map_template/shuttle/emergency
|
||||
port_id = "emergency"
|
||||
name = "Base Shuttle Template (Emergency)"
|
||||
|
||||
/datum/map_template/shuttle/cargo
|
||||
port_id = "cargo"
|
||||
name = "Base Shuttle Template (Cargo)"
|
||||
|
||||
/datum/map_template/shuttle/ferry
|
||||
port_id = "ferry"
|
||||
name = "Base Shuttle Template (Ferry)"
|
||||
|
||||
/datum/map_template/shuttle/whiteship
|
||||
port_id = "whiteship"
|
||||
|
||||
// Shuttles start here:
|
||||
|
||||
/datum/map_template/shuttle/emergency/airless
|
||||
suffix = "airless"
|
||||
name = "(Shuttle Under Construction)"
|
||||
description = "The documentation hasn't been finished yet for this \
|
||||
shuttle.\n\
|
||||
In case of emergency: Break glass."
|
||||
admin_notes = "No brig, no medical facilities, no air."
|
||||
|
||||
/datum/map_template/shuttle/emergency/asteroid
|
||||
suffix = "asteroid"
|
||||
name = "Asteroid emergency shuttle"
|
||||
|
||||
/datum/map_template/shuttle/emergency/bar
|
||||
suffix = "bar"
|
||||
name = "The Emergency Escape Bar"
|
||||
description = "Features include sentient bar staff (a Bardrone and a \
|
||||
Barmaid), bathroom, a quality lounge for the heads, and a \
|
||||
large gathering table."
|
||||
admin_notes = "Bardrone and Barmaid are GODMODE, will be automatically \
|
||||
sentienced by the fun balloon at 60 seconds before arrival. Has \
|
||||
medical facilities."
|
||||
|
||||
/datum/map_template/shuttle/emergency/birdboat
|
||||
suffix = "birdboat"
|
||||
name = "Birdboat emergency shuttle"
|
||||
|
||||
/datum/map_template/shuttle/emergency/box
|
||||
suffix = "box"
|
||||
name = "Box emergency shuttle"
|
||||
|
||||
/datum/map_template/shuttle/emergency/clown
|
||||
suffix = "clown"
|
||||
name = "Snappop(tm)!"
|
||||
description = "Hey kids and grownups! Are you bored of DULL and TEDIOUS \
|
||||
shuttle journeys after you're evacuating for probably BORING reasons. \
|
||||
Well then order the Snappop(tm) today! We've got fun activities for \
|
||||
everyone, an all access cockpit, and no boring security brig! Boo! \
|
||||
Play dress up with your friends! Collect all the bedsheets before \
|
||||
your neighbour does! Check if the AI is watching you with our patent \
|
||||
pending \"Peeping Tom AI Multitool Detector\" or PEEEEEETUR for \
|
||||
short. Have a fun ride!"
|
||||
admin_notes = "Brig is replaced by anchored greentext book surrounded by \
|
||||
lavaland chasms, stationside door has been removed to prevent \
|
||||
accidental dropping. No brig."
|
||||
|
||||
/datum/map_template/shuttle/emergency/cramped
|
||||
suffix = "cramped"
|
||||
name = "Secure Transport Vessel 5 (STV5)"
|
||||
description = "Well, looks like Centcomm only had this ship in the area, \
|
||||
they probably weren't expecting you to need evac for a while. \
|
||||
Probably best if you don't rifle around in whatever equipment they \
|
||||
were transporting. I hope you're friendly with your coworkers, \
|
||||
because there is very little space in this thing.\n\
|
||||
\n\
|
||||
Contains contraband armory guns, maintenance loot, and abandoned \
|
||||
crates!"
|
||||
admin_notes = "Due to origin as a solo piloted secure vessel, has an \
|
||||
active GPS onboard labeled STV5."
|
||||
|
||||
/datum/map_template/shuttle/emergency/meta
|
||||
suffix = "meta"
|
||||
name = "Meta emergency shuttle"
|
||||
|
||||
/datum/map_template/shuttle/emergency/mini
|
||||
suffix = "mini"
|
||||
name = "Mini emergency shuttle"
|
||||
|
||||
/datum/map_template/shuttle/emergency/narnar
|
||||
suffix = "narnar"
|
||||
name = "Shuttle 667"
|
||||
description = "Looks like this shuttle may have wandered into the \
|
||||
darkness between the stars on route to the station. Let's not think \
|
||||
too hard about where all the bodies came from."
|
||||
admin_notes = "Contains real cult ruins, mob eyeballs, and inactive \
|
||||
constructs. Cult mobs will automatically be sentienced by fun \
|
||||
balloon. Cloning pods in 'medbay' area are showcases and \
|
||||
nonfunctional."
|
||||
|
||||
/datum/map_template/shuttle/emergency/supermatter
|
||||
suffix = "supermatter"
|
||||
name = "Hyperfractal Gigashuttle"
|
||||
description = "\"I dunno, this seems kinda needlessly complicated.\"\n\
|
||||
\"This shuttle has very a very high safety record, according to \
|
||||
Centcom Officer Cadet Yins.\"\n\
|
||||
\"Are you sure?\"\n\
|
||||
\"Yes, it has a safety record of N-A-N, which is apparently \
|
||||
larger than 100%.\""
|
||||
admin_notes = "Supermatter that spawns on shuttle is special anchored \
|
||||
'hugbox' supermatter that cannot take damage and does not take in \
|
||||
or emit gas. Outside of admin intervention, it cannot explode. \
|
||||
It does, however, still dust anything on contact, emits high levels \
|
||||
of radiation, and induce hallucinations in anyone looking at it \
|
||||
without protective goggles. Emitters spawn powered on, expect \
|
||||
admin notices, they are harmless."
|
||||
|
||||
/datum/map_template/shuttle/emergency/imfedupwiththisworld
|
||||
suffix = "imfedupwiththisworld"
|
||||
name = "Oh, Hi Daniel"
|
||||
description = "How was space work today? \
|
||||
Oh, pretty good. We got a new space station and the company will make a lot of money. \
|
||||
What space station? \
|
||||
I cannot tell you; it's space confidential. \
|
||||
Aw, come space on. Why not? \
|
||||
No, I can't. Anyway, how is your space roleplay life?"
|
||||
|
||||
/datum/map_template/shuttle/emergency/goon
|
||||
suffix = "goon"
|
||||
name = "NES Port"
|
||||
description = "The Nanotrasen Emergency Shuttle Port(NES Port for short) \
|
||||
is a shuttle used at other less known nanotrasen facilities \
|
||||
and has a more open inside for larger crowds."
|
||||
|
||||
/datum/map_template/shuttle/emergency/wabbajack
|
||||
suffix = "wabbajack"
|
||||
name = "NT Lepton Violet"
|
||||
description = "The research team based on this vessel went missing one \
|
||||
day, and no amount of investigation could discover what happened to \
|
||||
them. The only occupants were a number of dead rodents, who appeared to \
|
||||
have clawed each other to death. Needless to say, no engineering team \
|
||||
wanted to go near the thing, and it's only being used as an Emergency \
|
||||
Escape Shuttle because there is literally nothing else available."
|
||||
admin_notes = "If the crew can solve the puzzle, they will wake the \
|
||||
wabbajack statue. It will likely not end well. There's a reason it's \
|
||||
boarded up. Maybe they should have just left it alone."
|
||||
|
||||
/datum/map_template/shuttle/ferry/base
|
||||
suffix = "base"
|
||||
name = "transport ferry"
|
||||
description = "Standard issue Box/Metastation Centcom ferry."
|
||||
|
||||
/datum/map_template/shuttle/ferry/meat
|
||||
suffix = "meat"
|
||||
name = "\"meat\" ferry"
|
||||
description = "Ahoy! We got all kinds o' meat aft here. Meat from plant \
|
||||
people, people who be dark, not in a racist way, just they're dark \
|
||||
black. Oh and lizard meat too,mighty popular that is. Definitely \
|
||||
100% fresh, just ask this guy here. *person on meatspike moans* See? \
|
||||
Definitely high quality meat, nothin' wrong with it, nothin' added, \
|
||||
definitely no zombifyin' reagents!"
|
||||
admin_notes = "Meat currently contains no zombifying reagents, lizard on \
|
||||
meatspike must be spawned in."
|
||||
|
||||
/datum/map_template/shuttle/ferry/lighthouse
|
||||
suffix = "lighthouse"
|
||||
name = "The Lighthouse(?)"
|
||||
description = "*static*... part of a much larger vessel, possibly \
|
||||
military in origin. The weapon markings aren't anything we've seen \
|
||||
... static ... by almost never the same person twice, possible use \
|
||||
of unknown storage ... static ... seeing ERT officers onboard, but \
|
||||
no missions are on file for ... static ... static ... annoying \
|
||||
jingle ... only at The LIGHTHOUSE! Fulfilling needs you didn't even \
|
||||
know you had. We've got EVERYTHING, and something else!"
|
||||
admin_notes = "Currently larger than ferry docking port on Box, will not \
|
||||
hit anything, but must be force docked. Trader and ERT bodyguards are \
|
||||
not included."
|
||||
|
||||
/datum/map_template/shuttle/whiteship/box
|
||||
suffix = "box"
|
||||
name = "NT Medical Ship"
|
||||
|
||||
/datum/map_template/shuttle/whiteship/meta
|
||||
suffix = "meta"
|
||||
name = "NT Recovery White-ship"
|
||||
|
||||
/datum/map_template/shuttle/cargo/box
|
||||
suffix = "box"
|
||||
name = "supply shuttle (Box)"
|
||||
|
||||
/datum/map_template/shuttle/cargo/birdboat
|
||||
suffix = "birdboat"
|
||||
name = "supply shuttle (Birdboat)"
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/votablemap
|
||||
var/name = ""
|
||||
var/friendlyname = ""
|
||||
var/minusers = 0
|
||||
var/maxusers = 0
|
||||
var/voteweight = 1
|
||||
|
||||
/datum/votablemap/New(name)
|
||||
src.name = name
|
||||
src.friendlyname = name
|
||||
@@ -0,0 +1,73 @@
|
||||
/datum/wires/airalarm
|
||||
holder_type = /obj/machinery/airalarm
|
||||
|
||||
/datum/wires/airalarm/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER,
|
||||
WIRE_IDSCAN, WIRE_AI,
|
||||
WIRE_PANIC, WIRE_ALARM
|
||||
)
|
||||
add_duds(3)
|
||||
..()
|
||||
|
||||
/datum/wires/airalarm/interactable(mob/user)
|
||||
var/obj/machinery/airalarm/A = holder
|
||||
if(A.panel_open && A.buildstage == 2)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/airalarm/get_status()
|
||||
var/obj/machinery/airalarm/A = holder
|
||||
var/list/status = list()
|
||||
status += "The interface light is [A.locked ? "red" : "green"]."
|
||||
status += "The short indicator is [A.shorted ? "lit" : "off"]."
|
||||
status += "The AI connection light is [!A.aidisabled ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/airalarm/on_pulse(wire)
|
||||
var/obj/machinery/airalarm/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER) // Short out for a long time.
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
A.update_icon()
|
||||
addtimer(A, "reset", 1200, FALSE, wire)
|
||||
if(WIRE_IDSCAN) // Toggle lock.
|
||||
A.locked = !A.locked
|
||||
if(WIRE_AI) // Disable AI control for a while.
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
addtimer(A, "reset", 100, FALSE, wire)
|
||||
if(WIRE_PANIC) // Toggle panic siphon.
|
||||
if(!A.shorted)
|
||||
if(A.mode == 1) // AALARM_MODE_SCRUB
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
else
|
||||
A.mode = 1 // AALARM_MODE_SCRUB
|
||||
A.apply_mode()
|
||||
if(WIRE_ALARM) // Clear alarms.
|
||||
var/area/AA = get_area_master(A)
|
||||
if(AA.atmosalert(0, holder))
|
||||
A.post_alert(0)
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/airalarm/on_cut(wire, mend)
|
||||
var/obj/machinery/airalarm/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER) // Short out forever.
|
||||
A.shock(usr, 50)
|
||||
A.shorted = !mend
|
||||
A.update_icon()
|
||||
if(WIRE_IDSCAN)
|
||||
if(!mend)
|
||||
A.locked = TRUE
|
||||
if(WIRE_AI)
|
||||
A.aidisabled = mend // Enable/disable AI control.
|
||||
if(WIRE_PANIC) // Force panic syphon on.
|
||||
if(!mend && !A.shorted)
|
||||
A.mode = 3 // AALARM_MODE_PANIC
|
||||
A.apply_mode()
|
||||
if(WIRE_ALARM) // Post alarm.
|
||||
var/area/AA = get_area_master(A)
|
||||
if(AA.atmosalert(2, holder))
|
||||
A.post_alert(2)
|
||||
A.update_icon()
|
||||
@@ -0,0 +1,150 @@
|
||||
/datum/wires/airlock
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
|
||||
/datum/wires/airlock/secure
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/airlock/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER1, WIRE_POWER2,
|
||||
WIRE_BACKUP1, WIRE_BACKUP2,
|
||||
WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI,
|
||||
WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT,
|
||||
WIRE_ZAP1, WIRE_ZAP2
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/airlock/interactable(mob/user)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
if(!istype(user, /mob/living/silicon) && A.isElectrified() && A.shock(user, 100))
|
||||
return FALSE
|
||||
if(A.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/airlock/get_status()
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
var/list/status = list()
|
||||
status += "The door bolts [A.locked ? "have fallen!" : "look up."]"
|
||||
status += "The test light is [A.hasPower() ? "on" : "off"]."
|
||||
status += "The AI connection light is [A.aiControlDisabled || A.emagged ? "off" : "on"]."
|
||||
status += "The check wiring light is [A.safe ? "off" : "on"]."
|
||||
status += "The timer is powered [A.autoclose ? "on" : "off"]."
|
||||
status += "The speed light is [A.normalspeed ? "on" : "off"]."
|
||||
status += "The emergency light is [A.emergency ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/airlock/on_pulse(wire)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power.
|
||||
A.loseMainPower()
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power.
|
||||
A.loseBackupPower()
|
||||
if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required).
|
||||
if(A.emagged)
|
||||
return
|
||||
if(!A.requiresID() || A.check_access(null))
|
||||
if(A.density)
|
||||
A.open()
|
||||
else
|
||||
A.close()
|
||||
if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on).
|
||||
if(!A.locked)
|
||||
A.bolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
else
|
||||
if(A.hasPower())
|
||||
A.unbolt()
|
||||
A.audible_message("<span class='italics'>You hear a click from the bottom of the door.</span>", null, 1)
|
||||
A.update_icon()
|
||||
if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights.
|
||||
if(A.hasPower() && A.density)
|
||||
A.do_animate("deny")
|
||||
if(A.emergency)
|
||||
A.emergency = FALSE
|
||||
A.update_icon()
|
||||
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
spawn(10)
|
||||
if(A)
|
||||
if(A.aiControlDisabled == 1)
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
|
||||
if(!A.secondsElectrified)
|
||||
A.secondsElectrified = 30
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
spawn(10)
|
||||
if(A)
|
||||
while (A.secondsElectrified > 0)
|
||||
A.secondsElectrified -= 1
|
||||
if(A.secondsElectrified < 0)
|
||||
A.secondsElectrified = 0
|
||||
sleep(10)
|
||||
if(WIRE_SAFETY)
|
||||
A.safe = !A.safe
|
||||
if(!A.density)
|
||||
A.close()
|
||||
if(WIRE_TIMING)
|
||||
A.normalspeed = !A.normalspeed
|
||||
if(WIRE_LIGHT)
|
||||
A.lights = !A.lights
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/airlock/on_cut(wire, mend)
|
||||
var/obj/machinery/door/airlock/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
|
||||
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
|
||||
A.regainMainPower()
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseMainPower()
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
|
||||
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
|
||||
A.regainBackupPower()
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.loseBackupPower()
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
|
||||
if(!mend)
|
||||
A.bolt()
|
||||
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
|
||||
if(mend)
|
||||
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
|
||||
A.aiControlDisabled = 0
|
||||
else if(A.aiControlDisabled == 2)
|
||||
A.aiControlDisabled = -1
|
||||
else
|
||||
if(A.aiControlDisabled == 0)
|
||||
A.aiControlDisabled = 1
|
||||
else if(A.aiControlDisabled == -1)
|
||||
A.aiControlDisabled = 2
|
||||
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
|
||||
if(mend)
|
||||
if(A.secondsElectrified)
|
||||
A.secondsElectrified = 0
|
||||
else
|
||||
if(A.secondsElectrified != -1)
|
||||
A.secondsElectrified = -1
|
||||
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
|
||||
add_logs(usr, A, "electrified")
|
||||
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
|
||||
A.safe = mend
|
||||
if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable.
|
||||
A.autoclose = mend
|
||||
if(A.autoclose && !A.density)
|
||||
A.close()
|
||||
if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable.
|
||||
A.lights = mend
|
||||
A.update_icon()
|
||||
if(WIRE_ZAP1, WIRE_ZAP2) // Ouch.
|
||||
A.shock(usr, 50)
|
||||
@@ -0,0 +1,54 @@
|
||||
/datum/wires/apc
|
||||
holder_type = /obj/machinery/power/apc
|
||||
|
||||
/datum/wires/apc/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER1, WIRE_POWER2,
|
||||
WIRE_IDSCAN, WIRE_AI
|
||||
)
|
||||
add_duds(6)
|
||||
..()
|
||||
|
||||
/datum/wires/apc/interactable(mob/user)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
if(A.panel_open && !A.opened)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/apc/get_status()
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
var/list/status = list()
|
||||
status += "The interface light is [A.locked ? "red" : "green"]."
|
||||
status += "The short indicator is [A.shorted ? "lit" : "off"]."
|
||||
status += "The AI connection light is [!A.aidisabled ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/apc/on_pulse(wire)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Short for a long while.
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
addtimer(A, "reset", 1200, FALSE, wire)
|
||||
if(WIRE_IDSCAN) // Unlock for a little while.
|
||||
A.locked = FALSE
|
||||
addtimer(A, "reset", 300, FALSE, wire)
|
||||
if(WIRE_AI) // Disable AI control for a very short time.
|
||||
if(!A.aidisabled)
|
||||
A.aidisabled = TRUE
|
||||
addtimer(A, "reset", 10, FALSE, wire)
|
||||
|
||||
/datum/wires/apc/on_cut(index, mend)
|
||||
var/obj/machinery/power/apc/A = holder
|
||||
switch(index)
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Short out.
|
||||
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
|
||||
A.shorted = FALSE
|
||||
A.shock(usr, 50)
|
||||
else
|
||||
A.shorted = TRUE
|
||||
A.shock(usr, 50)
|
||||
if(WIRE_AI) // Disable AI control.
|
||||
if(mend)
|
||||
A.aidisabled = FALSE
|
||||
else
|
||||
A.aidisabled = TRUE
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/wires/autolathe
|
||||
holder_type = /obj/machinery/autolathe
|
||||
|
||||
/datum/wires/autolathe/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_HACK, WIRE_DISABLE,
|
||||
WIRE_SHOCK, WIRE_ZAP
|
||||
)
|
||||
add_duds(6)
|
||||
..()
|
||||
|
||||
/datum/wires/autolathe/interactable(mob/user)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
if(A.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/autolathe/get_status()
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
var/list/status = list()
|
||||
status += "The red light is [A.disabled ? "on" : "off"]."
|
||||
status += "The blue light is [A.hacked ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/autolathe/on_pulse(wire)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
A.adjust_hacked(!A.hacked)
|
||||
addtimer(A, "reset", 60, FALSE, wire)
|
||||
if(WIRE_SHOCK)
|
||||
A.shocked = !A.shocked
|
||||
addtimer(A, "reset", 60, FALSE, wire)
|
||||
if(WIRE_DISABLE)
|
||||
A.disabled = !A.disabled
|
||||
addtimer(A, "reset", 60, FALSE, wire)
|
||||
|
||||
/datum/wires/autolathe/on_cut(wire, mend)
|
||||
var/obj/machinery/autolathe/A = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
A.adjust_hacked(!mend)
|
||||
if(WIRE_HACK)
|
||||
A.shocked = !mend
|
||||
if(WIRE_DISABLE)
|
||||
A.disabled = !mend
|
||||
if(WIRE_ZAP)
|
||||
A.shock(usr, 50)
|
||||
@@ -0,0 +1,79 @@
|
||||
/datum/wires/explosive/New(atom/holder)
|
||||
add_duds(2) // In this case duds actually explode.
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/on_pulse(index)
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/on_cut(index, mend)
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/proc/explode()
|
||||
return
|
||||
|
||||
|
||||
/datum/wires/explosive/c4
|
||||
holder_type = /obj/item/weapon/c4
|
||||
|
||||
/datum/wires/explosive/c4/interactable(mob/user)
|
||||
var/obj/item/weapon/c4/P = holder
|
||||
if(P.open_panel)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/c4/explode()
|
||||
var/obj/item/weapon/c4/P = holder
|
||||
P.explode()
|
||||
|
||||
|
||||
/datum/wires/explosive/pizza
|
||||
holder_type = /obj/item/pizzabox
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/explosive/pizza/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_DISARM
|
||||
)
|
||||
add_duds(3) // Duds also explode here.
|
||||
..()
|
||||
|
||||
/datum/wires/explosive/pizza/interactable(mob/user)
|
||||
var/obj/item/pizzabox/P = holder
|
||||
if(P.open && P.bomb)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/explosive/pizza/get_status()
|
||||
var/obj/item/pizzabox/P = holder
|
||||
var/list/status = list()
|
||||
status += "The red light is [P.bomb_active ? "on" : "off"]."
|
||||
status += "The green light is [P.bomb_defused ? "on": "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/explosive/pizza/on_pulse(wire)
|
||||
var/obj/item/pizzabox/P = holder
|
||||
switch(wire)
|
||||
if(WIRE_DISARM) // Pulse to toggle
|
||||
P.bomb_defused = !P.bomb_defused
|
||||
else // Boom
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/pizza/on_cut(wire, mend)
|
||||
var/obj/item/pizzabox/P = holder
|
||||
switch(wire)
|
||||
if(WIRE_DISARM) // Disarm and untrap the box.
|
||||
if(!mend)
|
||||
P.bomb_defused = TRUE
|
||||
else
|
||||
if(!mend && !P.bomb_defused)
|
||||
explode()
|
||||
|
||||
/datum/wires/explosive/pizza/explode()
|
||||
var/obj/item/pizzabox/P = holder
|
||||
P.bomb.detonate()
|
||||
|
||||
|
||||
/datum/wires/explosive/gibtonite
|
||||
holder_type = /obj/item/weapon/twohanded/required/gibtonite
|
||||
|
||||
/datum/wires/explosive/gibtonite/explode()
|
||||
var/obj/item/weapon/twohanded/required/gibtonite/P = holder
|
||||
P.GibtoniteReaction(null, 2)
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum/wires/mulebot
|
||||
holder_type = /mob/living/simple_animal/bot/mulebot
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/mulebot/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER1, WIRE_POWER2,
|
||||
WIRE_AVOIDANCE, WIRE_LOADCHECK,
|
||||
WIRE_MOTOR1, WIRE_MOTOR2,
|
||||
WIRE_RX, WIRE_TX, WIRE_BEACON
|
||||
)
|
||||
..()
|
||||
|
||||
/datum/wires/mulebot/interactable(mob/user)
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
if(M.open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/mulebot/on_pulse(wire)
|
||||
var/mob/living/simple_animal/bot/mulebot/M = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER1, WIRE_POWER2)
|
||||
holder.visible_message("<span class='notice'>\icon[M] The charge light flickers.</span>")
|
||||
if(WIRE_AVOIDANCE)
|
||||
holder.visible_message("<span class='notice'>\icon[M] The external warning lights flash briefly.</span>")
|
||||
if(WIRE_LOADCHECK)
|
||||
holder.visible_message("<span class='notice'>\icon[M] The load platform clunks.</span>")
|
||||
if(WIRE_MOTOR1, WIRE_MOTOR2)
|
||||
holder.visible_message("<span class='notice'>\icon[M] The drive motor whines briefly.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>\icon[M] You hear a radio crackle.</span>")
|
||||
@@ -0,0 +1,44 @@
|
||||
/datum/wires/particle_accelerator/control_box
|
||||
holder_type = /obj/machinery/particle_accelerator/control_box
|
||||
|
||||
/datum/wires/particle_accelerator/control_box/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_POWER, WIRE_STRENGTH, WIRE_LIMIT,
|
||||
WIRE_INTERFACE
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/particle_accelerator/control_box/interactable(mob/user)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
if(C.construction_state == 2)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/particle_accelerator/control_box/on_pulse(wire)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER)
|
||||
C.toggle_power()
|
||||
if(WIRE_STRENGTH)
|
||||
C.add_strength()
|
||||
if(WIRE_INTERFACE)
|
||||
C.interface_control = !C.interface_control
|
||||
if(WIRE_LIMIT)
|
||||
C.visible_message("\icon[C]<b>[C]</b> makes a large whirring noise.")
|
||||
|
||||
/datum/wires/particle_accelerator/control_box/on_cut(wire, mend)
|
||||
var/obj/machinery/particle_accelerator/control_box/C = holder
|
||||
switch(wire)
|
||||
if(WIRE_POWER)
|
||||
if(C.active == !mend)
|
||||
C.toggle_power()
|
||||
if(WIRE_STRENGTH)
|
||||
for(var/i = 1; i < 3; i++)
|
||||
C.remove_strength()
|
||||
if(WIRE_INTERFACE)
|
||||
if(!mend)
|
||||
C.interface_control = FALSE
|
||||
if(WIRE_LIMIT)
|
||||
C.strength_upper_limit = (mend ? 2 : 3)
|
||||
if(C.strength_upper_limit < C.strength)
|
||||
C.remove_strength()
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/wires/r_n_d
|
||||
holder_type = /obj/machinery/r_n_d
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/r_n_d/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_HACK, WIRE_DISABLE,
|
||||
WIRE_SHOCK
|
||||
)
|
||||
add_duds(5)
|
||||
..()
|
||||
|
||||
/datum/wires/r_n_d/interactable(mob/user)
|
||||
var/obj/machinery/r_n_d/R = holder
|
||||
if(R.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/r_n_d/get_status()
|
||||
var/obj/machinery/r_n_d/R = holder
|
||||
var/list/status = list()
|
||||
status += "The red light is [R.disabled ? "off" : "on"]."
|
||||
status += "The green light is [R.shocked ? "off" : "on"]."
|
||||
status += "The blue light is [R.hacked ? "off" : "on"]."
|
||||
return status
|
||||
|
||||
/datum/wires/r_n_d/on_pulse(wire)
|
||||
var/obj/machinery/r_n_d/R = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
R.hacked = !R.hacked
|
||||
if(WIRE_DISABLE)
|
||||
R.disabled = !R.disabled
|
||||
if(WIRE_SHOCK)
|
||||
R.shocked = TRUE
|
||||
spawn(100)
|
||||
if(R)
|
||||
R.shocked = FALSE
|
||||
|
||||
/datum/wires/r_n_d/on_cut(wire, mend)
|
||||
var/obj/machinery/r_n_d/R = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
R.hacked = !mend
|
||||
if(WIRE_DISABLE)
|
||||
R.disabled = !mend
|
||||
if(WIRE_SHOCK)
|
||||
R.shocked = !mend
|
||||
@@ -0,0 +1,25 @@
|
||||
/datum/wires/radio
|
||||
holder_type = /obj/item/device/radio
|
||||
|
||||
/datum/wires/radio/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_SIGNAL,
|
||||
WIRE_RX, WIRE_TX
|
||||
)
|
||||
..()
|
||||
|
||||
/datum/wires/radio/interactable(mob/user)
|
||||
var/obj/item/device/radio/R = holder
|
||||
if(R.b_stat)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/radio/on_pulse(index)
|
||||
var/obj/item/device/radio/R = holder
|
||||
switch(index)
|
||||
if(WIRE_SIGNAL)
|
||||
R.listening = !R.listening
|
||||
R.broadcasting = R.listening
|
||||
if(WIRE_RX)
|
||||
R.listening = !R.listening
|
||||
if(WIRE_TX)
|
||||
R.broadcasting = !R.broadcasting
|
||||
@@ -0,0 +1,66 @@
|
||||
/datum/wires/robot
|
||||
holder_type = /mob/living/silicon/robot
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/robot/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_AI, WIRE_CAMERA,
|
||||
WIRE_LAWSYNC, WIRE_LOCKDOWN
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/robot/interactable(mob/user)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
if(R.wiresexposed)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/robot/get_status()
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
var/list/status = list()
|
||||
status += "The law sync module is [R.lawupdate ? "on" : "off"]."
|
||||
status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]."
|
||||
status += "The camera light is [!isnull(R.camera) && R.camera.status ? "on" : "off"]."
|
||||
status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]."
|
||||
return status
|
||||
|
||||
/datum/wires/robot/on_pulse(wire)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(wire)
|
||||
if(WIRE_AI) // Pulse to pick a new AI.
|
||||
if(!R.emagged)
|
||||
var/new_ai = select_active_ai(R)
|
||||
if(new_ai && (new_ai != R.connected_ai))
|
||||
R.connected_ai = new_ai
|
||||
R.notify_ai(TRUE)
|
||||
if(WIRE_CAMERA) // Pulse to disable the camera.
|
||||
if(!isnull(R.camera) && !R.scrambledcodes)
|
||||
R.camera.toggle_cam(usr, 0)
|
||||
R.visible_message("[R]'s camera lense focuses loudly.", "Your camera lense focuses loudly.")
|
||||
if(WIRE_LAWSYNC) // Forces a law update if possible.
|
||||
if(R.lawupdate)
|
||||
R.visible_message("[R] gently chimes.", "LawSync protocol engaged.")
|
||||
R.lawsync()
|
||||
R.show_laws()
|
||||
if(WIRE_LOCKDOWN)
|
||||
R.SetLockdown(!R.lockcharge) // Toggle
|
||||
|
||||
/datum/wires/robot/on_cut(wire, mend)
|
||||
var/mob/living/silicon/robot/R = holder
|
||||
switch(wire)
|
||||
if(WIRE_AI) // Cut the AI wire to reset AI control.
|
||||
if(!mend)
|
||||
R.connected_ai = null
|
||||
if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync.
|
||||
if(mend)
|
||||
if(!R.emagged)
|
||||
R.lawupdate = TRUE
|
||||
else
|
||||
R.lawupdate = FALSE
|
||||
if (WIRE_CAMERA) // Disable the camera.
|
||||
if(!isnull(R.camera) && !R.scrambledcodes)
|
||||
R.camera.status = mend
|
||||
R.camera.toggle_cam(usr, 0)
|
||||
R.visible_message("[R]'s camera lense focuses loudly.", "Your camera lense focuses loudly.")
|
||||
if(WIRE_LOCKDOWN) // Simple lockdown.
|
||||
R.SetLockdown(!mend)
|
||||
@@ -0,0 +1,42 @@
|
||||
/datum/wires/suit_storage_unit
|
||||
holder_type = /obj/machinery/suit_storage_unit
|
||||
|
||||
/datum/wires/suit_storage_unit/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_HACK, WIRE_SAFETY,
|
||||
WIRE_ZAP
|
||||
)
|
||||
add_duds(2)
|
||||
..()
|
||||
|
||||
/datum/wires/suit_storage_unit/interactable(mob/user)
|
||||
var/obj/machinery/suit_storage_unit/SSU = holder
|
||||
if(SSU.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/suit_storage_unit/get_status()
|
||||
var/obj/machinery/suit_storage_unit/SSU = holder
|
||||
var/list/status = list()
|
||||
status += "The UV bulb is [SSU.uv_super ? "glowing" : "dim"]."
|
||||
status += "The service light is [SSU.safeties ? "off" : "on"]."
|
||||
return status
|
||||
|
||||
/datum/wires/suit_storage_unit/on_pulse(wire)
|
||||
var/obj/machinery/suit_storage_unit/SSU = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
SSU.uv_super = !SSU.uv_super
|
||||
if(WIRE_SAFETY)
|
||||
SSU.safeties = !SSU.safeties
|
||||
if(WIRE_ZAP)
|
||||
SSU.shock(usr)
|
||||
|
||||
/datum/wires/suit_storage_unit/on_cut(wire, mend)
|
||||
var/obj/machinery/suit_storage_unit/SSU = holder
|
||||
switch(wire)
|
||||
if(WIRE_HACK)
|
||||
SSU.uv_super = !mend
|
||||
if(WIRE_SAFETY)
|
||||
SSU.safeties = mend
|
||||
if(WIRE_ZAP)
|
||||
SSU.shock(usr)
|
||||
@@ -0,0 +1,91 @@
|
||||
/datum/wires/syndicatebomb
|
||||
holder_type = /obj/machinery/syndicatebomb
|
||||
randomize = TRUE
|
||||
|
||||
/datum/wires/syndicatebomb/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_BOOM, WIRE_UNBOLT,
|
||||
WIRE_ACTIVATE, WIRE_DELAY, WIRE_PROCEED
|
||||
)
|
||||
..()
|
||||
|
||||
/datum/wires/syndicatebomb/interactable(mob/user)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
if(P.open_panel)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/syndicatebomb/on_pulse(wire)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(wire)
|
||||
if(WIRE_BOOM)
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
|
||||
B.timer = 0
|
||||
tell_admins(B)
|
||||
if(WIRE_UNBOLT)
|
||||
holder.visible_message("<span class='notice'>\icon[B] The bolts spin in place for a moment.</span>")
|
||||
if(WIRE_DELAY)
|
||||
if(B.delayedbig)
|
||||
holder.visible_message("<span class='notice'>\icon[B] The bomb has already been delayed.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>\icon[B] The bomb chirps.</span>")
|
||||
playsound(B, 'sound/machines/chime.ogg', 30, 1)
|
||||
B.timer += 30
|
||||
B.delayedbig = TRUE
|
||||
if(WIRE_PROCEED)
|
||||
holder.visible_message("<span class='danger'>\icon[B] The bomb buzzes ominously!</span>")
|
||||
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
|
||||
if(B.timer >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
|
||||
B.timer = 60
|
||||
else if(B.timer >= 21)
|
||||
B.timer -= 10
|
||||
else if(B.timer >= 11) // Both to prevent negative timers and to have a little mercy.
|
||||
B.timer = 10
|
||||
if(WIRE_ACTIVATE)
|
||||
if(!B.active && !B.defused)
|
||||
holder.visible_message("<span class='danger'>\icon[B] You hear the bomb start ticking!</span>")
|
||||
playsound(B, 'sound/machines/click.ogg', 30, 1)
|
||||
B.active = TRUE
|
||||
B.update_icon()
|
||||
else if(B.delayedlittle)
|
||||
holder.visible_message("<span class='notice'>\icon[B] Nothing happens.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>\icon[B] The bomb seems to hesitate for a moment.</span>")
|
||||
B.timer += 10
|
||||
B.delayedlittle = TRUE
|
||||
|
||||
/datum/wires/syndicatebomb/on_cut(wire, mend)
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(wire)
|
||||
if(WIRE_BOOM)
|
||||
if(mend)
|
||||
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
|
||||
else
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
|
||||
B.timer = 0
|
||||
tell_admins(B)
|
||||
else
|
||||
B.defused = TRUE
|
||||
if(WIRE_UNBOLT)
|
||||
if(!mend && B.anchored)
|
||||
holder.visible_message("<span class='notice'>\icon[B] The bolts lift out of the ground!</span>")
|
||||
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
|
||||
B.anchored = 0
|
||||
if(WIRE_PROCEED)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
|
||||
B.timer = 0
|
||||
tell_admins(B)
|
||||
if(WIRE_ACTIVATE)
|
||||
if(!mend && B.active)
|
||||
holder.visible_message("<span class='notice'>\icon[B] The timer stops! The bomb has been defused!</span>")
|
||||
B.active = FALSE
|
||||
B.defused = TRUE
|
||||
B.update_icon()
|
||||
|
||||
/datum/wires/syndicatebomb/proc/tell_admins(obj/machinery/syndicatebomb/B)
|
||||
if(istype(B, /obj/machinery/syndicatebomb/training))
|
||||
return
|
||||
log_game("A [B.name] was detonated via boom wire at X=[B.x], Y=[B.y], Z=[B.z].")
|
||||
message_admins("A [B.name] was detonated via boom wire at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[B.x];Y=[B.y];Z=[B.z]'> (JMP)</a>.")
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/wires/vending
|
||||
holder_type = /obj/machinery/vending
|
||||
|
||||
/datum/wires/vending/New(atom/holder)
|
||||
wires = list(
|
||||
WIRE_THROW, WIRE_ELECTRIFY, WIRE_SPEAKER,
|
||||
WIRE_CONTRABAND, WIRE_IDSCAN
|
||||
)
|
||||
add_duds(1)
|
||||
..()
|
||||
|
||||
/datum/wires/vending/interactable(mob/user)
|
||||
var/obj/machinery/vending/V = holder
|
||||
if(!istype(user, /mob/living/silicon) && V.seconds_electrified && V.shock(user, 100))
|
||||
return FALSE
|
||||
if(V.panel_open)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/vending/get_status()
|
||||
var/obj/machinery/vending/V = holder
|
||||
var/list/status = list()
|
||||
status += "The orange light is [V.seconds_electrified ? "on" : "off"]."
|
||||
status += "The red light is [V.shoot_inventory ? "off" : "blinking"]."
|
||||
status += "The green light is [V.extended_inventory ? "on" : "off"]."
|
||||
status += "A [V.scan_id ? "purple" : "yellow"] light is on."
|
||||
status += "The speaker light is [V.shut_up ? "off" : "on"]."
|
||||
return status
|
||||
|
||||
/datum/wires/vending/on_pulse(wire)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(wire)
|
||||
if(WIRE_THROW)
|
||||
V.shoot_inventory = !V.shoot_inventory
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = !V.extended_inventory
|
||||
if(WIRE_ELECTRIFY)
|
||||
V.seconds_electrified = 30
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = !V.scan_id
|
||||
if(WIRE_SPEAKER)
|
||||
V.shut_up = !V.shut_up
|
||||
|
||||
/datum/wires/vending/on_cut(wire, mend)
|
||||
var/obj/machinery/vending/V = holder
|
||||
switch(wire)
|
||||
if(WIRE_THROW)
|
||||
V.shoot_inventory = !mend
|
||||
if(WIRE_CONTRABAND)
|
||||
V.extended_inventory = FALSE
|
||||
if(WIRE_ELECTRIFY)
|
||||
if(mend)
|
||||
V.seconds_electrified = FALSE
|
||||
else
|
||||
V.seconds_electrified = -1
|
||||
if(WIRE_IDSCAN)
|
||||
V.scan_id = mend
|
||||
if(WIRE_SPEAKER)
|
||||
V.shut_up = mend
|
||||
@@ -0,0 +1,344 @@
|
||||
var/list/wire_colors = list( // http://www.crockford.com/wrrrld/color.html
|
||||
"aliceblue",
|
||||
"antiquewhite",
|
||||
"aqua",
|
||||
"aquamarine",
|
||||
"beige",
|
||||
"blanchedalmond",
|
||||
"blue",
|
||||
"blueviolet",
|
||||
"brown",
|
||||
"burlywood",
|
||||
"cadetblue",
|
||||
"chartreuse",
|
||||
"chocolate",
|
||||
"coral",
|
||||
"cornflowerblue",
|
||||
"cornsilk",
|
||||
"crimson",
|
||||
"cyan",
|
||||
"deeppink",
|
||||
"deepskyblue",
|
||||
"dimgray",
|
||||
"dodgerblue",
|
||||
"firebrick",
|
||||
"floralwhite",
|
||||
"forestgreen",
|
||||
"fuchsia",
|
||||
"gainsboro",
|
||||
"ghostwhite",
|
||||
"gold",
|
||||
"goldenrod",
|
||||
"gray",
|
||||
"green",
|
||||
"greenyellow",
|
||||
"honeydew",
|
||||
"hotpink",
|
||||
"indianred",
|
||||
"ivory",
|
||||
"khaki",
|
||||
"lavender",
|
||||
"lavenderblush",
|
||||
"lawngreen",
|
||||
"lemonchiffon",
|
||||
"lightblue",
|
||||
"lightcoral",
|
||||
"lightcyan",
|
||||
"lightgoldenrodyellow",
|
||||
"lightgray",
|
||||
"lightgreen",
|
||||
"lightpink",
|
||||
"lightsalmon",
|
||||
"lightseagreen",
|
||||
"lightskyblue",
|
||||
"lightslategray",
|
||||
"lightsteelblue",
|
||||
"lightyellow",
|
||||
"lime",
|
||||
"limegreen",
|
||||
"linen",
|
||||
"magenta",
|
||||
"maroon",
|
||||
"mediumaquamarine",
|
||||
"mediumblue",
|
||||
"mediumorchid",
|
||||
"mediumpurple",
|
||||
"mediumseagreen",
|
||||
"mediumslateblue",
|
||||
"mediumspringgreen",
|
||||
"mediumturquoise",
|
||||
"mediumvioletred",
|
||||
"mintcream",
|
||||
"mistyrose",
|
||||
"moccasin",
|
||||
"navajowhite",
|
||||
"oldlace",
|
||||
"olive",
|
||||
"olivedrab",
|
||||
"orange",
|
||||
"orangered",
|
||||
"orchid",
|
||||
"palegoldenrod",
|
||||
"palegreen",
|
||||
"paleturquoise",
|
||||
"palevioletred",
|
||||
"papayawhip",
|
||||
"peachpuff",
|
||||
"peru",
|
||||
"pink",
|
||||
"plum",
|
||||
"powderblue",
|
||||
"purple",
|
||||
"red",
|
||||
"rosybrown",
|
||||
"royalblue",
|
||||
"saddlebrown",
|
||||
"salmon",
|
||||
"sandybrown",
|
||||
"seagreen",
|
||||
"seashell",
|
||||
"sienna",
|
||||
"silver",
|
||||
"skyblue",
|
||||
"slateblue",
|
||||
"slategray",
|
||||
"snow",
|
||||
"springgreen",
|
||||
"steelblue",
|
||||
"tan",
|
||||
"teal",
|
||||
"thistle",
|
||||
"tomato",
|
||||
"turquoise",
|
||||
"violet",
|
||||
"wheat",
|
||||
"white",
|
||||
"whitesmoke",
|
||||
"yellow",
|
||||
"yellowgreen",
|
||||
)
|
||||
var/list/wire_color_directory = list()
|
||||
|
||||
/proc/is_wire_tool(obj/item/I)
|
||||
if(istype(I, /obj/item/device/multitool))
|
||||
return TRUE
|
||||
if(istype(I, /obj/item/weapon/wirecutters))
|
||||
return TRUE
|
||||
if(istype(I, /obj/item/device/assembly))
|
||||
var/obj/item/device/assembly/A = I
|
||||
if(A.attachable)
|
||||
return TRUE
|
||||
return
|
||||
|
||||
/atom
|
||||
var/datum/wires/wires = null
|
||||
|
||||
/datum/wires
|
||||
var/atom/holder = null // The holder (atom that contains these wires).
|
||||
var/holder_type = null // The holder's typepath (used to make wire colors common to all holders).
|
||||
|
||||
var/list/wires = list() // List of wires.
|
||||
var/list/cut_wires = list() // List of wires that have been cut.
|
||||
var/list/colors = list() // Dictionary of colors to wire.
|
||||
var/list/assemblies = list() // List of attached assemblies.
|
||||
var/randomize = 0 // If every instance of these wires should be random.
|
||||
|
||||
/datum/wires/New(atom/holder)
|
||||
..()
|
||||
if(!istype(holder, holder_type))
|
||||
CRASH("Wire holder is not of the expected type!")
|
||||
return
|
||||
|
||||
src.holder = holder
|
||||
if(randomize)
|
||||
randomize()
|
||||
else
|
||||
if(!wire_color_directory[holder_type])
|
||||
randomize()
|
||||
wire_color_directory[holder_type] = colors
|
||||
else
|
||||
colors = wire_color_directory[holder_type]
|
||||
|
||||
/datum/wires/Destroy()
|
||||
holder = null
|
||||
assemblies = list()
|
||||
return ..()
|
||||
|
||||
/datum/wires/proc/add_duds(duds)
|
||||
while(duds)
|
||||
var/dud = "dud[--duds]"
|
||||
if(dud in wires)
|
||||
continue
|
||||
wires += dud
|
||||
|
||||
/datum/wires/proc/randomize()
|
||||
var/list/possible_colors = wire_colors.Copy()
|
||||
|
||||
for(var/wire in shuffle(wires))
|
||||
colors[pick_n_take(possible_colors)] = wire
|
||||
|
||||
/datum/wires/proc/shuffle_wires()
|
||||
colors.Cut()
|
||||
randomize()
|
||||
|
||||
/datum/wires/proc/repair()
|
||||
cut_wires.Cut()
|
||||
|
||||
/datum/wires/proc/get_wire(color)
|
||||
return colors[color]
|
||||
|
||||
/datum/wires/proc/get_attached(color)
|
||||
if(assemblies[color])
|
||||
return assemblies[color]
|
||||
return null
|
||||
|
||||
/datum/wires/proc/is_attached(color)
|
||||
if(assemblies[color])
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/is_cut(wire)
|
||||
return (wire in cut_wires)
|
||||
|
||||
/datum/wires/proc/is_color_cut(color)
|
||||
return is_cut(get_wire(color))
|
||||
|
||||
/datum/wires/proc/is_all_cut()
|
||||
if(cut_wires.len == wires.len)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/cut(wire)
|
||||
if(is_cut(wire))
|
||||
cut_wires -= wire
|
||||
on_cut(wire, mend = TRUE)
|
||||
else
|
||||
cut_wires += wire
|
||||
on_cut(wire, mend = FALSE)
|
||||
|
||||
/datum/wires/proc/cut_color(color)
|
||||
cut(get_wire(color))
|
||||
|
||||
/datum/wires/proc/cut_random()
|
||||
cut(wires[rand(1, wires.len)])
|
||||
|
||||
/datum/wires/proc/cut_all()
|
||||
for(var/wire in wires)
|
||||
cut(wire)
|
||||
|
||||
/datum/wires/proc/pulse(wire)
|
||||
if(is_cut(wire))
|
||||
return
|
||||
on_pulse(wire)
|
||||
|
||||
/datum/wires/proc/pulse_color(color)
|
||||
pulse(get_wire(color))
|
||||
|
||||
/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S)
|
||||
for(var/color in assemblies)
|
||||
if(S == assemblies[color])
|
||||
pulse_color(color)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S)
|
||||
if(S && istype(S) && S.attachable && !is_attached(color))
|
||||
assemblies[color] = S
|
||||
S.loc = holder
|
||||
S.connected = src
|
||||
return S
|
||||
|
||||
/datum/wires/proc/detach_assembly(color)
|
||||
var/obj/item/device/assembly/S = get_attached(color)
|
||||
if(S && istype(S))
|
||||
assemblies -= color
|
||||
S.connected = null
|
||||
S.loc = holder.loc
|
||||
return S
|
||||
|
||||
// Overridable Procs
|
||||
/datum/wires/proc/interactable(mob/user)
|
||||
return TRUE
|
||||
|
||||
/datum/wires/proc/get_status()
|
||||
return list()
|
||||
|
||||
/datum/wires/proc/on_cut(wire, mend = FALSE)
|
||||
return
|
||||
|
||||
/datum/wires/proc/on_pulse(wire)
|
||||
return
|
||||
// End Overridable Procs
|
||||
|
||||
/datum/wires/proc/interact(mob/user)
|
||||
if(!interactable(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
for(var/A in assemblies)
|
||||
var/obj/item/I = assemblies[A]
|
||||
if(istype(I) && I.on_found(user))
|
||||
return
|
||||
|
||||
/datum/wires/ui_host()
|
||||
return holder
|
||||
|
||||
/datum/wires/ui_status(mob/user)
|
||||
if(interactable(user))
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/wires/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/payload = list()
|
||||
for(var/color in colors)
|
||||
payload.Add(list(list(
|
||||
"color" = color,
|
||||
"wire" = (IsAdminGhost(user) ? get_wire(color) : null),
|
||||
"cut" = is_color_cut(color),
|
||||
"attached" = is_attached(color)
|
||||
)))
|
||||
data["wires"] = payload
|
||||
data["status"] = get_status()
|
||||
return data
|
||||
|
||||
/datum/wires/ui_act(action, params)
|
||||
if(..() || !interactable(usr))
|
||||
return
|
||||
var/target_wire = params["wire"]
|
||||
var/mob/living/L = usr
|
||||
var/obj/item/I = L.get_active_hand()
|
||||
switch(action)
|
||||
if("cut")
|
||||
if(istype(I, /obj/item/weapon/wirecutters) || IsAdminGhost(usr))
|
||||
playsound(holder, 'sound/items/Wirecutter.ogg', 20, 1)
|
||||
cut_color(target_wire)
|
||||
. = TRUE
|
||||
else
|
||||
L << "<span class='warning'>You need wirecutters!</span>"
|
||||
if("pulse")
|
||||
if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr))
|
||||
playsound(holder, 'sound/weapons/empty.ogg', 20, 1)
|
||||
pulse_color(target_wire)
|
||||
. = TRUE
|
||||
else
|
||||
L << "<span class='warning'>You need a multitool!</span>"
|
||||
if("attach")
|
||||
if(is_attached(target_wire))
|
||||
var/obj/item/O = detach_assembly(target_wire)
|
||||
if(O)
|
||||
L.put_in_hands(O)
|
||||
. = TRUE
|
||||
else
|
||||
if(istype(I, /obj/item/device/assembly))
|
||||
var/obj/item/device/assembly/A = I
|
||||
if(A.attachable)
|
||||
if(!L.drop_item())
|
||||
return
|
||||
attach_assembly(target_wire, A)
|
||||
. = TRUE
|
||||
else
|
||||
L << "<span class='warning'>You need an attachable assembly!</span>"
|
||||
Reference in New Issue
Block a user