Merge branch 'master' into upstream-merge-32311

This commit is contained in:
LetterJay
2017-12-29 18:38:50 -06:00
committed by GitHub
302 changed files with 4918 additions and 20468 deletions
+5 -5
View File
@@ -9,12 +9,12 @@
#define ANTAG_DATUM_TRAITOR /datum/antagonist/traitor
#define ANTAG_DATUM_TRAITOR_HUMAN /datum/antagonist/traitor/human
#define ANTAG_DATUM_TRAITOR_AI /datum/antagonist/traitor/AI
#define ANTAG_DATUM_IAA /datum/antagonist/traitor/internal_affairs
#define ANTAG_DATUM_IAA /datum/antagonist/traitor/internal_affairs
#define ANTAG_DATUM_IAA_HUMAN /datum/antagonist/traitor/human/internal_affairs
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
#define ANTAG_DATUM_BROTHER /datum/antagonist/brother
#define ANTAG_DATUM_ABDUCTOR /datum/antagonist/abductor
#define ANTAG_DATUM_ABDUCTOR_SCIENTIST /datum/antagonist/abductor/scientist
#define ANTAG_DATUM_ABDUCTOR_AGENT /datum/antagonist/abductor/agent
#define ANTAG_DATUM_ABDUCTOR_SCIENTIST /datum/antagonist/abductor/scientist
#define ANTAG_DATUM_ABDUCTOR_AGENT /datum/antagonist/abductor/agent
#define ANTAG_DATUM_MONKEY /datum/antagonist/monkey
#define ANTAG_DATUM_MONKEY_LEADER /datum/antagonist/monkey/leader
#define ANTAG_DATUM_MONKEY_LEADER /datum/antagonist/monkey/leader
+1 -1
View File
@@ -22,7 +22,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ON_BORDER_1 512 // item has priority to check when entering or leaving
#define NOSLIP_1 1024 //prevents from slipping on wet floors, in space etc
#define _UNUSED_1 2048
#define CLEAN_ON_MOVE_1 2048
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT_1 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
-1
View File
@@ -17,7 +17,6 @@
#define MODE_HOLOPAD "holopad"
#define MODE_CHANGELING "changeling"
#define MODE_VOCALCORDS "cords"
#define MODE_MONKEY "monkeyhive"
//Spans. Robot speech, italics, etc. Applied in compose_message().
#define SPAN_ROBOT "robot"
+11 -12
View File
@@ -10,17 +10,17 @@
//mob disabilities stat
#define BLIND "blind"
#define MUTE "mute"
#define DEAF "deaf"
#define NEARSIGHT "nearsighted"
#define FAT "fat"
#define HUSK "husk"
#define NOCLONE "noclone"
#define CLUMSY "clumsy"
#define DUMB "dumb"
#define MONKEYLIKE "monkeylike" //sets IsAdvancedToolUser to FALSE
#define PACIFISM "pacifism"
#define DISABILITY_BLIND "blind"
#define DISABILITY_MUTE "mute"
#define DISABILITY_DEAF "deaf"
#define DISABILITY_NEARSIGHT "nearsighted"
#define DISABILITY_FAT "fat"
#define DISABILITY_HUSK "husk"
#define DISABILITY_NOCLONE "noclone"
#define DISABILITY_CLUMSY "clumsy"
#define DISABILITY_DUMB "dumb"
#define DISABILITY_MONKEYLIKE "monkeylike" //sets IsAdvancedToolUser to FALSE
#define DISABILITY_PACIFISM "pacifism"
// common disability sources
#define EYE_DAMAGE "eye_damage"
@@ -33,7 +33,6 @@
#define GENETICS_SPELL "genetics_spell"
#define TRAUMA_DISABILITY "trauma"
// bitflags for machine stat variable
#define BROKEN 1
#define NOPOWER 2
+7
View File
@@ -267,6 +267,13 @@
if(!target_turf)
return NULLTURF_BORDER
var/area/target_area = get_area(target_turf)
var/area/source_area = get_area(source)
if(source_area.canSmoothWithAreas && !is_type_in_typecache(target_area, source_area.canSmoothWithAreas))
return null
if(target_area.canSmoothWithAreas && !is_type_in_typecache(source_area, target_area.canSmoothWithAreas))
return null
if(source.canSmoothWith)
var/atom/A
if(source.smooth & SMOOTH_MORE)
+45 -62
View File
@@ -1,41 +1,24 @@
#define POPCOUNT_SURVIVORS "survivors" //Not dead at roundend
#define POPCOUNT_ESCAPEES "escapees" //Not dead and on centcomm/shuttles marked as escaped
#define POPCOUNT_GHOSTS "ghosts" //Ghosts on roundend
#define POPCOUNT_HUMAN_ESCAPEES "human_escapees" //Same as escapees but human only
#define POPCOUNT_HUMAN_SURVIVORS "human_survivors" //Same as survivors but human only
#define POPCOUNT_SHUTTLE_ESCAPEES "shuttle_escapees" //Emergency shuttle only.
/datum/controller/subsystem/ticker/proc/gather_roundend_feedback()
//Survivor numbers
var/clients = GLOB.player_list.len
var/surviving_humans = 0
var/surviving_total = 0
var/ghosts = 0
var/escaped_humans = 0
var/escaped_total = 0
var/popcount = count_survivors()
SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients"))
SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_GHOSTS], list("ghosts"))
SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_HUMAN_SURVIVORS], list("survivors", "human"))
SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_SURVIVORS], list("survivors", "total"))
SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_HUMAN_ESCAPEES], list("escapees", "human"))
SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_ESCAPEES], list("escapees", "total"))
//Antag information
gather_antag_data()
for(var/mob/M in GLOB.player_list)
if(ishuman(M))
if(!M.stat)
surviving_humans++
if(M.z == ZLEVEL_CENTCOM)
escaped_humans++
if(!M.stat)
surviving_total++
if(M.z == ZLEVEL_CENTCOM)
escaped_total++
if(isobserver(M))
ghosts++
if(clients)
SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients"))
if(ghosts)
SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts"))
if(surviving_humans)
SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human"))
if(surviving_total)
SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total"))
if(escaped_humans)
SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human"))
if(escaped_total)
SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total"))
gather_antag_success_rate()
/datum/controller/subsystem/ticker/proc/gather_antag_success_rate()
/datum/controller/subsystem/ticker/proc/gather_antag_data()
var/team_gid = 1
var/list/team_ids = list()
@@ -64,27 +47,6 @@
SSblackbox.record_feedback("associative", "antagonists", 1, antag_info)
/datum/controller/subsystem/ticker/proc/gather_newscaster()
var/json_file = file("[GLOB.log_directory]/newscaster.json")
var/list/file_data = list()
var/pos = 1
for(var/datum/newscaster/feed_channel/channel in GLOB.news_network.network_channels)
if(!GLOB.news_network.network_channels.len)
break
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
if(!channel.messages.len)
continue
for(var/datum/newscaster/feed_message/message in channel.messages)
file_data["[pos]"]["messages"] |= list("author" = "[message.author]", "time stamp" = "[message.time_stamp]", "censored" = message.bodyCensor ? 1 : 0, "author censored" = message.authorCensor ? 1 : 0, "photo file" = "[message.photo_file]", "photo caption" = "[message.caption]", "body" = "[message.body]", "comments" = list())
if(!message.comments.len)
continue
for(var/datum/newscaster/feed_comment/comment in message.comments)
file_data["[pos]"]["messages"]["comments"] = list("author" = "[comment.author]", "time stamp" = "[comment.time_stamp]", "body" = "[comment.body]")
pos++
if(GLOB.news_network.wanted_issue.active)
file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scannedUser]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]")
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/ticker/proc/declare_completion()
set waitfor = FALSE
@@ -110,6 +72,7 @@
H.add_hud_to(M)
CHECK_TICK
//Set news report and mode result
mode.set_round_result()
@@ -189,29 +152,49 @@
return parts.Join()
/datum/controller/subsystem/ticker/proc/survivor_report()
var/list/parts = list()
/datum/controller/subsystem/ticker/proc/count_survivors()
. = list()
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
var/num_survivors = 0
var/num_escapees = 0
var/num_shuttle_escapees = 0
var/num_ghosts = 0
var/num_human_survivors = 0
var/num_human_escapees = 0
//Player status report
for(var/i in GLOB.mob_list)
var/mob/Player = i
if(Player.mind && !isnewplayer(Player))
if(isobserver(Player))
num_ghosts++
if(Player.stat != DEAD && !isbrain(Player))
num_survivors++
if(ishuman(Player))
num_human_survivors++
if(station_evacuated) //If the shuttle has already left the station
var/list/area/shuttle_areas
if(SSshuttle && SSshuttle.emergency)
shuttle_areas = SSshuttle.emergency.shuttle_areas
if(Player.onCentCom() || Player.onSyndieBase())
num_escapees++
if(ishuman(Player))
num_human_escapees++
if(shuttle_areas[get_area(Player)])
num_shuttle_escapees++
.[POPCOUNT_SURVIVORS] = num_survivors
.[POPCOUNT_ESCAPEES] = num_escapees
.[POPCOUNT_SHUTTLE_ESCAPEES] = num_shuttle_escapees
.[POPCOUNT_HUMAN_SURVIVORS] = num_human_survivors
.[POPCOUNT_HUMAN_ESCAPEES] = num_human_escapees
.[POPCOUNT_GHOSTS] = num_ghosts
/datum/controller/subsystem/ticker/proc/survivor_report()
var/list/parts = list()
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
var/popcount = count_survivors()
//Round statistics report
var/datum/station_state/end_state = new /datum/station_state()
end_state.count()
@@ -223,9 +206,9 @@
if(total_players)
parts+= "[GLOB.TAB]Total Population: <B>[total_players]</B>"
if(station_evacuated)
parts += "<BR>[GLOB.TAB]Evacuation Rate: <B>[num_escapees] ([PERCENT(num_escapees/total_players)]%)</B>"
parts += "[GLOB.TAB](on emergency shuttle): <B>[num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)</B>"
parts += "[GLOB.TAB]Survival Rate: <B>[num_survivors] ([PERCENT(num_survivors/total_players)]%)</B>"
parts += "<BR>[GLOB.TAB]Evacuation Rate: <B>[popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)</B>"
parts += "[GLOB.TAB](on emergency shuttle): <B>[popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)</B>"
parts += "[GLOB.TAB]Survival Rate: <B>[popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)</B>"
return parts.Join("<br>")
/datum/controller/subsystem/ticker/proc/show_roundend_report(client/C,common_report)
+1 -2
View File
@@ -23,8 +23,7 @@
if(..())
return
var/mob/living/silicon/ai/AI = usr
var/camera = input(AI, "Choose which camera you want to view", "Cameras") as null|anything in AI.get_camera_list()
AI.ai_camera_list(camera)
AI.show_camera_list()
/obj/screen/ai/camera_track
name = "Track With Camera"
+2
View File
@@ -60,6 +60,8 @@
var/pref = C.prefs.parallax
if (isnull(pref))
pref = PARALLAX_HIGH
if (C.byond_version < 511)
pref = PARALLAX_DISABLE
switch(C.prefs.parallax)
if (PARALLAX_INSANE)
C.parallax_throttle = FALSE
+2 -1
View File
@@ -58,7 +58,8 @@
SendSignal(COMSIG_ITEM_ATTACK, M, user)
if(flags_1 & NOBLUDGEON_1)
return
if(user.disabilities & PACIFISM)
if(user.has_disability(DISABILITY_PACIFISM))
return
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
+1 -1
View File
@@ -260,7 +260,7 @@
for(var/L in relevant_layers) //Less hardcode
H.remove_overlay(L)
if(H.disabilities & HUSK)
if(H.has_disability(DISABILITY_HUSK))
return
//start scanning for genitals
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
+7
View File
@@ -53,6 +53,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
var/static/random_seed
//current tick limit, assigned before running a subsystem.
//used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits
@@ -60,6 +62,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
/datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
if(!random_seed)
random_seed = rand(1, 1e9)
rand_seed(random_seed)
var/list/_subsystems = list()
subsystems = _subsystems
if (Master != src)
+1
View File
@@ -16,6 +16,7 @@ SUBSYSTEM_DEF(blackbox)
/datum/controller/subsystem/blackbox/Initialize()
triggertime = world.time
record_feedback("amount", "random_seed", Master.random_seed)
. = ..()
//poll population
+2 -2
View File
@@ -21,8 +21,8 @@ SUBSYSTEM_DEF(parallax)
return
continue
var/atom/movable/A = C.eye
if(!A)
return
if(!istype(A))
continue
for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc);
if(A != C.movingmob)
+1 -1
View File
@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(research)
var/list/techweb_point_items = list() //path = value
var/list/errored_datums = list()
//----------------------------------------------
var/single_server_income = 40.7
var/single_server_income = 54.3
var/multiserver_calculation = FALSE
var/last_income = 0
//^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^
-1
View File
@@ -631,7 +631,6 @@ SUBSYSTEM_DEF(ticker)
world.Reboot()
/datum/controller/subsystem/ticker/Shutdown()
gather_newscaster() //called here so we ensure the log is created even upon admin reboot
if(!round_end_sound)
round_end_sound = pick(\
'sound/roundend/newroundsexy.ogg',
+2 -13
View File
@@ -344,19 +344,6 @@
/datum/action/item_action/change
name = "Change"
/datum/action/item_action/nano_picket_sign
name = "Retext Nano Picket Sign"
var/obj/item/picket_sign/S
/datum/action/item_action/nano_picket_sign/New(Target)
..()
if(istype(Target, /obj/item/picket_sign))
S = Target
/datum/action/item_action/nano_picket_sign/Trigger()
if(istype(S))
S.retext(owner)
/datum/action/item_action/adjust
/datum/action/item_action/adjust/New(Target)
@@ -490,6 +477,8 @@
return FALSE
return TRUE
/datum/action/spell_action/spell
/datum/action/spell_action/spell/IsAvailable()
if(!target)
return FALSE
+12 -12
View File
@@ -1,12 +1,12 @@
/datum/action/item_action/zoom_speed_action
name = "Toggle Zooming Speed"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "projectile"
background_icon_state = "bg_tech"
/datum/action/item_action/zoom_lock_action
name = "Switch Zoom Mode"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "zoom_mode"
background_icon_state = "bg_tech"
/datum/action/item_action/zoom_speed_action
name = "Toggle Zooming Speed"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "projectile"
background_icon_state = "bg_tech"
/datum/action/item_action/zoom_lock_action
name = "Switch Zoom Mode"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "zoom_mode"
background_icon_state = "bg_tech"
+2
View File
@@ -1,3 +1,5 @@
/datum/action/item_action/flightsuit
icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
+2 -1
View File
@@ -223,7 +223,8 @@
if(verbose)
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
return
if((target.has_disability(NOCLONE)) || (target.has_disability(NOCLONE)))
if((target.has_disability(DISABILITY_NOCLONE)) || (target.has_disability(DISABILITY_NOCLONE)))
if(verbose)
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
return
+17 -17
View File
@@ -7,14 +7,14 @@
name = "Monkey"
job_rank = ROLE_MONKEY
roundend_category = "monkeys"
var/datum/objective_team/monkey/monkey_team
var/datum/team/monkey/monkey_team
/datum/antagonist/monkey/on_gain()
. = ..()
SSticker.mode.ape_infectees += owner
owner.special_role = "Infected Monkey"
var/datum/disease/D = new /datum/disease/transformation/jungle_fever
var/datum/disease/D = new /datum/disease/transformation/jungle_fever/monkeymode
if(!owner.current.HasDisease(D))
D.affected_mob = owner
owner.current.viruses += D
@@ -38,13 +38,13 @@
if(D)
D.cure()
/datum/antagonist/monkey/create_team(datum/objective_team/monkey/new_team)
/datum/antagonist/monkey/create_team(datum/team/monkey/new_team)
if(!new_team)
for(var/datum/antagonist/monkey/N in get_antagonists(/datum/antagonist/monkey, TRUE))
if(N.monkey_team)
monkey_team = N.monkey_team
return
monkey_team = new /datum/objective_team/monkey
monkey_team = new /datum/team/monkey
monkey_team.update_objectives()
return
if(!istype(new_team))
@@ -60,9 +60,6 @@
/datum/antagonist/monkey/leader/on_gain()
. = ..()
var/datum/disease/D = (/datum/disease/transformation/jungle_fever in owner.current.viruses)
if(D)
D.visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
var/obj/item/organ/heart/freedom/F = new
F.Insert(owner.current, drop_if_replaced = FALSE)
SSticker.mode.ape_leaders += owner
@@ -99,45 +96,45 @@
return TRUE
return FALSE
/datum/objective_team/monkey
/datum/team/monkey
name = "Monkeys"
/datum/objective_team/monkey/proc/update_objectives()
/datum/team/monkey/proc/update_objectives()
objectives = list()
var/datum/objective/monkey/O = new /datum/objective/monkey()
O.team = src
objectives += O
return
/datum/objective_team/monkey/proc/infected_monkeys_alive()
/datum/team/monkey/proc/infected_monkeys_alive()
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
if(M.HasDisease(D))
return TRUE
return FALSE
/datum/objective_team/monkey/proc/infected_monkeys_escaped()
/datum/team/monkey/proc/infected_monkeys_escaped()
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase()))
return TRUE
return FALSE
/datum/objective_team/monkey/proc/infected_humans_escaped()
/datum/team/monkey/proc/infected_humans_escaped()
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
for(var/mob/living/carbon/human/M in GLOB.alive_mob_list)
if(M.HasDisease(D) && (M.onCentCom() || M.onSyndieBase()))
return TRUE
return FALSE
/datum/objective_team/monkey/proc/infected_humans_alive()
/datum/team/monkey/proc/infected_humans_alive()
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
for(var/mob/living/carbon/human/M in GLOB.alive_mob_list)
if(M.HasDisease(D))
return TRUE
return FALSE
/datum/objective_team/monkey/proc/get_result()
/datum/team/monkey/proc/get_result()
if(infected_monkeys_escaped())
return MONKEYS_ESCAPED
if(infected_monkeys_alive())
@@ -146,7 +143,7 @@
return DISEASE_LIVED
return MONKEYS_DIED
/datum/objective_team/monkey/roundend_report()
/datum/team/monkey/roundend_report()
var/list/parts = list()
switch(get_result())
if(MONKEYS_ESCAPED)
@@ -161,10 +158,13 @@
if(MONKEYS_DIED)
parts += "<span class='redtext big'><B>Monkey Major Defeat!</B></span>"
parts += "<span class='redtext'><B>All the monkeys died, and Jungle Fever was wiped out!</B></span>"
if(LAZYLEN(SSticker.mode.ape_leaders))
var/list/leaders = get_antagonists(/datum/antagonist/monkey/leader, TRUE)
var/list/monkeys = get_antagonists(/datum/antagonist/monkey, TRUE)
if(LAZYLEN(leaders))
parts += "<span class='header'>The monkey leaders were:</span>"
parts += printplayerlist(SSticker.mode.ape_leaders)
if(LAZYLEN(SSticker.mode.ape_infectees))
if(LAZYLEN(monkeys))
parts += "<span class='header'>The monkeys were:</span>"
parts += printplayerlist(SSticker.mode.ape_infectees)
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
+2 -2
View File
@@ -42,7 +42,7 @@
lose_text = "<span class='notice'>You feel smart again.</span>"
/datum/brain_trauma/mild/dumbness/on_gain()
owner.add_disability(DUMB, TRAUMA_DISABILITY)
owner.add_disability(DISABILITY_DUMB, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/mild/dumbness/on_life()
@@ -54,7 +54,7 @@
..()
/datum/brain_trauma/mild/dumbness/on_lose()
owner.remove_disability(DUMB, TRAUMA_DISABILITY)
owner.remove_disability(DISABILITY_DUMB, TRAUMA_DISABILITY)
owner.derpspeech = 0
..()
+1 -1
View File
@@ -68,7 +68,7 @@
return
/datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq)
if(owner.disabilities & DEAF || world.time < next_scare) //words can't trigger you if you can't hear them *taps head*
if(owner.has_disability(DISABILITY_DEAF) || world.time < next_scare) //words can't trigger you if you can't hear them *taps head*
return message
for(var/word in trigger_words)
if(findtext(message, word))
+15 -24
View File
@@ -12,11 +12,11 @@
lose_text = "<span class='notice'>You suddenly remember how to speak.</span>"
/datum/brain_trauma/severe/mute/on_gain()
owner.add_disability(MUTE, TRAUMA_DISABILITY)
owner.add_disability(DISABILITY_MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/mute/on_lose()
owner.remove_disability(MUTE, TRAUMA_DISABILITY)
owner.remove_disability(DISABILITY_MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/aphasia
@@ -50,11 +50,17 @@
lose_text = "<span class='notice'>Your vision returns.</span>"
/datum/brain_trauma/severe/blindness/on_gain()
owner.become_blind(TRAUMA_DISABILITY)
owner.become_blind()
..()
//no fiddling with genetics to get out of this one
/datum/brain_trauma/severe/blindness/on_life()
if(!(owner.disabilities & BLIND))
on_gain()
..()
/datum/brain_trauma/severe/blindness/on_lose()
owner.cure_blind(TRAUMA_DISABILITY)
owner.cure_blind()
..()
/datum/brain_trauma/severe/paralysis
@@ -120,7 +126,7 @@
stress -= 4
/datum/brain_trauma/severe/monophobia/proc/check_alone()
if(owner.has_disability(BLIND))
if(owner.has_disability(DISABILITY_BLIND))
return TRUE
for(var/mob/M in oview(owner, 7))
if(!isliving(M)) //ghosts ain't people
@@ -182,11 +188,11 @@
lose_text = "<span class='notice'>You feel in control of your hands again.</span>"
/datum/brain_trauma/severe/discoordination/on_gain()
owner.add_disability(MONKEYLIKE, TRAUMA_DISABILITY)
owner.add_disability(DISABILITY_MONKEYLIKE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/discoordination/on_lose()
owner.remove_disability(MONKEYLIKE, TRAUMA_DISABILITY)
owner.remove_disability(DISABILITY_MONKEYLIKE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism
@@ -197,24 +203,9 @@
lose_text = "<span class='notice'>You no longer feel compelled to not harm.</span>"
/datum/brain_trauma/severe/pacifism/on_gain()
owner.add_disability(PACIFISM, TRAUMA_DISABILITY)
owner.add_disability(DISABILITY_PACIFISM, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism/on_lose()
owner.remove_disability(PACIFISM, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism
name = "Traumatic Non-Violence"
desc = "Patient is extremely unwilling to harm others in violent ways."
scan_desc = "pacific syndrome"
gain_text = "<span class='notice'>You feel oddly peaceful.</span>"
lose_text = "<span class='notice'>You no longer feel compelled to not harm.</span>"
/datum/brain_trauma/severe/pacifism/on_gain()
owner.disabilities |= PACIFISM
..()
/datum/brain_trauma/severe/pacifism/on_lose()
owner.disabilities &= ~PACIFISM
owner.remove_disability(DISABILITY_PACIFISM, TRAUMA_DISABILITY)
..()
@@ -192,7 +192,7 @@
return //no random switching
/datum/brain_trauma/severe/split_personality/brainwashing/on_hear(message, speaker, message_language, raw_message, radio_freq)
if(owner.disabilities & DEAF || owner == speaker)
if(owner.has_disability(DISABILITY_DEAF) || owner == speaker)
return message
if(findtext(message, codeword))
message = replacetext(message, codeword, "<span class='warning'>[codeword]</span>")
+1 -1
View File
@@ -51,7 +51,7 @@
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
if(user.a_intent == INTENT_HARM)
if(user.a_intent != INTENT_HELP)
return
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
+10 -9
View File
@@ -3,29 +3,29 @@
for(var/thing in viruses)
var/datum/disease/DD = thing
if(D.IsSame(DD))
return 1
return 0
return TRUE
return FALSE
/mob/proc/CanContractDisease(datum/disease/D)
if(stat == DEAD)
return 0
return FALSE
if(D.GetDiseaseID() in resistances)
return 0
return FALSE
if(HasDisease(D))
return 0
return FALSE
if(!(type in D.viable_mobtypes))
return 0
return FALSE
return 1
return TRUE
/mob/proc/ContactContractDisease(datum/disease/D)
if(!CanContractDisease(D))
return 0
return FALSE
AddDisease(D)
@@ -53,12 +53,13 @@
else
DD.vars[V] = D.vars[V]
DD.after_add()
DD.affected_mob.med_hud_set_status()
/mob/living/carbon/ContactContractDisease(datum/disease/D, target_zone)
if(!CanContractDisease(D))
return 0
return FALSE
var/obj/item/clothing/Cl = null
var/passed = TRUE
+7 -4
View File
@@ -60,14 +60,14 @@
/datum/disease/proc/has_cure()
if(!(disease_flags & CURABLE))
return 0
return FALSE
. = cures.len
for(var/C_id in cures)
if(!affected_mob.reagents.has_reagent(C_id))
.--
if(!. || (needs_all_cures && . < cures.len))
return 0
return FALSE
//Airborne spreading
/datum/disease/proc/spread(force_spread = 0)
@@ -111,8 +111,8 @@
/datum/disease/proc/IsSame(datum/disease/D)
if(istype(src, D.type))
return 1
return 0
return TRUE
return FALSE
/datum/disease/proc/Copy()
@@ -120,6 +120,9 @@
D.strain_data = strain_data.Copy()
return D
/datum/disease/proc/after_add()
return
/datum/disease/proc/GetDiseaseID()
return "[type]"
+75 -77
View File
@@ -1,10 +1,10 @@
/datum/symptom/heal
name = "Basic Healing (does nothing)" //warning for adminspawn viruses
desc = "You should not be seeing this."
stealth = 0
resistance = 0
stage_speed = 0
transmittable = 0
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 0 //not obtainable
base_message_chance = 20 //here used for the overlays
symptom_delay_min = 1
@@ -22,6 +22,7 @@
/datum/symptom/heal/Activate(datum/disease/advance/A)
if(!..())
return
//100% chance to activate for slow but consistent healing
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
@@ -44,20 +45,20 @@
return TRUE
/datum/symptom/heal/starlight
/datum/symptom/heal/toxin
name = "Starlight Condensation"
desc = "The virus reacts to direct starlight, producing regenerative chemicals. Works best against toxin-based damage."
stealth = -1
resistance = -2
stage_speed = 0
transmittable = 1
desc = "The virus reacts to direct starlight, producing regenerative chemicals that can cure toxin damage."
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -3
level = 6
passive_message = "<span class='notice'>You miss the feeling of starlight on your skin.</span>"
var/nearspace_penalty = 0.3
threshold_desc = "<b>Stage Speed 6:</b> Increases healing speed.<br>\
<b>Transmission 6:</b> Removes penalty for only being close to space."
/datum/symptom/heal/starlight/Start(datum/disease/advance/A)
/datum/symptom/heal/toxin/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["transmission"] >= 6)
@@ -65,7 +66,7 @@
if(A.properties["stage_rate"] >= 6)
power = 2
/datum/symptom/heal/starlight/CanHeal(datum/disease/advance/A)
/datum/symptom/heal/toxin/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
if(istype(get_turf(M), /turf/open/space))
return power
@@ -74,25 +75,15 @@
if(istype(T, /turf/open/space))
return power * nearspace_penalty
/datum/symptom/heal/starlight/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
if(M.getToxLoss() && prob(5))
to_chat(M, "<span class='notice'>Your skin tingles as the starlight seems to heal you.</span>")
M.adjustToxLoss(-(4 * heal_amt)) //most effective on toxins
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
M.update_damage_overlays()
to_chat(M, "<span class='notice'>Your skin tingles as the starlight purges toxins from your bloodstream.</span>")
M.adjustToxLoss(-heal_amt)
return 1
/datum/symptom/heal/starlight/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss() || M.getToxLoss())
/datum/symptom/heal/toxin/passive_message_condition(mob/living/M)
if(M.getToxLoss())
return TRUE
return FALSE
@@ -100,7 +91,7 @@
name = "Toxolysis"
stealth = 0
resistance = -2
stage_speed = 2
stage_speed = -2
transmittable = -2
level = 7
var/food_conversion = FALSE
@@ -162,50 +153,58 @@
to_chat(C, "<span class='notice'>You feel an odd gurgle in your stomach, as if it was working much faster than normal.</span>")
return 1
/datum/symptom/heal/darkness
name = "Nocturnal Regeneration"
desc = "The virus is able to mend the host's flesh when in conditions of low light, repairing physical damage. More effective against brute damage."
stealth = 2
resistance = -1
stage_speed = -2
transmittable = -1
/datum/symptom/heal/brute
name = "Cellular Molding"
desc = "The virus is able to shift cells around when in conditions of high heat, repairing existing physical damage."
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -3
level = 6
passive_message = "<span class='notice'>You feel tingling on your skin as light passes over it.</span>"
passive_message = "<span class='notice'>You feel the flesh pulsing under your skin for a moment, but it's too cold to move.</span>"
threshold_desc = "<b>Stage Speed 8:</b> Doubles healing speed."
/datum/symptom/heal/darkness/Start(datum/disease/advance/A)
/datum/symptom/heal/brute/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 8)
power = 2
/datum/symptom/heal/darkness/CanHeal(datum/disease/advance/A)
/datum/symptom/heal/brute/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/light_amount = 0
if(isturf(M.loc)) //else, there's considered to be no light
var/turf/T = M.loc
light_amount = min(1,T.get_lumcount()) - 0.5
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
return power
switch(M.bodytemperature)
if(0 to 340)
return FALSE
if(340 to BODYTEMP_HEAT_DAMAGE_LIMIT)
. = 0.3 * power
if(BODYTEMP_HEAT_DAMAGE_LIMIT to 400)
. = 0.75 * power
if(400 to 460)
. = power
else
. = 1.5 * power
/datum/symptom/heal/darkness/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
if(M.on_fire)
. *= 2
/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1)
var/list/parts = M.get_damaged_bodyparts(1,0) //brute only
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The darkness soothes and mends your wounds.</span>")
to_chat(M, "<span class='notice'>You feel your flesh moving beneath your heated skin, mending your wounds.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5)) //more effective on brute
if(L.heal_damage(heal_amt/parts.len, 0))
M.update_damage_overlays()
return 1
/datum/symptom/heal/darkness/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
/datum/symptom/heal/brute/passive_message_condition(mob/living/M)
if(M.getBruteLoss())
return TRUE
return FALSE
@@ -213,8 +212,8 @@
name = "Regenerative Coma"
desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage."
stealth = 0
resistance = 2
stage_speed = -3
resistance = 0
stage_speed = -2
transmittable = -2
level = 8
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
@@ -284,20 +283,20 @@
return TRUE
return FALSE
/datum/symptom/heal/water
/datum/symptom/heal/burn
name = "Tissue Hydration"
desc = "The virus uses excess water inside and outside the body to repair damaged tissue cells. More effective against burns."
stealth = 0
resistance = -1
stage_speed = 0
transmittable = 1
desc = "The virus uses excess water inside and outside the body to repair burned tisue cells."
stealth = 1
resistance = -3
stage_speed = -3
transmittable = -3
level = 6
passive_message = "<span class='notice'>Your skin feels oddly dry...</span>"
passive_message = "<span class='notice'>Your burned skin feels oddly dry...</span>"
var/absorption_coeff = 1
threshold_desc = "<b>Resistance 5:</b> Water is consumed at a much slower rate.<br>\
<b>Stage Speed 7:</b> Increases healing speed."
/datum/symptom/heal/water/Start(datum/disease/advance/A)
/datum/symptom/heal/burn/Start(datum/disease/advance/A)
if(!..())
return
if(A.properties["stage_rate"] >= 7)
@@ -305,7 +304,7 @@
if(A.properties["stealth"] >= 2)
absorption_coeff = 0.25
/datum/symptom/heal/water/CanHeal(datum/disease/advance/A)
/datum/symptom/heal/burn/CanHeal(datum/disease/advance/A)
. = 0
var/mob/living/M = A.affected_mob
if(M.fire_stacks < 0)
@@ -318,33 +317,33 @@
M.reagents.remove_reagent("water", 0.5 * absorption_coeff)
. += power * 0.5
/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 2 * actual_power
var/list/parts = M.get_damaged_bodyparts(1,1) //more effective on burns
var/list/parts = M.get_damaged_bodyparts(0,1) //burn only
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing the water around you to soothe your damaged skin.</span>")
to_chat(M, "<span class='notice'>You feel yourself absorbing the water around you to soothe your burned skin.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len))
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/water/passive_message_condition(mob/living/M)
if(M.getBruteLoss() || M.getFireLoss())
/datum/symptom/heal/burn/passive_message_condition(mob/living/M)
if(M.getFireLoss())
return TRUE
return FALSE
/datum/symptom/heal/plasma
name = "Plasma Fixation"
desc = "The virus draws plasma from the atmosphere and from inside the body to heal and stabilize body temperature."
desc = "The virus draws plasma from the atmosphere and from inside the body to stabilize body temperature and heal burns."
stealth = 0
resistance = 3
resistance = 0
stage_speed = -2
transmittable = -2
level = 8
@@ -380,6 +379,8 @@
/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
var/list/parts = M.get_damaged_bodyparts(0,1) //burn only
if(prob(5))
to_chat(M, "<span class='notice'>You feel yourself absorbing plasma inside and around you...</span>")
@@ -392,25 +393,24 @@
if(prob(5))
to_chat(M, "<span class='notice'>You feel warmer.</span>")
M.adjustToxLoss(-heal_amt)
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
return
if(prob(5))
to_chat(M, "<span class='notice'>The pain from your wounds fades rapidly.</span>")
to_chat(M, "<span class='notice'>The pain from your burns fades rapidly.</span>")
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len))
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
return 1
/datum/symptom/heal/radiation
name = "Radioactive Resonance"
desc = "The virus uses radiation to fix damage through dna mutations."
stealth = -1
resistance = -2
stage_speed = 2
stage_speed = 0
transmittable = -3
level = 6
symptom_delay_min = 1
@@ -450,8 +450,6 @@
if(cellular_damage)
M.adjustCloneLoss(-heal_amt * 0.5)
M.adjustToxLoss(-(2 * heal_amt))
var/list/parts = M.get_damaged_bodyparts(1,1)
if(!parts.len)
@@ -58,12 +58,11 @@ Bonus
M.blur_eyes(20)
M.adjust_eye_damage(5)
if(eyes.eye_damage >= 10)
M.become_nearsighted(EYE_DAMAGE)
M.become_nearsighted()
if(prob(eyes.eye_damage - 10 + 1))
if(!remove_eyes)
if(!M.has_disability(BLIND))
if(!M.has_disability(DISABILITY_BLIND))
to_chat(M, "<span class='userdanger'>You go blind!</span>")
M.become_blind(EYE_DAMAGE)
else
M.visible_message("<span class='warning'>[M]'s eyes fall off their sockets!</span>", "<span class='userdanger'>Your eyes fall off their sockets!</span>")
eyes.Remove(M)
@@ -112,18 +111,16 @@ Bonus
return
switch(A.stage)
if(4, 5) //basically oculine
if(M.has_disability(BLIND, EYE_DAMAGE))
if(M.has_disability(DISABILITY_BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "<span class='warning'>Your vision slowly returns...</span>")
M.cure_blind(EYE_DAMAGE)
M.cure_nearsighted(EYE_DAMAGE)
M.cure_blind()
M.cure_nearsighted()
M.blur_eyes(35)
else if(M.has_disability(NEARSIGHT, EYE_DAMAGE))
else if(M.has_disability(DISABILITY_NEARSIGHT, EYE_DAMAGE))
to_chat(M, "<span class='warning'>The blackness in your peripheral vision fades.</span>")
M.cure_nearsighted(EYE_DAMAGE)
M.cure_nearsighted()
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
M.set_blindness(0)
M.set_blurriness(0)
+15 -5
View File
@@ -1,6 +1,6 @@
/datum/disease/gbs
name = "GBS"
max_stages = 4
max_stages = 5
spread_text = "On contact"
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS
cure_text = "Synaptizine & Sulfur"
@@ -16,15 +16,25 @@
..()
switch(stage)
if(2)
if(prob(5))
affected_mob.emote("cough")
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))
to_chat(affected_mob, "<span class='danger'>Your body hurts all over!</span>")
to_chat(affected_mob, "<span class='danger'>You're starting to feel very weak...</span>")
if(4)
to_chat(affected_mob, "<span class='userdanger'>Your body feels as if it's trying to rip itself apart!</span>")
if(prob(10))
affected_mob.emote("cough")
affected_mob.adjustToxLoss(5)
affected_mob.updatehealth()
if(5)
to_chat(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
+11 -2
View File
@@ -65,8 +65,8 @@
/datum/disease/transformation/jungle_fever
name = "Jungle Fever"
cure_text = "Bananas"
cures = list("banana")
cure_text = "Death."
cures = list("adminordrazine")
spread_text = "Monkey Bites"
spread_flags = VIRUS_SPREAD_SPECIAL
viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human)
@@ -113,6 +113,15 @@
remove_monkey(affected_mob.mind)
..()
/datum/disease/transformation/jungle_fever/monkeymode
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
disease_flags = CAN_CARRY //no vaccines! no cure!
/datum/disease/transformation/jungle_fever/monkeymode/after_add()
if(affected_mob && !is_monkey_leader(affected_mob.mind))
visibility_flags = NONE
/datum/disease/transformation/robot
-2
View File
@@ -45,8 +45,6 @@
set name = "Show Server Revision"
set desc = "Check the current server code revision"
if(GLOB.round_id)
to_chat(src, "<b>Round ID:</b> [GLOB.round_id]")
if(GLOB.revdata.originmastercommit)
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
var/prefix = ""
+1 -1
View File
@@ -197,7 +197,7 @@
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
if((user.has_disability(CLUMSY)) && prob(50))
if((user.has_disability(DISABILITY_CLUMSY)) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
user.Knockdown(60)
if(ishuman(user))
+7 -21
View File
@@ -461,27 +461,20 @@
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (ishuman(current))
if(is_monkey_leader(src))
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> <b>LEADER</b> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <b>HUMAN</b> | other"
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <b>HUMAN</b> | other"
else if(ismonkey(current))
var/found = FALSE
for(var/datum/disease/transformation/jungle_fever/JF in current.viruses)
found = TRUE
break
var/isLeader = is_monkey_leader(src)
if(isLeader)
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> <b>LEADER</b> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else if(found)
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <b>INFECTED</b> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
if(found)
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <b>INFECTED</b> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "<b>HEALTHY</b> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
text += "<b>HEALTHY</b> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "healthy | infected | leader | human | <b>OTHER</b>"
text += "healthy | infected | human | <b>OTHER</b>"
if(current && current.client && (ROLE_MONKEY in current.client.prefs.be_special))
text += " | Enabled in Prefs"
@@ -1262,17 +1255,11 @@
else if (istype(M) && length(M.viruses))
for(var/thing in M.viruses)
var/datum/disease/D = thing
D.cure(FALSE)
if("leader")
if(check_rights(R_ADMIN, 0))
add_monkey_leader(src)
log_admin("[key_name(usr)] made [key_name(current)] a monkey leader!")
message_admins("[key_name_admin(usr)] made [key_name_admin(current)] a monkey leader!")
D.cure(0)
if("infected")
if(check_rights(R_ADMIN, 0))
if (check_rights(R_ADMIN, 0))
var/mob/living/carbon/human/H = current
var/mob/living/carbon/monkey/M = current
add_monkey(src)
if (istype(H))
log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]</span>")
@@ -1290,7 +1277,6 @@
for(var/datum/disease/transformation/jungle_fever/JF in M.viruses)
JF.cure(0)
stoplag() //because deleting of virus is doing throught spawn(0) //What
remove_monkey(src)
log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]</span>")
H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
+1
View File
@@ -8,6 +8,7 @@ GLOBAL_LIST_EMPTY(mutations_list)
GLOB.mutations_list[name] = src
/datum/mutation/human
var/dna_block
var/quality
var/get_chance = 100
+4 -4
View File
@@ -85,12 +85,12 @@
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.add_disability(CLUMSY, GENETIC_MUTATION)
owner.add_disability(DISABILITY_CLUMSY, GENETIC_MUTATION)
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.remove_disability(CLUMSY, GENETIC_MUTATION)
owner.remove_disability(DISABILITY_CLUMSY, GENETIC_MUTATION)
//Tourettes causes you to randomly stand in place and shout.
@@ -124,12 +124,12 @@
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.add_disability(DEAF, GENETIC_MUTATION)
owner.add_disability(DISABILITY_DEAF, GENETIC_MUTATION)
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.remove_disability(DEAF, GENETIC_MUTATION)
owner.remove_disability(DISABILITY_DEAF, GENETIC_MUTATION)
//Monified turns you into a monkey.
+4 -4
View File
@@ -7,12 +7,12 @@
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.become_nearsighted(GENETIC_MUTATION)
owner.become_nearsighted()
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.cure_nearsighted(GENETIC_MUTATION)
owner.cure_nearsighted()
//Blind makes you blind. Who knew?
@@ -24,12 +24,12 @@
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.become_blind(GENETIC_MUTATION)
owner.become_blind()
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.cure_blind(GENETIC_MUTATION)
owner.cure_blind()
//X-Ray Vision lets you see through walls.
+2 -2
View File
@@ -30,12 +30,12 @@
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.add_disability(MUTE, GENETIC_MUTATION)
owner.add_disability(DISABILITY_MUTE, GENETIC_MUTATION)
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.remove_disability(MUTE, GENETIC_MUTATION)
owner.remove_disability(DISABILITY_MUTE, GENETIC_MUTATION)
/datum/mutation/human/smile
+239 -239
View File
@@ -1,239 +1,239 @@
//Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
var/x = 0
var/y = 0
var/z = 0
var/pixel_x = 0
var/pixel_y = 0
/datum/position/proc/valid()
return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
if(istype(_x, /datum/point))
var/datum/point/P = _x
var/turf/T = P.return_turf()
_x = T.x
_y = T.y
_z = T.z
_pixel_x = P.return_px()
_pixel_y = P.return_py()
else if(isatom(_x))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
x = _x
y = _y
z = _z
pixel_x = _pixel_x
pixel_y = _pixel_y
/datum/position/proc/return_turf()
return locate(x, y, z)
/datum/position/proc/return_px()
return pixel_x
/datum/position/proc/return_py()
return pixel_y
/datum/position/proc/return_point()
return new /datum/point(src)
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
var/datum/point/P = new
P.x = round(a.x + (b.x - a.x) / 2, 1)
P.y = round(a.y + (b.y - a.y) / 2, 1)
P.z = a.z
return P
/proc/pixel_length_between_points(datum/point/a, datum/point/b)
return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
/proc/angle_between_points(datum/point/a, datum/point/b)
return ATAN2((b.y - a.y), (b.x - a.x))
/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
var/x = 0
var/y = 0
var/z = 0
/datum/point/proc/valid()
return x && y && z
/datum/point/proc/copy_to(datum/point/p = new)
p.x = x
p.y = y
p.z = z
return p
/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
if(istype(_x, /datum/position))
var/datum/position/P = _x
_x = P.x
_y = P.y
_z = P.z
_pixel_x = P.pixel_x
_pixel_y = P.pixel_y
else if(istype(_x, /atom))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
if(!isnull(tile_x))
x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x
if(!isnull(tile_y))
y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2+ p_y
if(!isnull(tile_z))
z = tile_z
/datum/point/proc/return_turf()
return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_position()
return new /datum/position(src)
/datum/point/proc/return_px()
return MODULUS(x, world.icon_size) - 16
/datum/point/proc/return_py()
return MODULUS(y, world.icon_size) - 16
/datum/point/proc/mapcheck()
. = FALSE
var/maxx = world.icon_size * world.maxx
var/maxy = world.icon_size * world.maxy
var/move_zx = 0
var/move_zy = 0
if(x < 0)
x += maxx
move_zx -= 1
if(y < 0)
y += maxy
move_zy -= 1
if(x > maxx)
x -= maxx
move_zx += 1
if(y > maxy)
y -= maxy
move_zy += 1
var/datum/space_level/S = GLOB.z_levels_list["[z]"]
if(move_zx != 0)
var/datum/space_level/L = S.neigbours["[move_zx < 0? WEST : EAST]"]
z = L.z_value
. = TRUE
if(move_zy != 0)
var/datum/space_level/L = S.neigbours["[move_zy < 0? SOUTH : NORTH]"]
z = L.z_value
. = TRUE
/datum/point/vector
var/speed = 32 //pixels per iteration
var/iteration = 0
var/angle = 0
var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
var/mpy = 0
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
var/starting_y = 0
var/starting_z = 0
/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed)
..()
initialize_trajectory(_speed, _angle)
/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
. = ..()
starting_x = x
starting_y = y
starting_z = z
/datum/point/vector/copy_to(datum/point/vector/v = new)
..(v)
v.speed = speed
v.iteration = iteration
v.angle = angle
v.mpx = mpx
v.mpy = mpy
v.starting_x = starting_x
v.starting_y = starting_y
v.starting_z = starting_z
return v
/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
if(!isnull(pixel_speed))
speed = pixel_speed
set_angle(new_angle)
/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
if(isnull(angle))
return
angle = new_angle
update_offsets()
/datum/point/vector/proc/update_offsets()
mpx = sin(angle) * speed
mpy = cos(angle) * speed
/datum/point/vector/proc/set_speed(new_speed)
if(isnull(new_speed) || speed == new_speed)
return
speed = new_speed
update_offsets()
/datum/point/vector/proc/increment(multiplier = 1)
iteration++
x += mpx * 1
y += mpy * 1
if(mapcheck())
on_z_change()
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
var/datum/point/vector/v = copy_to()
if(force_simulate)
for(var/i in 1 to amount)
v.increment(multiplier)
else
v.increment(multiplier * amount)
return v
/datum/point/vector/proc/on_z_change()
return
/datum/point/vector/processed //pixel_speed is per decisecond.
var/last_process = 0
var/last_move = 0
var/paused = FALSE
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/proc/start()
last_process = world.time
last_move = world.time
START_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/process()
if(paused)
last_move += world.time - last_process
last_process = world.time
return
var/needed_time = world.time - last_move
last_process = world.time
last_move = world.time
increment(needed_time)
//Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
var/x = 0
var/y = 0
var/z = 0
var/pixel_x = 0
var/pixel_y = 0
/datum/position/proc/valid()
return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
if(istype(_x, /datum/point))
var/datum/point/P = _x
var/turf/T = P.return_turf()
_x = T.x
_y = T.y
_z = T.z
_pixel_x = P.return_px()
_pixel_y = P.return_py()
else if(isatom(_x))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
x = _x
y = _y
z = _z
pixel_x = _pixel_x
pixel_y = _pixel_y
/datum/position/proc/return_turf()
return locate(x, y, z)
/datum/position/proc/return_px()
return pixel_x
/datum/position/proc/return_py()
return pixel_y
/datum/position/proc/return_point()
return new /datum/point(src)
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
var/datum/point/P = new
P.x = round(a.x + (b.x - a.x) / 2, 1)
P.y = round(a.y + (b.y - a.y) / 2, 1)
P.z = a.z
return P
/proc/pixel_length_between_points(datum/point/a, datum/point/b)
return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
/proc/angle_between_points(datum/point/a, datum/point/b)
return ATAN2((b.y - a.y), (b.x - a.x))
/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
var/x = 0
var/y = 0
var/z = 0
/datum/point/proc/valid()
return x && y && z
/datum/point/proc/copy_to(datum/point/p = new)
p.x = x
p.y = y
p.z = z
return p
/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
if(istype(_x, /datum/position))
var/datum/position/P = _x
_x = P.x
_y = P.y
_z = P.z
_pixel_x = P.pixel_x
_pixel_y = P.pixel_y
else if(istype(_x, /atom))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
if(!isnull(tile_x))
x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x
if(!isnull(tile_y))
y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2+ p_y
if(!isnull(tile_z))
z = tile_z
/datum/point/proc/return_turf()
return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_position()
return new /datum/position(src)
/datum/point/proc/return_px()
return MODULUS(x, world.icon_size) - 16
/datum/point/proc/return_py()
return MODULUS(y, world.icon_size) - 16
/datum/point/proc/mapcheck()
. = FALSE
var/maxx = world.icon_size * world.maxx
var/maxy = world.icon_size * world.maxy
var/move_zx = 0
var/move_zy = 0
if(x < 0)
x += maxx
move_zx -= 1
if(y < 0)
y += maxy
move_zy -= 1
if(x > maxx)
x -= maxx
move_zx += 1
if(y > maxy)
y -= maxy
move_zy += 1
var/datum/space_level/S = GLOB.z_levels_list["[z]"]
if(move_zx != 0)
var/datum/space_level/L = S.neigbours["[move_zx < 0? WEST : EAST]"]
z = L.z_value
. = TRUE
if(move_zy != 0)
var/datum/space_level/L = S.neigbours["[move_zy < 0? SOUTH : NORTH]"]
z = L.z_value
. = TRUE
/datum/point/vector
var/speed = 32 //pixels per iteration
var/iteration = 0
var/angle = 0
var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
var/mpy = 0
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
var/starting_y = 0
var/starting_z = 0
/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed)
..()
initialize_trajectory(_speed, _angle)
/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
. = ..()
starting_x = x
starting_y = y
starting_z = z
/datum/point/vector/copy_to(datum/point/vector/v = new)
..(v)
v.speed = speed
v.iteration = iteration
v.angle = angle
v.mpx = mpx
v.mpy = mpy
v.starting_x = starting_x
v.starting_y = starting_y
v.starting_z = starting_z
return v
/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
if(!isnull(pixel_speed))
speed = pixel_speed
set_angle(new_angle)
/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
if(isnull(angle))
return
angle = new_angle
update_offsets()
/datum/point/vector/proc/update_offsets()
mpx = sin(angle) * speed
mpy = cos(angle) * speed
/datum/point/vector/proc/set_speed(new_speed)
if(isnull(new_speed) || speed == new_speed)
return
speed = new_speed
update_offsets()
/datum/point/vector/proc/increment(multiplier = 1)
iteration++
x += mpx * 1
y += mpy * 1
if(mapcheck())
on_z_change()
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
var/datum/point/vector/v = copy_to()
if(force_simulate)
for(var/i in 1 to amount)
v.increment(multiplier)
else
v.increment(multiplier * amount)
return v
/datum/point/vector/proc/on_z_change()
return
/datum/point/vector/processed //pixel_speed is per decisecond.
var/last_process = 0
var/last_move = 0
var/paused = FALSE
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/proc/start()
last_process = world.time
last_move = world.time
START_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/process()
if(paused)
last_move += world.time - last_process
last_process = world.time
return
var/needed_time = world.time - last_move
last_process = world.time
last_move = world.time
increment(needed_time)
+1 -23
View File
@@ -33,7 +33,7 @@
if(LINGHIVE_LING)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
var/msg = "<i><font color=#800080><b>[changeling.changelingID]:</b> [message]</font></i>"
log_talk(user,"[changeling.changelingID]/[user.key] : [message]",LOGSAY)
log_talk(src,"[changeling.changelingID]/[user.key] : [message]",LOGSAY)
for(var/_M in GLOB.mob_list)
var/mob/M = _M
if(M in GLOB.dead_mob_list)
@@ -110,25 +110,3 @@
AI.holopad_talk(message, language)
return FALSE
return TRUE
/datum/saymode/monkey
key = "k"
mode = MODE_MONKEY
/datum/saymode/monkey/handle_message(mob/living/user, message, datum/language/language)
var/datum/mind = user.mind
if(!mind)
return TRUE
if(is_monkey_leader(mind) || (ismonkey(user) && is_monkey(mind)))
log_talk(user, "(MONKEY) [user]/[user.key]: [message]",LOGSAY)
if(prob(75) && ismonkey(user))
user.visible_message("<span class='notice'>\The [user] chimpers.</span>")
var/msg = "<span class='[is_monkey_leader(mind) ? "monkeylead" : "monkeyhive"]'><b><font size=2>\[[is_monkey_leader(mind) ? "Monkey Leader" : "Monkey"]\]</font> [user]</b>: [message]</span>"
for(var/_M in GLOB.mob_list)
var/mob/M = _M
if(M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, user)
to_chat(M, "[link] [msg]")
if((is_monkey_leader(M.mind) || ismonkey(M)) && (M.mind in SSticker.mode.ape_infectees))
to_chat(M, msg)
return FALSE
-1
View File
@@ -78,7 +78,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
QDEL_NULL(ghost_appearance)
/datum/atom_hud/alternate_appearance/basic/add_to_hud(atom/A)
LAZYINITLIST(A.hud_list)
A.hud_list[appearance_key] = theImage
. = ..()
+2
View File
@@ -62,6 +62,7 @@
var/list/firealarms
var/firedoors_last_closed_on = 0
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
@@ -105,6 +106,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
uid = ++global_uid
related = list(src)
map_name = name // Save the initial (the name set in the map) name of the area.
canSmoothWithAreas = typecacheof(canSmoothWithAreas)
if(requires_power)
luminosity = 0
+21 -9
View File
@@ -11,6 +11,11 @@
valid_territory = FALSE
icon_state = "shuttle"
/area/shuttle/Initialize()
if(!canSmoothWithAreas)
canSmoothWithAreas = type
. = ..()
////////////////////////////Multi-area shuttles////////////////////////////
////////////////////////////Syndicate infiltrator////////////////////////////
@@ -19,6 +24,7 @@
name = "Syndicate Infiltrator"
blob_allowed = FALSE
ambientsounds = HIGHSEC
canSmoothWithAreas = /area/shuttle/syndicate
/area/shuttle/syndicate/bridge
name = "Syndicate Infiltrator Control"
@@ -37,6 +43,18 @@
/area/shuttle/syndicate/airlock
name = "Syndicate Infiltrator Airlock"
////////////////////////////Pirate Shuttle////////////////////////////
/area/shuttle/pirate
name = "Pirate Shuttle"
blob_allowed = FALSE
requires_power = TRUE
canSmoothWithAreas = /area/shuttle/pirate
/area/shuttle/pirate/vault
name = "Pirate Shuttle Vault"
requires_power = FALSE
////////////////////////////Single-area shuttles////////////////////////////
/area/shuttle/transit
@@ -76,6 +94,9 @@
/area/shuttle/escape
name = "Emergency Shuttle"
/area/shuttle/escape/backup
name = "Backup Emergency Shuttle"
/area/shuttle/escape/luxury
name = "Luxurious Emergency Shuttle"
noteleport = TRUE
@@ -111,12 +132,3 @@
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
blob_allowed = FALSE
/area/shuttle/pirate
name = "Pirate Shuttle"
blob_allowed = FALSE
requires_power = TRUE
/area/shuttle/pirate/vault
name = "Pirate Shuttle Vault"
requires_power = FALSE
+32
View File
@@ -132,12 +132,44 @@
if (orbiting)
orbiting.Check()
if(flags_1 & CLEAN_ON_MOVE_1)
clean_on_move()
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
return 1
/atom/movable/proc/clean_on_move()
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
cleaned_human.wash_cream()
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
/atom/movable/Destroy(force)
var/inform_admins = (flags_2 & INFORM_ADMINS_ON_RELOCATE_2)
var/stationloving = (flags_2 & STATIONLOVING_2)
@@ -90,7 +90,7 @@
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
if((target.has_disability(HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
if((target.has_disability(DISABILITY_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
@@ -131,7 +131,7 @@
return
if(isliving(target))
var/mob/living/L = target
if((L.has_disability(HUSK)) || !L.has_dna())
if((L.has_disability(DISABILITY_HUSK)) || !L.has_dna())
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
@@ -209,7 +209,7 @@
/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
add_logs(user, target, "stung", "blind sting")
to_chat(target, "<span class='danger'>Your eyes burn horrifically!</span>")
target.become_nearsighted(EYE_DAMAGE)
target.become_nearsighted()
target.blind_eyes(20)
target.blur_eyes(40)
return TRUE
@@ -14,7 +14,7 @@
/obj/effect/clockwork/servant_blocker/CanPass(atom/movable/M, turf/target)
var/list/target_contents = M.GetAllContents() + M
for(var/mob/living/L in target_contents)
if(is_servant_of_ratvar(L) && get_dir(M, src) != dir) //Unless we're on the side the arrow is pointing directly away from, no-go
if(is_servant_of_ratvar(L) && get_dir(M, src) != dir && L.stat != DEAD) //Unless we're on the side the arrow is pointing directly away from, no-go
to_chat(L, "<span class='danger'>The space beyond here can't be accessed by you or other servants.</span>")
return
return TRUE
@@ -83,7 +83,6 @@
construct_type = /mob/living/simple_animal/drone/cogscarab
w_class = WEIGHT_CLASS_SMALL
var/infinite_resources = TRUE
var/static/obj/item/seasonal_hat //Share it with all other scarabs, since we're from the same cult!
/obj/item/clockwork/construct_chassis/cogscarab/Initialize()
. = ..()
@@ -94,12 +93,6 @@
if(infinite_resources)
//During rounds where they can't interact with the station, let them experiment with builds
construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar
if(!seasonal_hat)
var/obj/item/drone_shell/D = locate() in GLOB.poi_list
if(D && D.possible_seasonal_hats.len)
seasonal_hat = pick(D.possible_seasonal_hats)
else
seasonal_hat = "none"
/obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct)
if(infinite_resources) //Allow them to build stuff and recite scripture
@@ -108,6 +101,3 @@
F.uses_power = FALSE
for(var/obj/item/clockwork/slab/S in cached_stuff)
S.no_cost = TRUE
if(seasonal_hat && seasonal_hat != "none")
var/obj/item/hat = new seasonal_hat(construct)
construct.equip_to_slot_or_del(hat, slot_head)
@@ -32,7 +32,7 @@
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src == H.glasses && !up)
if(H.has_disability(BLIND))
if(H.has_disability(DISABILITY_BLIND))
to_chat(H, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>")
return
if(blind_cultist(H))
@@ -51,7 +51,7 @@
to_chat(victim, "<span class='heavy_brass'>\"It looks like Nar-Sie's dogs really don't value their eyes.\"</span>")
to_chat(victim, "<span class='userdanger'>Your eyes explode with horrific pain!</span>")
victim.emote("scream")
victim.become_blind(EYE_DAMAGE)
victim.become_blind()
victim.adjust_blurriness(30)
victim.adjust_blindness(30)
return TRUE
@@ -76,7 +76,7 @@
..()
if(slot != slot_glasses || up)
return
if(user.has_disability(BLIND))
if(user.has_disability(DISABILITY_BLIND))
to_chat(user, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>" )
return
if(blind_cultist(user)) //Cultists instantly go blind
@@ -115,11 +115,11 @@
var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses
desc = "[glasses_right && !WS.up ? "<font color=#DAAA18><b>":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!</b></font>":"."]<br>\
You have taken <font color=#DAAA18><b>[W.eye_damage_done]</b></font> eye damage from them.<br>"
if(L.has_disability(NEARSIGHT))
if(L.has_disability(DISABILITY_NEARSIGHT))
desc += "<font color=#DAAA18><b>You are nearsighted!</b></font><br>"
else if(glasses_right && !WS.up)
desc += "You will become nearsighted at <font color=#DAAA18><b>[W.nearsight_breakpoint]</b></font> eye damage.<br>"
if(L.has_disability(BLIND))
if(L.has_disability(DISABILITY_BLIND))
desc += "<font color=#DAAA18><b>You are blind!</b></font>"
else if(glasses_right && !WS.up)
desc += "You will become blind at <font color=#DAAA18><b>[W.blind_breakpoint]</b></font> eye damage."
@@ -142,8 +142,8 @@
apply_eye_damage(H)
else
if(GLOB.ratvar_awakens)
H.cure_nearsighted(list(EYE_DAMAGE))
H.cure_blind(list(EYE_DAMAGE))
H.cure_nearsighted()
H.cure_blind()
H.adjust_eye_damage(-eye_damage_done)
eye_damage_done = 0
else if(prob(50) && eye_damage_done)
@@ -153,20 +153,18 @@
qdel(src)
/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
if(H.has_disability(BLIND))
if(H.has_disability(DISABILITY_BLIND))
return
H.adjust_eye_damage(0.5)
eye_damage_done += 0.5
if(eye_damage_done >= 20)
H.adjust_blurriness(2)
if(eye_damage_done >= nearsight_breakpoint)
if(!H.has_disability(NEARSIGHT))
if(!H.has_disability(DISABILITY_NEARSIGHT))
to_chat(H, "<span class='nzcrentr'>Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!</span>")
H.become_nearsighted(EYE_DAMAGE)
if(eye_damage_done >= blind_breakpoint)
if(!H.has_disability(BLIND))
if(!H.has_disability(DISABILITY_BLIND))
to_chat(H, "<span class='nzcrentr_large'>A piercing white light floods your vision. Suddenly, all goes dark!</span>")
H.become_blind(EYE_DAMAGE)
if(prob(min(20, 5 + eye_damage_done)))
to_chat(H, "<span class='nzcrentr_small'><i>Your eyes continue to burn.</i></span>")
@@ -1,7 +1,3 @@
//Helper proc to get an Eminence mob if it exists
/proc/get_eminence()
return locate(/mob/camera/eminence) in servants_and_ghosts()
//The Eminence is a unique mob that functions like the leader of the cult. It's incorporeal but can interact with the world in several ways.
/mob/camera/eminence
name = "\the Emininence"
@@ -16,7 +12,6 @@
layer = FLY_LAYER
faction = list("ratvar")
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
var/turf/last_failed_turf
var/static/superheated_walls = 0
/mob/camera/eminence/CanPass(atom/movable/mover, turf/target)
@@ -25,37 +20,25 @@
/mob/camera/eminence/Move(NewLoc, direct)
var/OldLoc = loc
if(NewLoc && !istype(NewLoc, /turf/open/indestructible/reebe_void))
var/turf/T = get_turf(NewLoc)
if(T.flags_1 & NOJAUNT_1)
if(last_failed_turf != T)
T.visible_message("<span class='warning'>[T] suddenly emits a ringing sound!</span>", ignore_mob = src)
playsound(T, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
last_failed_turf = T
to_chat(src, "<span class='warning'>This turf is consecrated and can't be crossed!</span>")
return
if(istype(get_area(T), /area/chapel))
to_chat(src, "<span class='warning'>The Chapel is hallowed ground under a heretical deity, and can't be accessed!</span>")
return
forceMove(T)
forceMove(get_turf(NewLoc))
Moved(OldLoc, direct)
if(GLOB.ratvar_awakens)
for(var/turf/T in range(5, src))
if(prob(166 - (get_dist(src, T) * 33)))
T.ratvar_act() //Causes moving to leave a swath of proselytized area behind the Eminence
/mob/camera/eminence/Process_Spacemove(movement_dir = 0)
return TRUE
/mob/camera/eminence/Login()
..()
var/datum/antagonist/clockcult/C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE)
if(C && C.clock_team)
if(C.clock_team.eminence && C.clock_team.eminence != src)
remove_servant_of_ratvar(src,TRUE)
qdel(src)
return
else
C.clock_team.eminence = src
if(!C)
add_servant_of_ratvar(src, TRUE)
C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE)
if(C && C.clock_team)
if(C.clock_team.eminence)
remove_servant_of_ratvar(src,TRUE)
qdel(src)
else
C.clock_team.eminence = src
to_chat(src, "<span class='bold large_brass'>You have been selected as the Eminence!</span>")
to_chat(src, "<span class='brass'>As the Eminence, you lead the servants. Anything you say will be heard by the entire cult.</span>")
to_chat(src, "<span class='brass'>Though you can move through walls, you're also incorporeal, and largely can't interact with the world except for a few ways.</span>")
@@ -70,12 +53,6 @@
E.Grant(src)
/mob/camera/eminence/say(message)
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot send IC messages (muted).")
return
if(client.handle_spam_prevention(message,MUTE_IC))
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(!message)
return
@@ -83,13 +60,7 @@
if(GLOB.ratvar_awakens)
visible_message("<span class='brass'><b>You feel light slam into your mind and form words:</b> \"[capitalize(message)]\"</span>")
playsound(src, 'sound/machines/clockcult/ark_scream.ogg', 50, FALSE)
message = "<span class='big brass'><b>The [GLOB.ratvar_awakens ? "Radiance" : "Eminence"]:</b> \"[message]\"</span>"
for(var/mob/M in servants_and_ghosts())
if(isobserver(M))
var/link = FOLLOW_LINK(M, src)
to_chat(M, "[link] [message]")
else
to_chat(M, message)
hierophant_message("<span class='large_brass'><b>The Eminence:</b> \"[message]\"</span>")
/mob/camera/eminence/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
if(z == ZLEVEL_CITYOFCOGS || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything
@@ -113,7 +113,7 @@
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/mass_recall()
for(var/V in SSticker.mode.servants_of_ratvar)
var/datum/mind/M = V
if(M.current.stat != DEAD)
if(!M.current.stat)
M.current.forceMove(get_turf(src))
M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
M.current.clear_fullscreen("flash", 5)
@@ -38,6 +38,7 @@
/obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user)
if(!IsAdminGhost(user))
return
var/datum/antagonist/clockcult/random_cultist = locate() in GLOB.antagonists //if theres no cultists new team without eminence will be created anyway.
if(random_cultist && random_cultist.clock_team && random_cultist.clock_team.eminence)
to_chat(user, "<span class='warning'>There's already an Eminence - too late!</span>")
@@ -110,7 +110,7 @@
if(!(BI.resistance_flags & ON_FIRE))
BI.fire_act()
continue
if(is_servant_of_ratvar(L) || (L.has_disability(BLIND)) || L.null_rod_check())
if(is_servant_of_ratvar(L) || (L.has_disability(DISABILITY_BLIND)) || L.null_rod_check())
continue
if(L.stat || L.restrained() || L.buckled || L.lying)
continue
+1 -1
View File
@@ -115,7 +115,7 @@ structure_check() searches for nearby cultist structures required for the invoca
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if((H.has_disability(MUTE)) || H.silent)
if((H.has_disability(DISABILITY_MUTE)) || H.silent)
continue
if(L.stat)
continue
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
sleep(30)
if(!owner || QDELETED(owner))
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
@@ -576,8 +576,8 @@ Congratulations! You are now trained for invasive xenobiology research!"}
flags_1 = DROPDEL_1
/obj/item/restraints/handcuffs/energy/used/dropped(mob/user)
user.visible_message("<span class='danger'>[user]'s [src] break in a discharge of energy!</span>", \
"<span class='userdanger'>[user]'s [src] break in a discharge of energy!</span>")
user.visible_message("<span class='danger'>[user]'s [name] breaks in a discharge of energy!</span>", \
"<span class='userdanger'>[user]'s [name] breaks in a discharge of energy!</span>")
var/datum/effect_system/spark_spread/S = new
S.set_up(4,0,user.loc)
S.start()
@@ -22,7 +22,7 @@
var/players_per_carrier = 30
var/datum/objective_team/monkey/monkey_team
var/datum/team/monkey/monkey_team
+1 -1
View File
@@ -524,7 +524,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/list/otherwise = M.GetAllContents()
for(var/obj/item/disk/tech_disk/TD in otherwise)
TD.stored_research.copy_research_to(checking)
return checking.researched_nodes.len >= target_amount
return checking.researched_nodes.len >= target
/datum/objective/capture
+4 -6
View File
@@ -57,19 +57,17 @@
toggle_cam()
/obj/machinery/camera/Destroy()
toggle_cam(null, 0) //kick anyone viewing out
if(can_use())
toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks
GLOB.cameranet.cameras -= src
if(isarea(myarea))
LAZYREMOVE(myarea.cameras, src)
if(assembly)
qdel(assembly)
assembly = null
QDEL_NULL(assembly)
if(bug)
bug.bugged_cameras -= src.c_tag
if(bug.current == src)
bug.current = null
bug = null
GLOB.cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
GLOB.cameranet.cameras -= src
return ..()
/obj/machinery/camera/emp_act(severity)
+6 -23
View File
@@ -1,10 +1,4 @@
/mob/living/silicon/ai/proc/get_camera_list()
track.cameras.Cut()
if(src.stat == DEAD)
return
var/list/L = list()
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
L.Add(C)
@@ -18,25 +12,18 @@
if (tempnetwork.len)
T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
track.cameras = T
return T
/mob/living/silicon/ai/proc/ai_camera_list(camera)
if (!camera)
return 0
var/obj/machinery/camera/C = track.cameras[camera]
src.eyeobj.setLoc(C)
return
/mob/living/silicon/ai/proc/show_camera_list()
var/list/cameras = get_camera_list()
var/camera = input(src, "Choose which camera you want to view", "Cameras") as null|anything in cameras
switchCamera(cameras[camera])
/datum/trackable
var/list/names = list()
var/list/namecounts = list()
var/list/humans = list()
var/list/others = list()
var/list/cameras = list()
/mob/living/silicon/ai/proc/trackable_mobs()
@@ -143,13 +130,9 @@
/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user)
if (!istype(user))
return
if (!src.can_use())
if (!can_use())
return
user.eyeobj.setLoc(get_turf(src))
/mob/living/silicon/ai/attack_ai(mob/user)
ai_camera_list()
user.switchCamera(src)
/proc/camera_sort(list/L)
var/obj/machinery/camera/a
@@ -83,12 +83,23 @@
if(!eyeobj.eye_initialized)
var/camera_location
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
if(!C.can_use() || z_lock.len && !(C.z in z_lock))
continue
if(C.network & networks)
camera_location = get_turf(C)
break
var/turf/myturf = get_turf(src)
if(eyeobj.use_static)
if((!z_lock.len || (myturf.z in z_lock)) && GLOB.cameranet.checkTurfVis(myturf))
camera_location = myturf
else
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
if(!C.can_use() || z_lock.len && !(C.z in z_lock))
continue
var/list/network_overlap = networks & C.network
if(network_overlap.len)
camera_location = get_turf(C)
break
else
camera_location = myturf
if(z_lock.len && !(myturf.z in z_lock))
camera_location = locate(round(world.maxx/2), round(world.maxy/2), z_lock[1])
if(camera_location)
eyeobj.eye_initialized = TRUE
give_eye_control(L)
@@ -300,9 +311,6 @@
else if(isspaceturf(T))
to_chat(user, "<span class='sevtug_small'>[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]</span>")
return
else if(T.flags_1 & NOJAUNT_1)
to_chat(user, "<span class='sevtug_small'>This tile is blessed by holy water and deflects the warp.</span>")
return
var/area/AR = get_area(T)
if(!AR.clockwork_warp_allowed)
to_chat(user, "<span class='sevtug_small'>[AR.clockwork_warp_fail]</span>")
+1 -1
View File
@@ -449,7 +449,7 @@
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if((mob_occupant.has_disability(NOCLONE)) && (src.scanner.scan_level < 2))
if((mob_occupant.has_disability(DISABILITY_NOCLONE)) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
+2 -2
View File
@@ -81,7 +81,7 @@
if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.has_disability(NOCLONE)) || (connected.scan_level == 3))) //occupant is viable for dna modification
if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.has_disability(DISABILITY_NOCLONE)) || (connected.scan_level == 3))) //occupant is viable for dna modification
occupant_status += "[viable_occupant.name] => "
switch(viable_occupant.stat)
if(CONSCIOUS)
@@ -528,7 +528,7 @@
var/mob/living/carbon/viable_occupant = null
if(connected)
viable_occupant = connected.occupant
if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.has_disability(NOCLONE)))
if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.has_disability(DISABILITY_NOCLONE)))
viable_occupant = null
return viable_occupant
+1 -1
View File
@@ -100,7 +100,7 @@
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
if(istype(mob_occupant))
if(locate_computer(/obj/machinery/computer/cloning))
if(!mob_occupant.suiciding && !(mob_occupant.has_disability(NOCLONE)) && !mob_occupant.hellbound)
if(!mob_occupant.suiciding && !(mob_occupant.has_disability(DISABILITY_NOCLONE)) && !mob_occupant.hellbound)
mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
// DNA manipulators cannot operate on severed heads or brains
+5 -2
View File
@@ -251,13 +251,16 @@
note = null
update_icon()
/obj/machinery/door/airlock/proc/unzap() //for addtimer
justzap = FALSE
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
if(isElectrified())
if(!justzap)
if(shock(user, 100))
justzap = TRUE
addtimer(VARSET_CALLBACK(src, justzap, FALSE) , 10)
addtimer(CALLBACK(src, .proc/unzap), 10)
return
else
return
@@ -677,7 +680,7 @@
if(ishuman(user) && prob(40) && src.density)
var/mob/living/carbon/human/H = user
if((H.disabilities & DUMB) && Adjacent(user))
if((H.has_disability(DISABILITY_DUMB)) && Adjacent(user))
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
if(!istype(H.head, /obj/item/clothing/head/helmet))
H.visible_message("<span class='danger'>[user] headbutts the airlock.</span>", \
+1 -1
View File
@@ -195,7 +195,7 @@
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open)
if(prob(severity*10 - 20))
if(prob(40/severity))
if(secondsElectrified == 0)
secondsElectrified = -1
shockedby += "\[[time_stamp()]\]EM Pulse"
+63 -61
View File
@@ -1,66 +1,68 @@
/obj/machinery/door/poddoor
name = "blast door"
desc = "A heavy duty blast door that opens mechanically."
icon = 'icons/obj/doors/blastdoor.dmi'
icon_state = "closed"
var/id = 1
/obj/machinery/door/poddoor
name = "blast door"
desc = "A heavy duty blast door that opens mechanically."
icon = 'icons/obj/doors/blastdoor.dmi'
icon_state = "closed"
var/id = 1
sub_door = TRUE
explosion_block = 3
explosion_block = 3
heat_proof = TRUE
safe = FALSE
max_integrity = 600
armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70)
resistance_flags = FIRE_PROOF
damage_deflection = 70
/obj/machinery/door/poddoor/preopen
icon_state = "open"
max_integrity = 600
armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70)
resistance_flags = FIRE_PROOF
damage_deflection = 70
/obj/machinery/door/poddoor/preopen
icon_state = "open"
density = FALSE
opacity = 0
/obj/machinery/door/poddoor/ert
desc = "A heavy duty blast door that only opens for dire emergencies."
//special poddoors that open when emergency shuttle docks at centcom
/obj/machinery/door/poddoor/shuttledock
var/checkdir = 4 //door won't open if turf in this dir is `turftype`
var/turftype = /turf/open/space
/obj/machinery/door/poddoor/shuttledock/proc/check()
var/turf/T = get_step(src, checkdir)
if(!istype(T, turftype))
INVOKE_ASYNC(src, .proc/open)
else
INVOKE_ASYNC(src, .proc/close)
opacity = 0
/obj/machinery/door/poddoor/ert
desc = "A heavy duty blast door that only opens for dire emergencies."
//special poddoors that open when emergency shuttle docks at centcom
/obj/machinery/door/poddoor/shuttledock
var/checkdir = 4 //door won't open if turf in this dir is `turftype`
var/turftype = /turf/open/space
/obj/machinery/door/poddoor/shuttledock/proc/check()
var/turf/T = get_step(src, checkdir)
if(!istype(T, turftype))
INVOKE_ASYNC(src, .proc/open)
else
INVOKE_ASYNC(src, .proc/close)
/obj/machinery/door/poddoor/CollidedWith(atom/movable/AM)
if(density)
return 0
else
return ..()
//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS.
/obj/machinery/door/poddoor/ex_act(severity, target)
if(severity == 3)
return
..()
/obj/machinery/door/poddoor/do_animate(animation)
switch(animation)
if("opening")
flick("opening", src)
if("closing")
flick("closing", src)
/obj/machinery/door/poddoor/update_icon()
if(density)
icon_state = "closed"
else
icon_state = "open"
/obj/machinery/door/poddoor/try_to_activate_door(mob/user)
return
/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user)
if(stat & NOPOWER)
open(1)
if(density)
return 0
else
return ..()
//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS.
/obj/machinery/door/poddoor/ex_act(severity, target)
if(severity == 3)
return
..()
/obj/machinery/door/poddoor/do_animate(animation)
switch(animation)
if("opening")
flick("opening", src)
playsound(src, 'sound/machines/blastdoor.ogg', 30, 1)
if("closing")
flick("closing", src)
playsound(src, 'sound/machines/blastdoor.ogg', 30, 1)
/obj/machinery/door/poddoor/update_icon()
if(density)
icon_state = "closed"
else
icon_state = "open"
/obj/machinery/door/poddoor/try_to_activate_door(mob/user)
return
/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user)
if(stat & NOPOWER)
open(1)
+1 -10
View File
@@ -22,7 +22,6 @@ GLOBAL_LIST_EMPTY(allCasters)
var/creationTime
var/authorCensor
var/bodyCensor
var/photo_file
/datum/newscaster/feed_message/proc/returnAuthor(censor)
if(censor == -1)
@@ -98,7 +97,6 @@ GLOBAL_LIST_EMPTY(allCasters)
var/scannedUser
var/isAdminMsg
var/icon/img
var/photo_file
/datum/newscaster/feed_network
var/list/datum/newscaster/feed_channel/network_channels = list()
@@ -128,7 +126,6 @@ GLOBAL_LIST_EMPTY(allCasters)
if(photo)
newMsg.img = photo.img
newMsg.caption = photo.scribble
newMsg.photo_file = save_photo(photo.img)
for(var/datum/newscaster/feed_channel/FC in network_channels)
if(FC.channel_name == channel_name)
FC.messages += newMsg
@@ -146,7 +143,6 @@ GLOBAL_LIST_EMPTY(allCasters)
wanted_issue.isAdminMsg = adminMsg
if(photo)
wanted_issue.img = photo.img
wanted_issue.photo_file = save_photo(photo.img)
if(newMessage)
for(var/obj/machinery/newscaster/N in GLOB.allCasters)
N.newsAlert()
@@ -161,12 +157,7 @@ GLOBAL_LIST_EMPTY(allCasters)
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
NEWSCASTER.update_icon()
/datum/newscaster/feed_network/proc/save_photo(icon/photo)
var/photo_file = copytext(md5("\icon[photo]"), 1, 6)
if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
var/icon/p = icon(photo, frame = 1)
fcopy(p, "[GLOB.log_directory]/photos/[photo_file].png")
return photo_file
/obj/item/wallframe/newscaster
name = "newscaster frame"
+181 -97
View File
@@ -25,8 +25,8 @@
integrity_failure = 100
armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70)
circuit = /obj/item/circuitboard/machine/vendor
var/active = TRUE //No sales pitches if off!
var/vend_ready = TRUE //Are we ready to vend?? Is it time??
var/active = 1 //No sales pitches if off!
var/vend_ready = 1 //Are we ready to vend?? Is it time??
// To be filled out at compile time
var/list/products = list() //For each, use the following pattern:
@@ -227,15 +227,15 @@
if(!allowed(user) && !emagged && scan_id)
to_chat(user, "<span class='warning'>[src]'s chef compartment blinks red: Access denied.</span>")
req_access_txt = "0"
return FALSE
return 0
req_access_txt = "0"
return TRUE
return 1
/obj/machinery/vending/snack/proc/iscompartmentfull(mob/user)
if(contents.len >= 30) // no more than 30 dishes can fit inside
to_chat(user, "<span class='warning'>[src]'s chef compartment is full.</span>")
return TRUE
return FALSE
return 1
return 0
/obj/machinery/vending/snack/proc/food_load(obj/item/reagent_containers/food/snacks/S)
if(dish_quants[S.name])
@@ -350,6 +350,180 @@
/obj/machinery/vending/attack_ai(mob/user)
return attack_hand(user)
/obj/machinery/vending/attack_hand(mob/user)
var/dat = ""
if(panel_open && !isAI(user))
return wires.interact(user)
else
if(stat & (BROKEN|NOPOWER))
return
dat += "<h3>Select an item</h3>"
dat += "<div class='statusDisplay'>"
if(product_records.len == 0)
dat += "<font color = 'red'>No product loaded!</font>"
else
var/list/display_records = product_records
if(extended_inventory)
display_records = product_records + hidden_records
if(coin || bill)
display_records = product_records + coin_records
if((coin || bill) && extended_inventory)
display_records = product_records + hidden_records + coin_records
dat += "<ul>"
for (var/datum/data/vending_product/R in display_records)
dat += "<li>"
if(R.amount > 0)
dat += "<a href='byond://?src=[REF(src)];vend=[REF(R)]'>Vend</a> "
else
dat += "<span class='linkOff'>Sold out</span> "
dat += "<font color = '[R.display_color]'><b>[sanitize(R.product_name)]</b>:</font>"
dat += " <b>[R.amount]</b>"
dat += "</li>"
dat += "</ul>"
dat += "</div>"
if(premium.len > 0)
dat += "<b>Change Return:</b> "
if (coin || bill)
dat += "[(coin ? coin : "")][(bill ? bill : "")]&nbsp;&nbsp;<a href='byond://?src=[REF(src)];remove_coin=1'>Remove</a>"
else
dat += "<i>No money</i>&nbsp;&nbsp;<span class='linkOff'>Remove</span>"
if(istype(src, /obj/machinery/vending/snack))
dat += "<h3>Chef's Food Selection</h3>"
dat += "<div class='statusDisplay'>"
for (var/O in dish_quants)
if(dish_quants[O] > 0)
var/N = dish_quants[O]
dat += "<a href='byond://?src=[REF(src)];dispense=[sanitize(O)]'>Dispense</A> "
dat += "<B>[capitalize(O)]: [N]</B><br>"
dat += "</div>"
user.set_machine(src)
if(seconds_electrified && !(stat & NOPOWER))
if(shock(user, 100))
return
var/datum/browser/popup = new(user, "vending", (name))
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/vending/Topic(href, href_list)
if(..())
return
if(href_list["remove_coin"])
if(!(coin || bill))
to_chat(usr, "<span class='notice'>There is no money in this machine.</span>")
return
if(coin)
if(!usr.get_active_held_item())
usr.put_in_hands(coin)
else
coin.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
if(bill)
if(!usr.get_active_held_item())
usr.put_in_hands(bill)
else
bill.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [bill] from [src].</span>")
bill = null
usr.set_machine(src)
if((href_list["dispense"]) && (vend_ready))
var/N = href_list["dispense"]
if(dish_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
return
vend_ready = 0
use_power(5)
dish_quants[N] = max(dish_quants[N] - 1, 0)
for(var/obj/O in contents)
if(O.name == N)
O.forceMove(drop_location())
break
vend_ready = 1
updateUsrDialog()
return
if((href_list["vend"]) && (vend_ready))
if(panel_open)
to_chat(usr, "<span class='notice'>The vending machine cannot dispense products while its service panel is open!</span>")
return
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
to_chat(usr, "<span class='warning'>Access denied.</span>" )
flick(icon_deny,src)
return
vend_ready = 0 //One thing at a time!!
var/datum/data/vending_product/R = locate(href_list["vend"])
if(!R || !istype(R) || !R.product_path)
vend_ready = 1
return
if(R in hidden_records)
if(!extended_inventory)
vend_ready = 1
return
else if(R in coin_records)
if(!(coin || bill))
to_chat(usr, "<span class='warning'>You need to insert money to get this item!</span>")
vend_ready = 1
return
if(coin && coin.string_attached)
if(prob(50))
if(usr.put_in_hands(coin))
to_chat(usr, "<span class='notice'>You successfully pull [coin] out before [src] could swallow it.</span>")
coin = null
else
to_chat(usr, "<span class='warning'>You couldn't pull [coin] out because your hands are full!</span>")
QDEL_NULL(coin)
else
to_chat(usr, "<span class='warning'>You weren't able to pull [coin] out fast enough, the machine ate it, string and all!</span>")
QDEL_NULL(coin)
else
QDEL_NULL(coin)
QDEL_NULL(bill)
else if (!(R in product_records))
vend_ready = 1
message_admins("Vending machine exploit attempted by [key_name(usr, usr.client)]!")
return
if (R.amount <= 0)
to_chat(usr, "<span class='warning'>Sold out.</span>")
vend_ready = 1
return
else
R.amount--
if(((last_reply + 200) <= world.time) && vend_reply)
speak(vend_reply)
last_reply = world.time
use_power(5)
if(icon_vend) //Show the vending animation if needed
flick(icon_vend,src)
new R.product_path(get_turf(src))
SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]"))
vend_ready = 1
return
updateUsrDialog()
return
else if(href_list["togglevoice"] && panel_open)
shut_up = !shut_up
updateUsrDialog()
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
return
@@ -431,96 +605,6 @@
else
return FALSE
/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "vending", name, 350, 475, master_ui, state)
ui.open()
/obj/machinery/vending/ui_data()
var/list/data = list()
var/list/listed_products = list()
var/list/display_records = product_records
if(extended_inventory)
display_records += hidden_records
if(coin)
display_records += coin_records
for(var/key = 1 to display_records.len)
var/datum/data/vending_product/I = display_records[key]
listed_products.Add(list(list(
"key" = key,
"name" = I.product_name,
"color" = I.display_color,
"amount" = I.amount)))
data["products"] = listed_products
if(!isnull(coin))
data["coin"] = coin.name
data["coinslot"] = premium.len
data["canvend"] = vend_ready
return data
/obj/machinery/vending/ui_act(action, params)
if(..())
return
if(!vend_ready)
return
switch(action)
if("vend")
if(!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
to_chat(usr, "<span class='warning'>Access denied.</span>")
flick(icon_deny,src)
return
vend_ready = FALSE
addtimer(VARSET_CALLBACK(src, vend_ready, TRUE), 10)
var/key = text2num(params["key"])
var/datum/data/vending_product/R = product_records[key]
if(R in hidden_records)
if(!extended_inventory)
return
else if(R in coin_records)
if(!coin)
to_chat(usr, "<span class='warning'>You need to insert a coin to get this item!</span>")
return
if(coin.string_attached)
if(prob(50))
if(usr.put_in_hands(coin))
to_chat(usr, "<span class='notice'>You successfully pull [coin] out before [src] could swallow it.</span>")
coin = null
else
to_chat(usr, "<span class='warning'>You couldn't pull [coin] out because your hands are full!</span>")
QDEL_NULL(coin)
else
to_chat(usr, "<span class='warning'>You weren't able to pull [coin] out fast enough, the machine ate it, string and all!</span>")
QDEL_NULL(coin)
else
QDEL_NULL(coin)
else if (!(R in product_records))
return
if (R.amount <= 0)
to_chat(usr, "<span class='warning'>Sold out.</span>")
return
R.amount--
if(((last_reply + 200) <= world.time) && vend_reply)
speak(vend_reply)
last_reply = world.time
use_power(5)
if(icon_vend) //Show the vending animation if needed
flick(icon_vend,src)
new R.product_path(drop_location())
return TRUE
if("eject")
if(!coin)
to_chat(usr, "<span class='notice'>There is no coin in this machine.</span>")
return
usr.put_in_hands(coin)
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
/*
* Vending machine types
*/
@@ -1111,4 +1195,4 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
#undef COIN_CHARGE
#undef COIN_CHARGE
+55 -88
View File
@@ -16,7 +16,7 @@
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/landmarks.dmi'
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
anchored = TRUE
var/jobspawn_override = FALSE
@@ -40,9 +40,9 @@
// START LANDMARKS FOLLOW. Don't change the names unless
// you are refactoring shitty landmark code.
/obj/effect/landmark/start/assistant
name = "Assistant"
icon_state = "Assistant"
/obj/effect/landmark/start/assistant/override
jobspawn_override = TRUE
@@ -50,135 +50,102 @@
/obj/effect/landmark/start/janitor
name = "Janitor"
icon_state = "Janitor"
/obj/effect/landmark/start/cargo_technician
name = "Cargo Technician"
icon_state = "Cargo Technician"
/obj/effect/landmark/start/bartender
name = "Bartender"
icon_state = "Bartender"
/obj/effect/landmark/start/clown
name = "Clown"
icon_state = "Clown"
/obj/effect/landmark/start/mime
name = "Mime"
icon_state = "Mime"
/obj/effect/landmark/start/quartermaster
name = "Quartermaster"
icon_state = "Quartermaster"
/obj/effect/landmark/start/atmospheric_technician
name = "Atmospheric Technician"
icon_state = "Atmospheric Technician"
/obj/effect/landmark/start/cook
name = "Cook"
icon_state = "Cook"
/obj/effect/landmark/start/shaft_miner
name = "Shaft Miner"
icon_state = "Shaft Miner"
/obj/effect/landmark/start/security_officer
name = "Security Officer"
icon_state = "Security Officer"
/obj/effect/landmark/start/botanist
name = "Botanist"
icon_state = "Botanist"
/obj/effect/landmark/start/head_of_security
name = "Head of Security"
icon_state = "Head of Security"
/obj/effect/landmark/start/captain
name = "Captain"
icon_state = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
icon_state = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
icon_state = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
icon_state = "Chief Engineer"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
icon_state = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
icon_state = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
icon_state = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
icon_state = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
icon_state = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
icon_state = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
icon_state = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
icon_state = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
icon_state = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
icon_state = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
icon_state = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
icon_state = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
icon_state = "Chaplain"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
icon_state = "Cyborg"
/obj/effect/landmark/start/ai
name = "AI"
icon_state = "AI"
delete_after_roundstart = FALSE
/obj/effect/landmark/start/captain
name = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
//Department Security spawns
/obj/effect/landmark/start/depsec
name = "department_sec"
icon_state = "Security Officer"
/obj/effect/landmark/start/depsec/New()
..()
@@ -1,70 +1,70 @@
/proc/generate_projectile_beam_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
if(!istype(starting) || !istype(ending) || !ispath(beam_type))
return
var/datum/point/midpoint = point_midpoint_points(starting, ending)
var/obj/effect/projectile_beam/PB = new beam_type
PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0)
. = PB
if(qdel_in)
QDEL_IN(PB, qdel_in)
/obj/effect/projectile_beam
icon = 'icons/obj/projectiles.dmi'
layer = ABOVE_MOB_LAYER
anchored = TRUE
light_power = 1
light_range = 2
light_color = "#00ffff"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
flags_1 = ABSTRACT_1
appearance_flags = 0
/obj/effect/projectile_beam/singularity_pull()
return
/obj/effect/projectile_beam/singularity_act()
return
/obj/effect/projectile_beam/proc/scale_to(nx,ny,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Scale(nx,ny)
transform = M
/obj/effect/projectile_beam/proc/turn_to(angle,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Turn(angle)
transform = M
/obj/effect/projectile_beam/New(angle_override, p_x, p_y, color_override, scaling = 1)
if(angle_override && p_x && p_y && color_override && scaling)
apply_vars(angle_override, p_x, p_y, color_override, scaling)
return ..()
/obj/effect/projectile_beam/proc/apply_vars(angle_override, p_x = 0, p_y = 0, color_override, scaling = 1, new_loc, increment = 0)
var/mutable_appearance/look = new(src)
look.pixel_x = p_x
look.pixel_y = p_y
if(color_override)
look.color = color_override
appearance = look
scale_to(1,scaling, FALSE)
turn_to(angle_override, FALSE)
if(!isnull(new_loc)) //If you want to null it just delete it...
forceMove(new_loc)
for(var/i in 1 to increment)
pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1)
pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
/obj/effect/projectile_beam/tracer
icon_state = "tracer_beam"
/obj/effect/projectile_beam/tracer/aiming
icon_state = "gbeam"
/proc/generate_projectile_beam_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
if(!istype(starting) || !istype(ending) || !ispath(beam_type))
return
var/datum/point/midpoint = point_midpoint_points(starting, ending)
var/obj/effect/projectile_beam/PB = new beam_type
PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0)
. = PB
if(qdel_in)
QDEL_IN(PB, qdel_in)
/obj/effect/projectile_beam
icon = 'icons/obj/projectiles.dmi'
layer = ABOVE_MOB_LAYER
anchored = TRUE
light_power = 1
light_range = 2
light_color = "#00ffff"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
flags_1 = ABSTRACT_1
appearance_flags = 0
/obj/effect/projectile_beam/singularity_pull()
return
/obj/effect/projectile_beam/singularity_act()
return
/obj/effect/projectile_beam/proc/scale_to(nx,ny,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Scale(nx,ny)
transform = M
/obj/effect/projectile_beam/proc/turn_to(angle,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Turn(angle)
transform = M
/obj/effect/projectile_beam/New(angle_override, p_x, p_y, color_override, scaling = 1)
if(angle_override && p_x && p_y && color_override && scaling)
apply_vars(angle_override, p_x, p_y, color_override, scaling)
return ..()
/obj/effect/projectile_beam/proc/apply_vars(angle_override, p_x = 0, p_y = 0, color_override, scaling = 1, new_loc, increment = 0)
var/mutable_appearance/look = new(src)
look.pixel_x = p_x
look.pixel_y = p_y
if(color_override)
look.color = color_override
appearance = look
scale_to(1,scaling, FALSE)
turn_to(angle_override, FALSE)
if(!isnull(new_loc)) //If you want to null it just delete it...
forceMove(new_loc)
for(var/i in 1 to increment)
pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1)
pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
/obj/effect/projectile_beam/tracer
icon_state = "tracer_beam"
/obj/effect/projectile_beam/tracer/aiming
icon_state = "gbeam"
+3 -3
View File
@@ -539,7 +539,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "<span class='danger'>Your eyes start to bleed profusely!</span>")
if(!(M.has_disability(BLIND) || M.has_disability(NEARSIGHT)))
if(!(M.has_disability(DISABILITY_BLIND) || M.has_disability(DISABILITY_NEARSIGHT)))
to_chat(M, "<span class='danger'>You become nearsighted!</span>")
M.become_nearsighted(EYE_DAMAGE)
if(prob(50))
@@ -550,8 +550,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.Unconscious(20)
M.Knockdown(40)
if (prob(eyes.eye_damage - 10 + 1))
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
if(M.become_blind())
to_chat(M, "<span class='danger'>You go blind!</span>")
/obj/item/singularity_pull(S, current_size)
..()
+6
View File
@@ -8,6 +8,7 @@
var/colour = "red"
var/open = FALSE
/obj/item/lipstick/purple
name = "purple lipstick"
colour = "purple"
@@ -21,6 +22,7 @@
name = "black lipstick"
colour = "black"
/obj/item/lipstick/random
name = "lipstick"
icon_state = "random_lipstick"
@@ -31,6 +33,8 @@
colour = pick("red","purple","lime","black","green","blue","white")
name = "[colour] lipstick"
/obj/item/lipstick/attack_self(mob/user)
cut_overlays()
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
@@ -99,6 +103,7 @@
else
..()
/obj/item/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
@@ -107,6 +112,7 @@
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
/obj/item/razor/proc/shave(mob/living/carbon/human/H, location = "mouth")
if(location == "mouth")
H.facial_hair_style = "Shaved"
+2 -2
View File
@@ -393,7 +393,7 @@
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/human/H)
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
return (!H.suiciding && !(H.has_disability(NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
return (!H.suiciding && !(H.has_disability(DISABILITY_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(isliving(H.pulledby)) //CLEAR!
@@ -514,7 +514,7 @@
shock_touching(30, H)
var/failed
if (H.suiciding || (H.has_disability(NOCLONE)))
if (H.suiciding || (H.has_disability(DISABILITY_NOCLONE)))
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
else if (H.hellbound)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile.</span>"
@@ -48,7 +48,7 @@
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
if((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50)) //too dumb to use flashlight properly
if((user.has_disability(DISABILITY_CLUMSY) || user.has_disability(DISABILITY_DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
@@ -82,7 +82,7 @@
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
if(M.stat == DEAD || (M.has_disability(BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
if(M.stat == DEAD || (M.has_disability(DISABILITY_BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
to_chat(user, "<span class='warning'>[M]'s pupils don't react to the light!</span>")
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision
to_chat(user, "<span class='danger'>[M]'s pupils give an eerie glow!</span>")
+5 -5
View File
@@ -85,7 +85,7 @@ GAS ANALYZER
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
if ((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50))
if ((user.has_disability(DISABILITY_CLUMSY) || user.has_disability(DISABILITY_DUMB)) && prob(50))
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b>")
@@ -181,10 +181,10 @@ GAS ANALYZER
to_chat(user, "\t<span class='info'><b>==EAR STATUS==</b></span>")
if(istype(ears))
var/healthy = TRUE
if(C.has_disability(DEAF, GENETIC_MUTATION))
if(C.has_disability(DISABILITY_DEAF, GENETIC_MUTATION))
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is genetically deaf.</span>")
else if(C.has_disability(DEAF))
else if(C.has_disability(DISABILITY_DEAF))
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is deaf.</span>")
else
@@ -202,10 +202,10 @@ GAS ANALYZER
to_chat(user, "\t<span class='info'><b>==EYE STATUS==</b></span>")
if(istype(eyes))
var/healthy = TRUE
if(C.has_disability(BLIND))
if(C.has_disability(DISABILITY_BLIND))
to_chat(user, "\t<span class='alert'>Subject is blind.</span>")
healthy = FALSE
if(C.has_disability(NEARSIGHT))
if(C.has_disability(DISABILITY_NEARSIGHT))
to_chat(user, "\t<span class='alert'>Subject is nearsighted.</span>")
healthy = FALSE
if(eyes.eye_damage > 30)
+2 -2
View File
@@ -31,7 +31,7 @@
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.has_disability(NOCLONE)))
if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.has_disability(DISABILITY_NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
@@ -313,7 +313,7 @@
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
if(M.has_dna() && !(M.has_disability(NOCLONE)))
if(M.has_dna() && !(M.has_disability(DISABILITY_NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
+1 -1
View File
@@ -24,7 +24,7 @@
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
+2 -15
View File
@@ -1,19 +1,6 @@
/obj/item/restraints
breakouttime = 600
/obj/item/restraints/Destroy()
if(iscarbon(loc))
var/mob/living/carbon/M = loc
if(M.handcuffed == src)
M.handcuffed = null
M.update_handcuffed()
if(M.buckled && M.buckled.buckle_requires_restraints)
M.buckled.unbuckle_mob(M)
if(M.legcuffed == src)
M.legcuffed = null
M.update_inv_legcuffed()
return ..()
//Handcuffs
/obj/item/restraints/handcuffs
@@ -39,7 +26,7 @@
/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user)
if(!istype(C))
return
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user,user)
return
@@ -392,4 +379,4 @@
B.Crossed(hit_atom)
qdel(src)
..()
+2 -2
View File
@@ -44,7 +44,7 @@
forkload = null
else if(user.zone_selected == "eyes")
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
@@ -70,7 +70,7 @@
/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
if(user.zone_selected == "eyes")
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
+1 -1
View File
@@ -99,7 +99,7 @@
return ..()
add_fingerprint(user)
if((user.has_disability(CLUMSY)) && prob(50))
if((user.has_disability(DISABILITY_CLUMSY)) && prob(50))
to_chat(user, "<span class ='danger'>You club yourself over the head.</span>")
user.Knockdown(60 * force)
if(ishuman(user))
@@ -72,6 +72,6 @@
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
user.take_bodypart_damage(5,5)
+6 -14
View File
@@ -125,14 +125,14 @@
loadedWeightClass += I.w_class
return TRUE
/obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/user, flag, params)
/obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/carbon/human/user, flag, params)
if(flag && user.a_intent == INTENT_HARM) //melee attack
return
if(!istype(user))
return
Fire(user, target)
/obj/item/pneumatic_cannon/proc/Fire(mob/living/user, var/atom/target)
/obj/item/pneumatic_cannon/proc/Fire(mob/living/carbon/human/user, var/atom/target)
if(!istype(user) && !target)
return
var/discharge = 0
@@ -147,7 +147,7 @@
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
return
if(user.has_disability(CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
if(user.has_disability(DISABILITY_CLUMSY) && prob(75) && clumsyCheck && iscarbon(user))
var/mob/living/carbon/C = user
C.visible_message("<span class='warning'>[C] loses their grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
C.dropItemToGround(src, TRUE)
@@ -164,10 +164,9 @@
var/turf/T = get_target(target, get_turf(src))
playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
fire_items(T, user)
if(pressureSetting >= 3 && iscarbon(user))
var/mob/living/carbon/C = user
C.visible_message("<span class='warning'>[C] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
C.Knockdown(60)
if(pressureSetting >= 3 && user)
user.visible_message("<span class='warning'>[user] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
user.Knockdown(60)
/obj/item/pneumatic_cannon/proc/fire_items(turf/target, mob/user)
if(fire_mode == PCANNON_FIREALL)
@@ -273,10 +272,3 @@
selfcharge = TRUE
charge_type = /obj/item/reagent_containers/food/snacks/pie/cream
maxWeightClass = 60 //20 pies.
/obj/item/pneumatic_cannon/pie/selfcharge/cyborg
name = "low velocity pie cannon"
automatic = FALSE
charge_type = /obj/item/reagent_containers/food/snacks/pie/cream/nostun
maxWeightClass = 6 //2 pies
charge_ticks = 2 //4 second/pie
@@ -355,9 +355,6 @@
var/hitdamage = 0
var/emaggedhitdamage = 3
/obj/item/borg/lollipop/clown
emaggedhitdamage = 0
/obj/item/borg/lollipop/equipped()
check_amount()
+142 -142
View File
@@ -1,142 +1,142 @@
/obj/item/shield
name = "shield"
block_chance = 50
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "riot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = SLOT_BACK
force = 10
throwforce = 5
throw_speed = 2
throw_range = 3
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
if(cooldown < world.time - 25)
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else
return ..()
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
return ..()
/obj/item/shield/riot/roman
name = "roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
icon_state = "roman_shield"
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
/obj/item/shield/riot/buckler
name = "wooden buckler"
desc = "A medieval wooden buckler."
icon_state = "buckler"
item_state = "buckler"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "eshield0" // eshield1 for expanded
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
force = 3
throwforce = 3
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
var/active = 0
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/shield/energy/IsReflect()
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "eshield[active]"
if(active)
force = 10
throwforce = 8
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "teleriot0"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = null
force = 3
throwforce = 3
throw_speed = 3
throw_range = 4
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
if(active)
force = 8
throwforce = 5
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
to_chat(user, "<span class='notice'>You extend \the [src].</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_NORMAL
slot_flags = null
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield
name = "shield"
block_chance = 50
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "riot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = SLOT_BACK
force = 10
throwforce = 5
throw_speed = 2
throw_range = 3
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
if(cooldown < world.time - 25)
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else
return ..()
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
return ..()
/obj/item/shield/riot/roman
name = "roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
icon_state = "roman_shield"
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
/obj/item/shield/riot/buckler
name = "wooden buckler"
desc = "A medieval wooden buckler."
icon_state = "buckler"
item_state = "buckler"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "eshield0" // eshield1 for expanded
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
force = 3
throwforce = 3
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
var/active = 0
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/shield/energy/IsReflect()
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "eshield[active]"
if(active)
force = 10
throwforce = 8
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "teleriot0"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = null
force = 3
throwforce = 3
throw_speed = 3
throw_range = 4
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
if(active)
force = 8
throwforce = 5
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
to_chat(user, "<span class='notice'>You extend \the [src].</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_NORMAL
slot_flags = null
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
+5 -15
View File
@@ -10,23 +10,13 @@
var/label = ""
var/last_wave = 0
/obj/item/picket_sign/cyborg
name = "metallic nano-sign"
desc = "A high tech picket sign used by silicons that can reprogram its surface at will. Probably hurts to get hit by, too."
force = 13
resistance_flags = NONE
actions_types = list(/datum/action/item_action/nano_picket_sign)
/obj/item/picket_sign/proc/retext(mob/user)
var/txt = stripped_input(user, "What would you like to write on the sign?", "Sign Label", null , 30)
if(txt && Adjacent(user))
label = txt
name = "[label] sign"
desc = "It reads: [label]"
/obj/item/picket_sign/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen) || istype(W, /obj/item/toy/crayon))
retext(user)
var/txt = stripped_input(user, "What would you like to write on the sign?", "Sign Label", null , 30)
if(txt)
label = txt
src.name = "[label] sign"
desc = "It reads: [label]"
else
return ..()
+3 -3
View File
@@ -109,7 +109,7 @@
if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
recipe_list = srl.recipes
var/t1 = "Amount Left: [get_amount()]<br>"
var/t1 = "Amount Left: [amount]<br>"
for(var/i in 1 to length(recipe_list))
var/E = recipe_list[i]
if (isnull(E))
@@ -161,8 +161,8 @@
if (href_list["sublist"] && !href_list["make"])
interact(usr, text2num(href_list["sublist"]))
if (href_list["make"])
if (get_amount() < 1 && !is_cyborg)
qdel(src)
if (get_amount() < 1)
qdel(src) //Never should happen
var/list/recipes_list = recipes
if (href_list["sublist"])
+1 -2
View File
@@ -93,8 +93,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if (user.has_disability(CLUMSY) && prob(50))
if (user.has_disability(DISABILITY_CLUMSY) && prob(50))
to_chat(user, "<span class='danger'>[src] slips out of your hand and hits your head.</span>")
user.take_bodypart_damage(10)
user.Unconscious(400)
+1 -1
View File
@@ -108,7 +108,7 @@
add_fingerprint(user)
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
if(status && user.has_disability(CLUMSY) && prob(50))
if(status && user.has_disability(DISABILITY_CLUMSY) && prob(50))
user.visible_message("<span class='danger'>[user] accidentally hits themself with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
user.Knockdown(stunforce*3)
+1 -1
View File
@@ -8,7 +8,7 @@
/obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
..()
if(status && user.has_disability(CLUMSY) && prob(50))
if(status && user.has_disability(DISABILITY_CLUMSY) && prob(50))
user.visible_message("<span class='danger'>[user] accidentally hits themself with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
if(do_teleport(user, get_turf(user), 50))//honk honk
+1 -1
View File
@@ -75,7 +75,7 @@
return ..()
if(user.zone_selected != "eyes" && user.zone_selected != "head")
return ..()
if(user.has_disability(CLUMSY) && prob(50))
if(user.has_disability(DISABILITY_CLUMSY) && prob(50))
M = user
return eyestab(M,user)
+8 -15
View File
@@ -14,8 +14,7 @@
materials = list(MAT_METAL=80)
attack_verb = list("pinched", "nipped")
hitsound = 'sound/items/wirecutter.ogg'
usesound = 'sound/items/wirecutter.ogg'
usesound = 'sound/items/wirecutter.ogg'
tool_behaviour = TOOL_WIRECUTTER
toolspeed = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
@@ -33,6 +32,10 @@
if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable))
user.visible_message("<span class='notice'>[user] cuts [C]'s restraints with [src]!</span>")
qdel(C.handcuffed)
C.handcuffed = null
if(C.buckled && C.buckled.buckle_requires_restraints)
C.buckled.unbuckle_mob(C)
C.update_handcuffed()
return
else
..()
@@ -55,8 +58,7 @@
desc = "Extremely sharp wirecutters, made out of a silvery-green metal."
icon = 'icons/obj/abductor.dmi'
icon_state = "cutters"
toolspeed = 0.1
toolspeed = 0.1
random_color = FALSE
/obj/item/wirecutters/cyborg
@@ -68,8 +70,7 @@
name = "jaws of life"
desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head."
icon_state = "jaws_cutter"
item_state = "jawsoflife"
item_state = "jawsoflife"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
usesound = 'sound/items/jaws_cut.ogg'
toolspeed = 0.25
@@ -91,12 +92,4 @@
var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power
to_chat(user, "<span class='notice'>You attach the pry jaws to [src].</span>")
qdel(src)
user.put_in_active_hand(pryjaws)
/obj/item/wirecutters/power/attack(mob/living/carbon/C, mob/user)
if(istype(C) && C.handcuffed)
user.visible_message("<span class='notice'>[user] cuts [C]'s restraints with [src]!</span>")
qdel(C.handcuffed)
return
else
..()
user.put_in_active_hand(pryjaws)
+1 -1
View File
@@ -302,7 +302,7 @@
unwield()
return
..()
if(user.has_disability(CLUMSY) && (wielded) && prob(40))
if(user.has_disability(DISABILITY_CLUMSY) && (wielded) && prob(40))
impale(user)
return
if((wielded) && prob(50))
+30 -23
View File
@@ -10,65 +10,72 @@
density = TRUE
pixel_x = -16
layer = FLY_LAYER
var/cut = FALSE
var/log_amount = 10
/obj/structure/flora/tree/attackby(obj/item/W, mob/user, params)
if(!cut && log_amount && (!(flags_1 & NODECONSTRUCT_1)))
if(log_amount && (!(flags_1 & NODECONSTRUCT_1)))
if(W.sharpness && W.force > 0)
if(W.hitsound)
playsound(get_turf(src), W.hitsound, 100, 0, 0)
user.visible_message("<span class='notice'>[user] begins to cut down [src] with [W].</span>","<span class='notice'>You begin to cut down [src] with [W].</span>", "You hear the sound of sawing.")
if(do_after(user, 1000/W.force, target = user)) //5 seconds with 20 force, 8 seconds with a hatchet, 20 seconds with a shard.
if(cut)
return
if(do_after(user, 1000/W.force, target = src)) //5 seconds with 20 force, 8 seconds with a hatchet, 20 seconds with a shard.
user.visible_message("<span class='notice'>[user] fells [src] with the [W].</span>","<span class='notice'>You fell [src] with the [W].</span>", "You hear the sound of a tree falling.")
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0)
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "tree_stump"
density = FALSE
pixel_x = -16
name += " stump"
cut = TRUE
for(var/i=1 to log_amount)
new /obj/item/grown/log/tree(get_turf(src))
var/obj/structure/flora/stump/S = new(loc)
S.name = "[name] stump"
qdel(src)
else
return ..()
/obj/structure/flora/stump
name = "stump"
desc = "This represents our promise to the crew, and the station itself, to cut down as many trees as possible." //running naked through the trees
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "tree_stump"
density = FALSE
pixel_x = -16
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
var/list/icon_states = list("pine_1", "pine_2", "pine_3")
/obj/structure/flora/tree/pine/Initialize()
icon_state = "pine_[rand(1, 3)]"
. = ..()
if(islist(icon_states && icon_states.len))
icon_state = pick(icon_states)
/obj/structure/flora/tree/pine/xmas
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
var/gifts_under_tree = FALSE
icon_states = null
/obj/structure/flora/tree/pine/xmas/presents
icon_state = "pinepresents"
desc = "A wondrous decorated Christmas tree. It has presents!"
var/gift_type = /obj/item/a_gift/anything
var/list/ckeys_that_took = list()
/obj/structure/flora/tree/pine/xmas/attack_hand(mob/living/user)
if(!gifts_under_tree)
return
/obj/structure/flora/tree/pine/xmas/presents/attack_hand(mob/living/user)
if(!user.ckey)
return
if(ckeys_that_took[user.ckey])
to_chat(user, "<span class='warning'>You already took your gift.</span>")
to_chat(user, "<span class='warning'>There are no presents with your name on.</span>")
return
to_chat(user, "<span class='warning'>After a bit of rummaging, you locate a gift with your name on it!</span>")
ckeys_that_took[user.ckey] = TRUE
var/obj/item/a_gift/anything/A = new
user.put_in_hands(A)
/obj/structure/flora/tree/pine/xmas/Initialize()
. = ..()
icon_state = "pine_c"
var/obj/item/G = new gift_type(src)
user.put_in_hands(G)
/obj/structure/flora/tree/dead
icon = 'icons/obj/flora/deadtrees.dmi'
@@ -17,7 +17,7 @@
L.buckled.unbuckle_mob(L,force=1)
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
L.forceMove(src)
L.add_disability(MUTE, STATUE_MUTE)
L.add_disability(DISABILITY_MUTE, STATUE_MUTE)
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
L.status_flags |= GODMODE
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
@@ -59,7 +59,7 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
petrified_mob.forceMove(loc)
petrified_mob.remove_disability(MUTE, STATUE_MUTE)
petrified_mob.remove_disability(DISABILITY_MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
petrified_mob.faction -= "mimic"
petrified_mob = null
+3 -3
View File
@@ -202,7 +202,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
return FALSE
P.setAngle(new_angle)
P.Angle = new_angle
return ..()
//DOUBLE
@@ -229,7 +229,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
new_angle += 180
P.setAngle(new_angle)
P.Angle = new_angle
return ..()
//BOX
@@ -251,7 +251,7 @@
anchored = TRUE
/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P)
P.setAngle(rotation_angle)
P.Angle = rotation_angle
return ..()
/obj/structure/reflector/ex_act()
+2 -3
View File
@@ -18,8 +18,7 @@
/turf/closed/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSCLOSEDTURF))
return TRUE
else
..()
return ..()
/turf/closed/indestructible
name = "wall"
@@ -165,4 +164,4 @@
name = "wall"
desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern."
icon = 'icons/turf/walls/hierophant_wall.dmi'
icon_state = "wall"
icon_state = "wall"
+1 -1
View File
@@ -88,7 +88,7 @@
/turf/open/indestructible/clock_spawn_room/proc/port_servants()
. = FALSE
for(var/mob/living/L in src)
if(is_servant_of_ratvar(L))
if(is_servant_of_ratvar(L) && L.stat != DEAD)
. = TRUE
L.forceMove(get_turf(pick(GLOB.servant_spawns)))
visible_message("<span class='warning'>[L] vanishes in a flash of red!</span>")
@@ -146,9 +146,6 @@
var/uses_overlay = TRUE
var/obj/effect/clockwork/overlay/floor/realappearence
/turf/open/floor/clockwork/Bless() //Who needs holy blessings when you have DADDY RATVAR?
return
/turf/open/floor/clockwork/Initialize()
. = ..()
if(uses_overlay)
@@ -70,10 +70,6 @@
if(realappearence)
qdel(realappearence)
realappearence = null
if(heated)
var/mob/camera/eminence/E = get_eminence()
if(E)
E.superheated_walls--
return ..()
/turf/closed/wall/clockwork/ReplaceWithLattice()
+1 -1
View File
@@ -61,7 +61,7 @@
new_angle_s -= 360
while(new_angle_s < -180)
new_angle_s += 360
P.setAngle(new_angle_s)
P.Angle = new_angle_s
return TRUE
/turf/closed/wall/proc/dismantle_wall(devastated=0, explode=0)

Some files were not shown because too many files have changed in this diff Show More