diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 03a684fc743..73258a2875c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -15,13 +15,11 @@ if (isarea(A)) return A -/proc/get_area(O) - if(isarea(O)) - return O - var/turf/loc = get_turf(O) - if(loc) - var/area/res = loc.loc - .= res +/proc/get_area(atom/A) + if(!istype(A)) + return + for(A, A && !isarea(A), A=A.loc); //semicolon is for the empty statement + return A /proc/get_area_name(N) //get area by its name for(var/area/A in world) diff --git a/code/controllers/Processes/timer.dm b/code/controllers/Processes/timer.dm new file mode 100644 index 00000000000..8cea3c60514 --- /dev/null +++ b/code/controllers/Processes/timer.dm @@ -0,0 +1,81 @@ +var/global/datum/controller/process/timer/PStimer + +/datum/controller/process/timer + var/list/processing_timers = list() + var/list/hashes = list() + +/datum/controller/process/timer/setup() + name = "timer" + schedule_interval = 5 //every 0.5 seconds + PStimer = src + +/datum/controller/process/timer/statProcess() + ..() + stat(null, "[processing_timers.len] timers") + +/datum/controller/process/timer/doWork() + if(!processing_timers.len) + disabled = 1 //nothing to do, lets stop firing. + return + for(last_object in processing_timers) + var/datum/timedevent/event = last_object + if(!event.thingToCall || qdeleted(event.thingToCall)) + qdel(event) + if(event.timeToRun <= world.time) + runevent(event) + qdel(event) + SCHECK + +/datum/controller/process/timer/proc/runevent(datum/timedevent/event) + set waitfor = 0 + call(event.thingToCall, event.procToCall)(arglist(event.argList)) + +/datum/timedevent + var/thingToCall + var/procToCall + var/timeToRun + var/argList + var/id + var/hash + var/static/nextid = 1 + +/datum/timedevent/New() + id = nextid + nextid++ + +/datum/timedevent/Destroy() + PStimer.processing_timers -= src + PStimer.hashes -= hash + return QDEL_HINT_IWILLGC + +/proc/addtimer(thingToCall, procToCall, wait, unique = FALSE, ...) + if(!PStimer) //can't run timers before the mc has been created + return + if(!thingToCall || !procToCall || wait <= 0) + return + if(PStimer.disabled) + PStimer.disabled = 0 + + var/datum/timedevent/event = new() + event.thingToCall = thingToCall + event.procToCall = procToCall + event.timeToRun = world.time + wait + event.hash = list2text(args) + if(args.len > 4) + event.argList = args.Copy(5) + + // Check for dupes if unique = 1. + if(unique) + if(event.hash in PStimer.hashes) + return + // If we are unique (or we're not checking that), add the timer and return the id. + PStimer.processing_timers += event + PStimer.hashes += event.hash + return event.id + +/proc/deltimer(id) + for(var/datum/timedevent/event in PStimer.processing_timers) + if(event.id == id) + qdel(event) + return 1 + return 0 \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index e65ced5c08c..208c41ffcf6 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -135,7 +135,7 @@ var/comms_password = "" var/use_irc_bot = 0 - var/irc_bot_host = "" + var/list/irc_bot_host = list() var/main_irc = "" var/admin_irc = "" var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix @@ -458,7 +458,7 @@ config.comms_password = value if("irc_bot_host") - config.irc_bot_host = value + config.irc_bot_host = text2list(value, ";") if("main_irc") config.main_irc = value diff --git a/code/datums/martial.dm b/code/datums/martial.dm index bfd5a3b6757..1d730315707 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -5,6 +5,8 @@ var/current_target = null var/temporary = 0 var/datum/martial_art/base = null // The permanent style + var/deflection_chance = 0 //Chance to deflect projectiles + var/help_verb = null /datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) return 0 @@ -25,29 +27,32 @@ return /datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) - add_logs(D, A, "punched") - A.do_attack_animation(D) - var/damage = rand(0,9) - var/atk_verb = "punch" + A.do_attack_animation(D) + var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) + var/datum/unarmed_attack/attack = A.species.unarmed + + var/atk_verb = "[pick(attack.attack_verb)]" if(D.lying) atk_verb = "kick" if(!damage) - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") return 0 var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") - playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - + playsound(D.loc, attack.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ "[A] has [atk_verb]ed [D]!") D.apply_damage(damage, BRUTE, affecting, armor_block) - if((D.stat != DEAD) && damage >= 9) + + add_logs(D, A, "punched") + + if((D.stat != DEAD) && damage >= A.species.punchstunthreshold) D.visible_message("[A] has weakened [D]!!", \ "[A] has weakened [D]!") D.apply_effect(4, WEAKEN, armor_block) @@ -57,6 +62,8 @@ return 1 /datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) + if(help_verb) + H.verbs += help_verb if(make_temporary) temporary = 1 if(H.martial_art && H.martial_art.temporary) @@ -71,30 +78,31 @@ if(H.martial_art != src) return H.martial_art = base - + if(help_verb) + H.verbs -= help_verb /datum/martial_art/boxing name = "Boxing" /datum/martial_art/boxing/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A << " Can't disarm while boxing!" + A << "Can't disarm while boxing!" return 1 /datum/martial_art/boxing/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A << " Can't grab while boxing!" + A << "Can't grab while boxing!" return 1 /datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_logs(D, A, "punched") + A.do_attack_animation(D) var/atk_verb = pick("left hook","right hook","straight punch") - var/damage = rand(5,8) - + var/damage = rand(5, 8) + A.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") + add_logs(D, A, "attempted to hit", atk_verb) return 0 @@ -103,11 +111,11 @@ playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) - D.visible_message("[A] has hit [D] with a [atk_verb]!", \ "[A] has hit [D] with a [atk_verb]!") D.apply_damage(damage, STAMINA, affecting, armor_block) + add_logs(D, A, "punched") if(D.getStaminaLoss() > 50) var/knockout_prob = D.getStaminaLoss() + rand(-15,15) if((D.stat != DEAD) && prob(knockout_prob)) @@ -182,6 +190,12 @@ /datum/martial_art/wrestling name = "Wrestling" + help_verb = /mob/living/carbon/human/proc/wrestling_help + +// combo refence since wrestling uses a different format to sleeping carp and plasma fist. +// Clinch "G" +// Suplex "GD" +// Advanced grab "G" /datum/martial_art/wrestling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) D.grabbedby(A,1) @@ -197,13 +211,15 @@ /datum/martial_art/wrestling/proc/Suplex(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_logs(D, A, "suplexed") + D.visible_message("[A] suplexes [D]!", \ "[A] suplexes [D]!") D.forceMove(A.loc) var/armor_block = D.run_armor_check(null, "melee") D.apply_damage(30, BRUTE, null, armor_block) D.apply_effect(6, WEAKEN, armor_block) + add_logs(D, A, "suplexed") + A.SpinAnimation(10,1) D.SpinAnimation(10,1) @@ -230,12 +246,24 @@ D.apply_damage(10, STAMINA, affecting, armor_block) return 1 +/mob/living/carbon/human/proc/wrestling_help() + set name = "Recall Teachings" + set desc = "Remember how to wrestle." + set category = "Wrestling" + + usr << "You flex your muscles and have a revelation..." + usr << "Clinch: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful." + usr << "Suplex: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor." + usr << "Advanced grab: Grab. Passively causes stamina damage when grabbing someone." + #define TORNADO_COMBO "HHD" #define THROWBACK_COMBO "DHD" #define PLASMA_COMBO "HDDDH" /datum/martial_art/plasma_fist name = "Plasma Fist" + help_verb = /mob/living/carbon/human/proc/plasma_fist_help + /datum/martial_art/plasma_fist/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(findtext(streak,TORNADO_COMBO)) @@ -271,7 +299,7 @@ "[A] has hit [D] with Plasma Punch!") playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) - D.throw_at(throw_target, 200, 4) + D.throw_at(throw_target, 200, 4,A) A.say("HYAH!") return @@ -285,26 +313,37 @@ return /datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H") + add_to_streak("H",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 /datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D") + add_to_streak("D",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 /datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G") + add_to_streak("G",D) if(check_streak(A,D)) return 1 basic_hit(A,D) return 1 +/mob/living/carbon/human/proc/plasma_fist_help() + set name = "Recall Teachings" + set desc = "Remember the martial techniques of the Plasma Fist." + set category = "Plasma Fist" + + usr << "You clench your fists and have a flashback of knowledge..." + usr << "Tornado Sweep: Harm Harm Disarm. Repulses target and everyone back." + usr << "Throwback: Disarm Harm Disarm. Throws the target and an item at them." + usr << "The Plasma Fist: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body." + +//Used by the gang of the same name. Uses combos. Basic attacks bypass armor and never miss #define WRIST_WRENCH_COMBO "DD" #define BACK_KICK_COMBO "HG" #define STOMACH_KNEE_COMBO "GH" @@ -312,6 +351,8 @@ #define ELBOW_DROP_COMBO "HDHDH" /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" + deflection_chance = 100 + help_verb = /mob/living/carbon/human/proc/sleeping_carp_help /datum/martial_art/the_sleeping_carp/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(findtext(streak,WRIST_WRENCH_COMBO)) @@ -344,7 +385,7 @@ D.emote("scream") D.drop_item() D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - D.Stun(1) + D.Stun(3) return 1 return basic_hit(A,D) @@ -375,7 +416,8 @@ "[A] kicks you in the jaw!") D.apply_damage(20, BRUTE, "head") D.drop_item() - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) + D.Stun(4) return 1 return basic_hit(A,D) @@ -386,32 +428,36 @@ if(D.stat) D.death() //FINISH HIM! D.apply_damage(50, BRUTE, "chest") - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 100, 1, -1) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) return 1 return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G") + add_to_streak("G",D) if(check_streak(A,D)) return 1 - ..() + D.grabbedby(A,1) var/obj/item/weapon/grab/G = A.get_active_hand() if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab -/datum/martial_art/the_sleeping_carp/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H") +/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("H",D) if(check_streak(A,D)) return 1 - D.visible_message("[A] [pick("punches", "kicks", "chops", "hits", "slams")] [D]!", \ - "[A] hits you!") - D.apply_damage(10, BRUTE) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) + var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") + D.visible_message("[A] [atk_verb] [D]!", \ + "[A] [atk_verb] you!") + D.apply_damage(rand(10,15), BRUTE) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1) + if(prob(D.getBruteLoss()) && !D.lying) + D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!") + D.Weaken(4) return 1 /datum/martial_art/the_sleeping_carp/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D") + add_to_streak("D",D) if(check_streak(A,D)) return 1 return ..() @@ -422,6 +468,7 @@ set category = "Sleeping Carp" usr << "You retreat inward and recall the teachings of the Sleeping Carp..." + usr << "Wrist Wrench: Disarm Disarm. Forces opponent to drop item in hand." usr << "Back Kick: Harm Grab. Opponent must be facing away. Knocks down." usr << "Stomach Knee: Grab Harm. Knocks the wind out of opponent and stuns." @@ -459,6 +506,7 @@ if(slot == slot_belt) var/mob/living/carbon/human/H = user style.teach(H,1) + user << "You have an urge to flex your muscles and get into a fight. You have the knowledge of a thousand wrestlers before you. You can remember more by using the Recall teaching verb in the wrestling tab." return /obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) @@ -467,11 +515,12 @@ var/mob/living/carbon/human/H = user if(H.get_item_by_slot(slot_belt) == src) style.remove(H) + user << "You no longer have an urge to flex your muscles." return /obj/item/weapon/plasma_fist_scroll - name = "Plasma Fist Scroll" - desc = "Teaches the traditional wizard martial art." + name = "frayed scroll" + desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" var/used = 0 @@ -483,9 +532,11 @@ var/mob/living/carbon/human/H = user var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) F.teach(H) - H << "You learn the PLASMA FIST style." + H << "You have learned the ancient martial art of Plasma Fist." used = 1 - desc += "It looks like it's magic was used up." + desc = "It's completely blank." + name = "empty scroll" + icon_state = "blankscroll" /obj/item/weapon/sleeping_carp_scroll name = "mysterious scroll" @@ -496,11 +547,8 @@ /obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user as mob) if(!istype(user) || !user) return - user << "You begin to read the scroll..." - user << "And all at once the secrets of the Sleeping Carp fill your mind. The ancient clan's martial teachings have been imbued into this scroll. As you read through it, \ - these secrets flood into your mind and body. You now know the martial techniques of the Sleeping Carp. Your hand-to-hand combat has become much more effective, and you may now perform powerful \ - combination attacks. To learn more about these combos, use the Recall Teachings ability in the Sleeping Carp tab." - user.verbs += /mob/living/carbon/human/proc/sleeping_carp_help + user << "You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \ + directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab." var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null) theSleepingCarp.teach(user) user.drop_item() @@ -508,16 +556,16 @@ new /obj/effect/decal/cleanable/ash(get_turf(src)) qdel(src) - /obj/item/weapon/twohanded/bostaff name = "bo staff" desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate." - force = 8 + force = 10 w_class = 4 slot_flags = SLOT_BACK - force_unwielded = 8 - force_wielded = 18 + force_unwielded = 10 + force_wielded = 24 throwforce = 20 + throw_speed = 2 attack_verb = list("smashed", "slammed", "whacked", "thwacked") icon = 'icons/obj/weapons.dmi' icon_state = "bostaff0" @@ -572,7 +620,7 @@ if(total_health <= config.health_threshold_crit && !H.stat) H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \ "[user] knocks you unconscious!") - H.sleeping += 30 + H.SetSleeping(30) H.adjustBrainLoss(25) return else diff --git a/code/datums/spells/fake_gib.dm b/code/datums/spells/fake_gib.dm index 5b8dc339c8e..23d2343e10e 100644 --- a/code/datums/spells/fake_gib.dm +++ b/code/datums/spells/fake_gib.dm @@ -1,17 +1,11 @@ -/obj/effect/proc_holder/spell/targeted/fake_gib +/obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate name = "Disintegrate" - desc = "This spell instantly kills somebody adjacent to you with the vilest of magick." + desc = "This spell charges your hand with vile energy that can be used to violently explode victims." + hand_path = "/obj/item/weapon/melee/touch_attack/fake_disintegrate" - school = "conjuration" - charge_max = 20 + school = "evocation" + charge_max = 600 clothes_req = 0 - invocation = "EI NATH" - invocation_type = "shout" - range = -1 - include_user = 1 - cooldown_min = 5 //25 deciseconds reduction per rank + cooldown_min = 200 //100 deciseconds reduction per rank - sparks_spread = 3 - sparks_amt = 1 - - action_icon_state = "spell_disintegrate" \ No newline at end of file + action_icon_state = "gib" \ No newline at end of file diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 99e7b0c8a0d..2c31c943284 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -14,7 +14,7 @@ selection_type = "range" var/list/compatible_mobs = list(/mob/living/carbon/human) - action_icon_state = "spell_horse" + action_icon_state = "barn" /obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) if(!targets.len) diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 904b7d54e63..98423b3e5fc 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -85,8 +85,6 @@ emp_heavy = 6 emp_light = 10 - action_icon_state = "tech" - /obj/effect/proc_holder/spell/targeted/turf_teleport/blink name = "Blink" desc = "This spell randomly teleports you a short distance." @@ -144,7 +142,7 @@ summon_type = list("/obj/effect/forcefield") summon_lifespan = 300 - action_icon_state = "spell_forcewall" + action_icon_state = "shield" /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop name = "Stop Time" diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index 7ab4e51f56e..621f159eced 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -9,10 +9,13 @@ desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \ Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \ Must be used within five minutes, or your benefactors will lose interest." + var/declaring_war = 0 /obj/item/device/nuclear_challenge/attack_self(mob/living/user) + if(declaring_war) + return if(player_list.len < MIN_CHALLENGE_PLAYERS) user << "The enemy crew is too small to be worth declaring war on." return @@ -24,9 +27,11 @@ user << "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand." return + declaring_war = 1 var/are_you_sure = alert(user, "Consult your team carefully before you declare war on [station_name()]]. Are you sure you want to alert the enemy crew?", "Declare war?", "Yes", "No") if(are_you_sure == "No") user << "On second thought, the element of surprise isn't so bad after all." + declaring_war = 0 return var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them." diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index f23ef05ad57..d7ecbf66055 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -642,7 +642,7 @@ var/global/list/multiverse = list() if(heresy) spawnheresy(M)//oh god why else - M.makeSkeleton() + M.set_species("Skeleton") M.visible_message(" A massive amount of flesh sloughs off [M] and a skeleton rises up!") M.revive() equip_skeleton(M) diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index 77703c53715..e2812db9a17 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -8,7 +8,7 @@ var/making_mage = 0 var/mages_made = 1 var/time_checked = 0 - var/players_per_mage = 8 // If the admin wants to tweak things or something + var/players_per_mage = 6 // If the admin wants to tweak things or something but_wait_theres_more = 1 var/delay_per_mage = 4200 // Every 7 minutes by default var/time_till_chaos = 18000 // Half-hour in @@ -17,11 +17,6 @@ world << "The current game mode is - Ragin' Mages!" world << "The \red Space Wizard Federation\black is pissed, help defeat all the space wizards!" -/datum/game_mode/wizard/raginmages/pre_setup() - . = ..() - if(!max_mages) - max_mages = round(num_players() / players_per_mage) - /datum/game_mode/wizard/raginmages/greet_wizard(var/datum/mind/wizard, var/you_are=1) if (you_are) @@ -37,6 +32,8 @@ /datum/game_mode/wizard/raginmages/check_finished() var/wizards_alive = 0 + // Accidental pun! + var/wizard_cap = (max_mages || (num_players() / players_per_mage)) for(var/datum/mind/wizard in wizards) if(isnull(wizard.current)) continue @@ -78,11 +75,11 @@ if (wizards_alive) if(!time_checked) time_checked = world.time - if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < max_mages)) + if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < wizard_cap)) time_checked = world.time make_more_mages() else - if(wizards.len >= max_mages) + if(wizards.len >= wizard_cap) finished = 1 return 1 else diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index f168ca5f35a..7422d610fb9 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -839,7 +839,7 @@ /obj/item/weapon/spellbook/oneuse/fake_gib - spell = /obj/effect/proc_holder/spell/targeted/fake_gib + spell = /obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate spellname = "disintegrate" icon_state ="bookfireball" desc = "This book feels like it will rip stuff apart." \ No newline at end of file diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index bd2000595f6..4e95938a2a1 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -67,6 +67,9 @@ var/new_glove_icon_state = "" var/new_glove_item_state = "" var/new_glove_name = "" + var/new_bandana_icon_state = "" + var/new_bandana_item_state = "" + var/new_bandana_name = "" var/new_shoe_icon_state = "" var/new_shoe_name = "" var/new_sheet_icon_state = "" @@ -76,59 +79,57 @@ var/new_desc = "The colors are a bit dodgy." for(var/T in typesof(/obj/item/clothing/under)) var/obj/item/clothing/under/J = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == J.item_color) new_jumpsuit_icon_state = J.icon_state new_jumpsuit_item_state = J.item_state new_jumpsuit_name = J.name qdel(J) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(J) for(var/T in typesof(/obj/item/clothing/gloves/color)) var/obj/item/clothing/gloves/color/G = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == G.item_color) new_glove_icon_state = G.icon_state new_glove_item_state = G.item_state new_glove_name = G.name qdel(G) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(G) for(var/T in typesof(/obj/item/clothing/shoes)) var/obj/item/clothing/shoes/S = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == S.item_color) new_shoe_icon_state = S.icon_state new_shoe_name = S.name qdel(S) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(S) + for(var/T in typesof(/obj/item/clothing/mask/bandana)) + var/obj/item/clothing/mask/bandana/M = new T + if(wash_color == M.item_color) + new_bandana_icon_state = M.icon_state + new_bandana_item_state = M.item_state + new_bandana_name = M.name + qdel(M) + break + qdel(M) for(var/T in typesof(/obj/item/weapon/bedsheet)) var/obj/item/weapon/bedsheet/B = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == B.item_color) new_sheet_icon_state = B.icon_state new_sheet_name = B.name qdel(B) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(B) for(var/T in typesof(/obj/item/clothing/head/soft)) var/obj/item/clothing/head/soft/H = new T - //world << "DEBUG: [color] == [J.color]" if(wash_color == H.item_color) new_softcap_icon_state = H.icon_state new_softcap_name = H.name qdel(H) - //world << "DEBUG: YUP! [new_icon_state] and [new_item_state]" break qdel(H) if(new_jumpsuit_icon_state && new_jumpsuit_item_state && new_jumpsuit_name) for(var/obj/item/clothing/under/J in contents) - //world << "DEBUG: YUP! FOUND IT!" J.item_state = new_jumpsuit_item_state J.icon_state = new_jumpsuit_icon_state J.item_color = wash_color @@ -136,7 +137,6 @@ J.desc = new_desc if(new_glove_icon_state && new_glove_item_state && new_glove_name) for(var/obj/item/clothing/gloves/color/G in contents) - //world << "DEBUG: YUP! FOUND IT!" G.item_state = new_glove_item_state G.icon_state = new_glove_icon_state G.item_color = wash_color @@ -145,7 +145,6 @@ G.desc = new_desc if(new_shoe_icon_state && new_shoe_name) for(var/obj/item/clothing/shoes/S in contents) - //world << "DEBUG: YUP! FOUND IT!" if (S.chained == 1) S.chained = 0 S.slowdown = SHOES_SLOWDOWN @@ -154,16 +153,21 @@ S.item_color = wash_color S.name = new_shoe_name S.desc = new_desc + if(new_bandana_icon_state && new_bandana_name) + for(var/obj/item/clothing/mask/bandana/M in contents) + M.item_state = new_bandana_item_state + M.icon_state = new_bandana_icon_state + M.item_color = wash_color + M.name = new_bandana_name + M.desc = new_desc if(new_sheet_icon_state && new_sheet_name) for(var/obj/item/weapon/bedsheet/B in contents) - //world << "DEBUG: YUP! FOUND IT!" B.icon_state = new_sheet_icon_state B.item_color = wash_color B.name = new_sheet_name B.desc = new_desc if(new_softcap_icon_state && new_softcap_name) for(var/obj/item/clothing/head/soft/H in contents) - //world << "DEBUG: YUP! FOUND IT!" H.icon_state = new_softcap_icon_state H.item_color = wash_color H.name = new_softcap_name @@ -313,4 +317,4 @@ state = 1 - update_icon() \ No newline at end of file + update_icon() diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 940634e6b0b..b357075b62d 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -30,12 +30,13 @@ LIGHTERS ARE IN LIGHTERS.DM var/lastHolder = null var/smoketime = 300 var/chem_volume = 30 - species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin") + species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/mask.dmi', "Unathi" = 'icons/mob/species/unathi/mask.dmi', "Tajaran" = 'icons/mob/species/tajaran/mask.dmi', - "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi' + "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi', + "Grey" = 'icons/mob/species/grey/mask.dmi' ) diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 6af8207c163..7a1107cce1d 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -89,7 +89,6 @@ display_contents_with_number = 0 //or else this will lead to stupid behavior. can_hold = list() // any cant_hold = list("/obj/item/weapon/disk/nuclear") - var/head = 0 /obj/item/weapon/storage/bag/plasticbag/mob_can_equip(M as mob, slot) @@ -101,20 +100,19 @@ /obj/item/weapon/storage/bag/plasticbag/equipped(var/mob/user, var/slot) if(slot==slot_head) - head = 1 storage_slots = 0 processing_objects.Add(src) return /obj/item/weapon/storage/bag/plasticbag/process() - if(is_equipped() && head) + if(is_equipped()) if(ishuman(loc)) var/mob/living/carbon/human/H = loc - if(H.internal) - return - H.losebreath += 1 + if(H.get_item_by_slot(slot_head) == src) + if(H.internal) + return + H.losebreath += 1 else - head = 0 storage_slots = 7 processing_objects.Remove(src) return diff --git a/code/game/vehicles/spacepods/equipment.dm b/code/game/vehicles/spacepods/equipment.dm index 80a24e72727..e151e75d99e 100644 --- a/code/game/vehicles/spacepods/equipment.dm +++ b/code/game/vehicles/spacepods/equipment.dm @@ -15,14 +15,12 @@ switch(my_atom.dir) if(NORTH) firstloc = get_step(my_atom, NORTH) - firstloc = get_step(firstloc, NORTH) secondloc = get_step(firstloc,EAST) if(SOUTH) firstloc = get_step(my_atom, SOUTH) secondloc = get_step(firstloc,EAST) if(EAST) firstloc = get_step(my_atom, EAST) - firstloc = get_step(firstloc, EAST) secondloc = get_step(firstloc,NORTH) if(WEST) firstloc = get_step(my_atom, WEST) @@ -72,34 +70,33 @@ var/shot_cost = 0 var/shots_per = 1 var/fire_sound - var/fire_delay = 20 + var/fire_delay = 15 /obj/item/device/spacepod_equipment/weaponry/taser - name = "\improper taser system" - desc = "A weak taser system for space pods, fires electrodes that shock upon impact." + name = "disabler system" + desc = "A weak taser system for space pods, fires disabler beams." icon_state = "pod_taser" projectile_type = "/obj/item/projectile/beam/disabler" - shot_cost = 250 + shot_cost = 400 fire_sound = "sound/weapons/Taser.ogg" /obj/item/device/spacepod_equipment/weaponry/burst_taser - name = "\improper burst taser system" + name = "burst taser system" desc = "A weak taser system for space pods, this one fires 3 at a time." icon_state = "pod_b_taser" projectile_type = "/obj/item/projectile/beam/disabler" - shot_cost = 350 + shot_cost = 1200 shots_per = 3 fire_sound = "sound/weapons/Taser.ogg" - fire_delay = 40 + fire_delay = 30 /obj/item/device/spacepod_equipment/weaponry/laser - name = "\improper laser system" + name = "laser system" desc = "A weak laser system for space pods, fires concentrated bursts of energy" icon_state = "pod_w_laser" projectile_type = "/obj/item/projectile/beam" - shot_cost = 300 + shot_cost = 600 fire_sound = 'sound/weapons/Laser.ogg' - fire_delay = 30 //base item for spacepod misc equipment (tracker) /obj/item/device/spacepod_equipment/misc diff --git a/code/game/vehicles/spacepods/spacepod.dm b/code/game/vehicles/spacepods/spacepod.dm index af322b3f60f..caf7c8b16be 100644 --- a/code/game/vehicles/spacepods/spacepod.dm +++ b/code/game/vehicles/spacepods/spacepod.dm @@ -49,6 +49,9 @@ var/allow2enter = 1 + var/move_delay = 2 + var/next_move = 0 + /obj/spacepod/New() . = ..() if(!pod_overlays) @@ -723,43 +726,45 @@ /datum/global_iterator/pod_tank_give_air delay = 15 - process(var/obj/spacepod/spacepod) - if(spacepod && spacepod.internal_tank) - var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air() - var/datum/gas_mixture/cabin_air = spacepod.cabin_air +/datum/global_iterator/pod_tank_give_air/process(var/obj/spacepod/spacepod) + if(spacepod && spacepod.internal_tank) + var/datum/gas_mixture/tank_air = spacepod.internal_tank.return_air() + var/datum/gas_mixture/cabin_air = spacepod.cabin_air - var/release_pressure = ONE_ATMOSPHERE - var/cabin_pressure = cabin_air.return_pressure() - var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) - var/transfer_moles = 0 - if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.return_temperature() > 0) - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) - cabin_air.merge(removed) - else if(pressure_delta < 0) //cabin pressure higher than release pressure - var/datum/gas_mixture/t_air = spacepod.get_turf_air() - pressure_delta = cabin_pressure - release_pressure + var/release_pressure = ONE_ATMOSPHERE + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) + var/transfer_moles = 0 + if(pressure_delta > 0) //cabin pressure lower than release pressure + if(tank_air.return_temperature() > 0) + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = tank_air.remove(transfer_moles) + cabin_air.merge(removed) + else if(pressure_delta < 0) //cabin pressure higher than release pressure + var/datum/gas_mixture/t_air = spacepod.get_turf_air() + pressure_delta = cabin_pressure - release_pressure + if(t_air) + pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) + if(pressure_delta > 0) //if location pressure is lower than cabin pressure + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) if(t_air) - pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) - if(pressure_delta > 0) //if location pressure is lower than cabin pressure - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles) - if(t_air) - t_air.merge(removed) - else //just delete the cabin gas, we're in space or some shit - qdel(removed) - else - return stop() - return + t_air.merge(removed) + else //just delete the cabin gas, we're in space or some shit + qdel(removed) + else + return stop() + return /obj/spacepod/relaymove(mob/user, direction) if(!CheckIfOccupant2(user)) handlerelaymove(user, direction) /obj/spacepod/proc/handlerelaymove(mob/user, direction) + if(world.time < next_move) + return 0 var/moveship = 1 - if(battery && battery.charge >= 3 && health && empcounter == 0) + if(battery && battery.charge >= 1 && health && empcounter == 0) src.dir = direction switch(direction) if(NORTH) @@ -783,16 +788,17 @@ else if(!battery) user << "No energy cell detected." - else if(battery.charge < 3) + else if(battery.charge < 1) user << "Not enough charge left." else if(!health) user << "She's dead, Jim" else if(empcounter != 0) user << "The pod control interface isn't responding. The console indicates [empcounter] seconds before reboot." else - user << "Unknown error has occurred, yell at pomf." + user << "Unknown error has occurred, yell at the coders." return 0 - battery.charge = max(0, battery.charge - 3) + battery.charge = max(0, battery.charge - 1) + next_move = world.time + move_delay /obj/spacepod/proc/CheckIfOccupant2(mob/user) if(!src.occupant2) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 81e4fd17681..b8a6f370834 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -115,7 +115,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," X << 'sound/effects/adminhelp.ogg' X << msg if("Adminhelp") - msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob, "holder")]) (CA) (REJT) [ai_found ? " (CL)" : ""]: [msg]" + msg = "[selected_type]: [key_name(src, 1, 1, selected_type)] (?) (PP) (VV) (SM) ([admin_jump_link(mob, "holder")]) (CA) (REJT) [ai_found ? " (CL)" : ""]: [msg]" for(var/client/X in modholders + adminholders) if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 0c8fec79572..18fc3ef07c7 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -120,7 +120,7 @@ if(check_rights(R_MOD|R_MENTOR,0) && !check_rights(R_ADMIN,0)) recieve_span = "mentorhelp" else - recieve_span = "danger" + recieve_span = "adminhelp" send_pm_type = holder.rank + " " recieve_pm_type = holder.rank @@ -175,7 +175,7 @@ X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" if("Adminhelp") if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) - X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" + X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" else if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) X << "[type]: [key_name(src, X, 0, type)]->[key_name(C, X, 0, type)]: [msg]" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 0c3c59595b2..8e3f5cf9b3f 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -285,16 +285,32 @@ BLIND // can't see anything //Proc that moves gas/breath masks out of the way /obj/item/clothing/mask/proc/adjustmask(var/mob/user) + var/mob/living/carbon/human/H = usr //Used to check if the mask is on the head, to check if the hands are full, and to turn off internals if they were on when the mask was pushed out of the way. if(!ignore_maskadjust) if(!user.canmove || user.stat || user.restrained()) return if(src.mask_adjusted == 1) - src.icon_state = initial(icon_state) + src.icon_state = copytext(src.icon_state, 1, findtext(src.icon_state, "_up")) //Trims the '_up' off the end of the icon state, thus reverting to the most recent previous state gas_transfer_coefficient = initial(gas_transfer_coefficient) permeability_coefficient = initial(permeability_coefficient) user << "You push \the [src] back into place." src.mask_adjusted = 0 slot_flags = initial(slot_flags) + if(flags_inv != initial(flags_inv)) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again. + flags_inv += HIDEFACE + if(H.head == src) + if(src.flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. + if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. + user.unEquip(src) + else + src.loc = user + H.head = null + if(!(H.l_hand) && H.r_hand) //If only the left hand is free, put the bandana there instead. + user.put_in_l_hand(src) + else if(!(H.r_hand) && H.l_hand) //Otherwise if only the right hand is free, put the bandana there instead. + user.put_in_r_hand(src) + else if(!(H.l_hand && H.r_hand)) //Otherwise if both hands are free, pick the active one to put the bandana into. + user.put_in_active_hand(src) else src.icon_state += "_up" user << "You push \the [src] out of the way." @@ -304,12 +320,28 @@ BLIND // can't see anything if(adjusted_flags) slot_flags = adjusted_flags if(ishuman(user)) - var/mob/living/carbon/human/H = user if(H.internal) if(H.internals) H.internals.icon_state = "internal0" H.internal = null + if(user.wear_mask == src) + if(src.flags_inv == HIDEFACE) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer. + if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground. + user.unEquip(src) + else + src.loc = user + user.wear_mask = null + if(!(H.l_hand) && H.r_hand) //If only the left hand is free, put the bandana there instead. + user.put_in_l_hand(src) + else if(!(H.r_hand) && H.l_hand) //Otherwise if only the right hand is free, put the bandana there instead. + user.put_in_r_hand(src) + else if(!(H.l_hand && H.r_hand)) //Otherwise if both hands are free, pick the active one to put the bandana into. + user.put_in_active_hand(src) + flags_inv -= HIDEFACE /*Done after the above to avoid having to do a check for initial(src.flags_inv == HIDEFACE). + This reveals the user's face since the bandana will now be going on their head.*/ + usr.update_inv_wear_mask() + usr.update_inv_head() //Shoes /obj/item/clothing/shoes diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index e9da678a45b..93e8dc6cd79 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -197,18 +197,38 @@ obj/item/clothing/mask/bandana/red name = "red bandana" icon_state = "bandred" + item_color = "red" + desc = "It's a red bandana." obj/item/clothing/mask/bandana/blue name = "blue bandana" icon_state = "bandblue" + item_color = "blue" + desc = "It's a blue bandana." obj/item/clothing/mask/bandana/gold name = "gold bandana" icon_state = "bandgold" + item_color = "yellow" + desc = "It's a gold bandana." obj/item/clothing/mask/bandana/green name = "green bandana" icon_state = "bandgreen" + item_color = "green" + desc = "It's a green bandana." + +obj/item/clothing/mask/bandana/orange + name = "orange bandana" + icon_state = "bandorange" + item_color = "orange" + desc = "It's an orange bandana." + +obj/item/clothing/mask/bandana/purple + name = "purple bandana" + icon_state = "bandpurple" + item_color = "purple" + desc = "It's a purple bandana." /obj/item/clothing/mask/bandana/botany name = "botany bandana" @@ -222,5 +242,6 @@ obj/item/clothing/mask/bandana/green /obj/item/clothing/mask/bandana/black name = "black bandana" - desc = "It's a black bandana." - icon_state = "bandblack" \ No newline at end of file + icon_state = "bandblack" + item_color = "black" + desc = "It's a black bandana." \ No newline at end of file diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index 3776f3587fb..05ac226d7e7 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -1,7 +1,8 @@ /proc/send2irc(var/channel, var/msg) - if(config.use_irc_bot && config.irc_bot_host) - spawn(0) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") + if(config.use_irc_bot && config.irc_bot_host.len) + for(var/IP in config.irc_bot_host) + spawn(0) + ext_python("ircbot_message.py", "[config.comms_password] [IP] [channel] [msg]") return /proc/send2mainirc(var/msg) diff --git a/code/modules/food/deep_fryer.dm b/code/modules/food/deep_fryer.dm index 4805983fdf4..96e5fb94c57 100644 --- a/code/modules/food/deep_fryer.dm +++ b/code/modules/food/deep_fryer.dm @@ -68,3 +68,7 @@ /datum/deepfryer_special/fried_tofu input = /obj/item/weapon/reagent_containers/food/snacks/tofu output = /obj/item/weapon/reagent_containers/food/snacks/fried_tofu + +/datum/deepfryer_special/chimichanga + input = /obj/item/weapon/reagent_containers/food/snacks/burrito + output = /obj/item/weapon/reagent_containers/food/snacks/chimichanga \ No newline at end of file diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index a9135316abe..3bbcc875bb4 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -280,6 +280,16 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas +/datum/recipe/microwave/burrito + reagents = list("capsaicin" = 5, "rice" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/beans, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito + /datum/recipe/microwave/monkeysdelight fruit = list("banana" = 1) reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8fdde351e16..436429e9bda 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -785,6 +785,12 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/proc/slip(var/description, var/stun, var/weaken, var/tilesSlipped, var/walkSafely, var/slipAny) if (flying || buckled || (walkSafely && m_intent == "walk")) return + if ((lying) && (!(tilesSlipped))) + return + if (istype(loc, /obj/structure/closet)) // for getting in a locker + return + for (var/obj/structure/closet/closet in loc.contents) // for getting out of a locker + return if (!(slipAny)) if (istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4d6b2b7cb6c..d00a4152870 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -394,6 +394,15 @@ var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) +/mob/living/carbon/human/bullet_act() + if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles! + if(!prob(martial_art.deflection_chance)) + return ..() + if(!src.lying && !(HULK in mutations)) //But only if they're not lying down, and hulks can't do it + src.visible_message("[src] deflects the projectile!", "You deflect the projectile!") + return 0 + ..() + /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M as mob) if(M.melee_damage_upper == 0) M.custom_emote(1, "[M.friendly] [src]") diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index d594d365d5c..3fd09f42d40 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -148,7 +148,7 @@ else LAssailant = M - var/damage = rand(0, M.species.max_hurt_damage)//BS12 EDIT + var/damage = rand(M.species.punchdamagelow, M.species.punchdamagehigh) damage += attack.damage if(!damage) playsound(loc, attack.miss_sound, 25, 1, -1) @@ -167,7 +167,7 @@ visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!") apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. - if((stat != DEAD) && damage >= 9) + if((stat != DEAD) && damage >= M.species.punchstunthreshold) visible_message("[M] has weakened [src]!", \ "[M] has weakened [src]!") apply_effect(4, WEAKEN, armor_block) diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index b36ba8d8ac5..a5e92e951d9 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -6,6 +6,8 @@ language = "Wryn Hivemind" tail = "wryntail" unarmed_type = /datum/unarmed_attack/punch/weak + punchdamagelow = 0 + punchdamagehigh = 1 //primitive = /mob/living/carbon/monkey/wryn darksight = 3 slowdown = 1 diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index d7b6301a61d..f3e8793fed1 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -6,12 +6,33 @@ deform = 'icons/mob/human_races/r_golem.dmi' default_language = "Galactic Common" - flags = NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN + flags = NO_BREATHE | NO_BLOOD | RADIMMUNE + virus_immune = 1 dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG + unarmed_type = /datum/unarmed_attack/punch + punchdamagelow = 5 + punchdamagehigh = 14 + punchstunthreshold = 11 //about 40% chance to stun + + warning_low_pressure = -1 + hazard_low_pressure = -1 + hazard_high_pressure = 999999999 + warning_high_pressure = 999999999 + + cold_level_1 = -1 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 999999999 + heat_level_2 = 999999999 + heat_level_3 = 999999999 + heat_level_3_breathe = 999999999 + blood_color = "#515573" flesh_color = "#137E8F" + slowdown = 3 siemens_coeff = 0 has_organ = list( @@ -45,62 +66,36 @@ item_color = "golem" has_sensor = 0 flags = ABSTRACT | NODROP - armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/suit/golem name = "adamantine shell" desc = "a golem's thick outter shell" icon_state = "golem" item_state = "golem" - w_class = 4//bulky item - gas_transfer_coefficient = 0.90 - permeability_coefficient = 0.50 - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|HEAD - slowdown = 1.0 - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE | ABSTRACT | NODROP - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD - max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD - min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) + body_parts_covered = HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES + flags = ONESIZEFITSALL | ABSTRACT | NODROP | THICKMATERIAL + armor = list(melee = 55, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/shoes/golem name = "golem's feet" desc = "sturdy adamantine feet" icon_state = "golem" item_state = "golem" - flags = NOSLIP | ABSTRACT | AIRTIGHT | MASKCOVERSMOUTH | NODROP - slowdown = SHOES_SLOWDOWN+1 - + flags = ABSTRACT | NODROP /obj/item/clothing/mask/gas/golem name = "golem's face" desc = "the imposing face of an adamantine golem" icon_state = "golem" item_state = "golem" - siemens_coefficient = 0 unacidable = 1 flags = ABSTRACT | NODROP - /obj/item/clothing/gloves/golem name = "golem's hands" desc = "strong adamantine hands" icon_state = "golem" item_state = null - siemens_coefficient = 0 - flags = ABSTRACT | NODROP - - -/obj/item/clothing/head/space/golem - icon_state = "golem" - item_state = "dermal" - item_color = "dermal" - name = "golem's head" - desc = "a golem's head" - unacidable = 1 - flags = STOPSPRESSUREDMAGE | ABSTRACT | NODROP - heat_protection = HEAD - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - armor = list(melee = 80, bullet = 20, laser = 20, energy = 10, bomb = 0, bio = 0, rad = 0) \ No newline at end of file + flags = ABSTRACT | NODROP \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 1151175ccb2..f889cbe0e4f 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -57,7 +57,9 @@ var/light_effect_amp //If 0, takes/heals 1 burn and brute per tick. Otherwise, both healing and damage effects are amplified. var/total_health = 100 - var/max_hurt_damage = 9 // Max melee damage dealt + 5 if hulk + var/punchdamagelow = 0 //lowest possible punch damage + var/punchdamagehigh = 9 //highest possible punch damage + var/punchstunthreshold = 9 //damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical var/list/default_genes = list() var/ventcrawler = 0 //Determines if the mob can go through the vents. @@ -350,7 +352,7 @@ /datum/unarmed_attack var/attack_verb = list("attack") // Empty hand hurt intent verb. - var/damage = 0 // Extra empty hand attack damage. + var/damage = 0 // How much flat bonus damage an attack will do. This is a *bonus* guaranteed damage amount on top of the random damage attacks do. var/attack_sound = "punch" var/miss_sound = 'sound/weapons/punchmiss.ogg' var/sharp = 0 @@ -361,7 +363,6 @@ /datum/unarmed_attack/punch/weak attack_verb = list("flail") - damage = 1 /datum/unarmed_attack/diona attack_verb = list("lash", "bludgeon") @@ -375,7 +376,7 @@ /datum/unarmed_attack/claws/armalis attack_verb = list("slash", "claw") - damage = 6 //they're huge! they should do a little more damage, i'd even go for 15-20 maybe... + damage = 6 /datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user) return 0 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index a3878647b44..ba88d6d7527 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -956,6 +956,7 @@ var/global/list/damage_icon_parts = list() client.screen |= contents if(hud_used) hud_used.hidden_inventory_update() //Updates the screenloc of the items on the 'other' inventory bar + update_inv_handcuffed(0) // update handcuff overlay /mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1) @@ -964,22 +965,23 @@ var/global/list/damage_icon_parts = list() drop_l_hand() stop_pulling() //TODO: should be handled elsewhere if(hud_used) //hud handcuff icons - var/obj/screen/inventory/R = hud_used.adding[7] - var/obj/screen/inventory/L = hud_used.adding[8] + var/obj/screen/inventory/R = hud_used.r_hand_hud_object + var/obj/screen/inventory/L = hud_used.l_hand_hud_object R.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="markus") L.overlays += image("icon"='icons/mob/screen_gen.dmi', "icon_state"="gabrielle") if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs)) - overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") + overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1") else - overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") + overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") else - overlays_standing[HANDCUFF_LAYER] = null + overlays_standing[HANDCUFF_LAYER] = null if(hud_used) - var/obj/screen/inventory/R = hud_used.adding[7] - var/obj/screen/inventory/L = hud_used.adding[8] - R.overlays = null - L.overlays = null - if(update_icons) update_icons() + var/obj/screen/inventory/R = hud_used.r_hand_hud_object + var/obj/screen/inventory/L = hud_used.l_hand_hud_object + R.overlays.Cut() + L.overlays.Cut() + if(update_icons) + update_icons() /mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1) if(legcuffed) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 21636735093..aa5f7723316 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -1759,6 +1759,29 @@ reagents.add_reagent("capsaicin", 6) bitesize = 4 +/obj/item/weapon/reagent_containers/food/snacks/burrito + name = "Burrito" + desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." + icon_state = "burrito" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + +/obj/item/weapon/reagent_containers/food/snacks/burrito/New() + ..() + reagents.add_reagent("nutriment", 5) + +/obj/item/weapon/reagent_containers/food/snacks/chimichanga + name = "Chimichanga" + desc = "Time to eat a chimi-f***ing-changa." + icon_state = "chimichanga" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + +/obj/item/weapon/reagent_containers/food/snacks/chimichanga/New() + ..() + reagents.add_reagent("omnizine", 4) //Deadpool reference. Deal with it. + reagents.add_reagent("cheese", 2) + /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight name = "monkey's Delight" desc = "Eeee Eee!" diff --git a/config/example/config.txt b/config/example/config.txt index c21bbcec76e..e7eaed2443a 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -245,8 +245,8 @@ GHOST_INTERACTION ## Uncomment to enable sending data to the IRC bot. #USE_IRC_BOT -## Host where the IRC bot is hosted. Port 45678 needs to be open. -#IRC_BOT_HOST localhost +## Host(s) where the IRC bot is hosted. Seperate IP's by ;. Port 45678 needs to be open. +#IRC_BOT_HOST 127.0.0.1;localhost ## IRC channel to send information to. Leave blank to disable. #MAIN_IRC #main diff --git a/html/changelogs/AutoChangeLog-pr-3547.yml b/html/changelogs/AutoChangeLog-pr-3547.yml new file mode 100644 index 00000000000..8c1f845f0c6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3547.yml @@ -0,0 +1,10 @@ +author: KasparoVy +delete-after: True +changes: + - rscadd: "Orange and purple bandanas for all station species." + - rscadd: "The ability to colour bandanas with a crayon in a washing machine." + - tweak: "Refactors the bandana adjustment system." + - tweak: "Minor adjustments to Tajaran and Unathi bandana east/west sprites." + - tweak: "Adjusting a bandana will now take if off of your head/face and put it in an available hand. If both hands are available, it goes in the selected hand." + - bugfix: "Adjusting a coloured bandana will no longer revert it to the original coloured icons anymore." + - bugfix: "Adjusting a bandana from mask-style to hat-style means the bandana won't obscure your identity anymore." diff --git a/html/changelogs/AutoChangeLog-pr-3557.yml b/html/changelogs/AutoChangeLog-pr-3557.yml new file mode 100644 index 00000000000..fdc062cb3eb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3557.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - tweak: "Updates some spell icons with better/higher quality icons" diff --git a/html/changelogs/AutoChangeLog-pr-3559.yml b/html/changelogs/AutoChangeLog-pr-3559.yml new file mode 100644 index 00000000000..ac56a2bfa3a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3559.yml @@ -0,0 +1,5 @@ +author: Crazylemon64 +delete-after: True +changes: + - tweak: "Mages are now more ragin" + - tweak: "Admins can now adjust the total number of wizards at runtime by tweaking either max_mages, or players_per mage" diff --git a/html/changelogs/AutoChangeLog-pr-3560.yml b/html/changelogs/AutoChangeLog-pr-3560.yml new file mode 100644 index 00000000000..cef1c0c229f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3560.yml @@ -0,0 +1,4 @@ +author: DaveTheHeadcrab +delete-after: True +changes: + - rscadd: "Adds new worn icons for duffelbags to better reflect their size, compliments of WJohn at /tg/" diff --git a/html/changelogs/AutoChangeLog-pr-3568.yml b/html/changelogs/AutoChangeLog-pr-3568.yml new file mode 100644 index 00000000000..2ca65994c33 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3568.yml @@ -0,0 +1,4 @@ +author: KasparoVy +delete-after: True +changes: + - rscadd: "Greys now use re-positioned smokeables. They no longer smoke out the eyes." diff --git a/html/changelogs/AutoChangeLog-pr-3569.yml b/html/changelogs/AutoChangeLog-pr-3569.yml new file mode 100644 index 00000000000..29aa056157c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3569.yml @@ -0,0 +1,12 @@ +author: Fox McCloud +delete-after: True +changes: + - tweak: "Updates unarmed attacks to allow for more customization" + - tweak: "Updates martial arts so they factor in specie's attack messages and sounds" + - tweak: "Re-balances Sleeping Carp fighting style" + - tweak: "Re-balances Bo Staff" + - tweak: "Rebalances Golem: they should now be spaceproof, fire+cold proof, rad proof, virus immune, clonable, parapen+syringe gun immune, deal increased melee damage. Their armor has been reduced to 55 melee across the board, their slip immunity removed, pain immunity removed, and they're slightly slower" + - bugfix: "Fixes Ei Nath generating two brains" + - bugfix: "Ensures the Necromatic Stone generates actual skeletons" + - bugfix: "Can now strip PDA/IDs from Golems" + - bugfix: "Fixes sleeping carp grab not being an instant aggressive grab" diff --git a/html/changelogs/AutoChangeLog-pr-3575.yml b/html/changelogs/AutoChangeLog-pr-3575.yml new file mode 100644 index 00000000000..c32ed0c1f09 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3575.yml @@ -0,0 +1,8 @@ +author: TheDZD +delete-after: True +changes: + - bugfix: "Fixes spacepods being able to shoot through walls." + - tweak: "Lowers spacepod weapons fire delay." + - tweak: "Increases spacepod weapons energy costs." + - tweak: "Makes spacepods move at speeds not rivaling those of photon beams. They are now a hair bit faster than a person with a jetpack." + - tweak: "Reduces battery costs for spacepod movement." diff --git a/html/changelogs/AutoChangeLog-pr-3576.yml b/html/changelogs/AutoChangeLog-pr-3576.yml new file mode 100644 index 00000000000..f6d9443efcc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3576.yml @@ -0,0 +1,5 @@ +author: FalseIncarnate +delete-after: True +changes: + - rscadd: "Adds burritos, made from cutlets, beans, rice, capsacin oil (hotsauce), cheese, and flat dough (because we lack proper tortillas) in the microwave." + - rscadd: "Adds chimichangas. You know you want a deep-fried burrito." diff --git a/html/changelogs/AutoChangeLog-pr-3584.yml b/html/changelogs/AutoChangeLog-pr-3584.yml new file mode 100644 index 00000000000..98ed8cd34bb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3584.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - bugfix: "Fixes an exploit with declaring war on the station" diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 57d17caaa46..7f5f8925b17 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 6f24676144a..043c0f35be0 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index d839e71c4d7..d6dacdce500 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/species/grey/mask.dmi b/icons/mob/species/grey/mask.dmi new file mode 100644 index 00000000000..27785b33141 Binary files /dev/null and b/icons/mob/species/grey/mask.dmi differ diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi index a54464d1f2d..9c3339e29e0 100644 Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi index e1b2f430e02..a37b45b4e96 100644 Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi index fd7fb656620..df31a6851ae 100644 Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi index fb17cd483a4..37aedd13592 100644 Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 9bd0199de51..1e033f6746d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index f8728eb6ab3..b2ff355592b 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index db264270f2c..a8ba16b7b69 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -20,6 +20,7 @@ em {font-style: normal; font-weight: bold;} .adminobserverooc {color: #0099cc; font-weight: bold;} .adminooc {color: #b82e00; font-weight: bold;} .mentorhelp {color: #0077bb; font-weight: bold;} +.adminhelp {color: #aa0000; font-weight: bolt;} .adminobserver {color: #996600; font-weight: bold;} .admin {color: #386aff; font-weight: bold;} diff --git a/paradise.dme b/paradise.dme index 21a15e95ada..7f3586f1537 100644 --- a/paradise.dme +++ b/paradise.dme @@ -167,6 +167,7 @@ #include "code\controllers\Processes\shuttles.dm" #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\ticker.dm" +#include "code\controllers\Processes\timer.dm" #include "code\controllers\Processes\vote.dm" #include "code\controllers\Processes\shuttles\emergency.dm" #include "code\controllers\Processes\shuttles\supply.dm"