diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index e94f02efcf9..a20997140f0 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -667,6 +667,17 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee access = access_security group = "Security" +/datum/supply_packs/disabler + name = "Disabler Crate" + contains = list(/obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler, + /obj/item/weapon/gun/energy/disabler) + cost = 10 + containertype = /obj/structure/closet/crate/secure/weapon + containername = "disabler crate" + access = access_security + group = "Security" + /datum/supply_packs/eweapons name = "Experimental weapons crate" contains = list(/obj/item/weapon/flamethrower/full, diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 799f7f7da90..627d24d9355 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -16,6 +16,7 @@ var/global/datum/controller/gameticker/ticker var/event_time = null var/event = 0 + var/login_music // music played in pregame lobby var/list/datum/mind/minds = list()//The people in the game. Used for objective tracking. @@ -38,6 +39,10 @@ var/global/datum/controller/gameticker/ticker var/initialtpass = 0 //holder for inital autotransfer vote timer /datum/controller/gameticker/proc/pregame() + login_music = pick(\ + 'sound/music/space.ogg',\ + 'sound/music/Title1.ogg',\ + 'sound/music/Title2.ogg',) do pregame_timeleft = 180 world << "Welcome to the pre-game lobby!" diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index f63b3fd114b..a2a5e5228c2 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -109,7 +109,7 @@ icon_state = "mecha_taser" energy_drain = 20 equip_cooldown = 8 - projectile = /obj/item/projectile/energy/electrode/revolver + projectile = /obj/item/projectile/energy/electrode fire_sound = 'sound/weapons/Taser.ogg' size = 1 diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index ec5506e125b..224de285a1c 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -1,227 +1,148 @@ /obj/item/device/flash name = "flash" - desc = "Used for blinding and being an asshole." + desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production." icon_state = "flash" item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang) - throwforce = 5 - w_class = 1.0 - throw_speed = 4 - throw_range = 10 - flags = FPRINT | TABLEPASS| CONDUCT + throwforce = 0 + w_class = 1 + throw_speed = 3 + throw_range = 7 + flags = FPRINT | TABLEPASS | CONDUCT origin_tech = "magnets=2;combat=1" var/times_used = 0 //Number of times it's been used. var/broken = 0 //Is the flash burnt out? var/last_used = 0 //last world.time it was used. -/obj/item/device/flash/proc/clown_check(var/mob/user) + +/obj/item/device/flash/proc/clown_check(mob/user) if(user && (M_CLUMSY in user.mutations) && prob(50)) - user << "\red \The [src] slips out of your hand." - user.drop_item() + flash_carbon(user, user, 15, 0) + user.visible_message("[user] blinds [user] with the flash!") return 0 return 1 -/obj/item/device/flash/proc/flash_recharge() - //capacitor recharges over time - for(var/i=0, i<3, i++) - if(last_used+600 > world.time) - break - last_used += 600 - times_used -= 2 + +/obj/item/device/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. + broken = 1 + icon_state = "[initial(icon_state)]burnt" + visible_message("The [src.name] burns out!") + + +/obj/item/device/flash/proc/flash_recharge(var/mob/user) + if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break! + burn_out() + return 0 + + var/deciseconds_passed = world.time - last_used + for(var/seconds = deciseconds_passed/10, seconds>=10, seconds-=10) //get 1 charge every 10 seconds + times_used-- + last_used = world.time - times_used = max(0,round(times_used)) //sanity + times_used = max(0, times_used) //sanity -/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob) - if(!user || !M) return //sanity +/obj/item/device/flash/proc/try_use_flash(var/mob/user) + flash_recharge(user) - M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])") - if(M.ckey) - msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (JMP)") - - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - if(!clown_check(user)) return if(broken) - user << "\The [src] is broken." - return + return 0 - flash_recharge() - - //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking - //It will never break on the first use. - switch(times_used) - if(0 to 5) - last_used = world.time - if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break! - broken = 1 - user << "The bulb has burnt out!" - icon_state = "flashburnt" - return - times_used++ - else //can only use it 5 times a minute - user << "*click* *click*" - return playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) - var/flashfail = 0 + flick("[initial(icon_state)]2", src) + times_used++ + + if(user && !clown_check(user)) + return 0 + + return 1 + + +/obj/item/device/flash/proc/flash_carbon(var/mob/living/carbon/M, var/mob/user = null, var/power = 5, convert = 1) + add_logs(M, user, "flashed", object="the flash") + var/safety = M:eyecheck() + if(safety <= 0) + M.confused += power + flick("e_flash", M.flash) + if(user && convert) + terrible_conversion_proc(M, user) + M.Stun(1) + +/obj/item/device/flash/attack(mob/living/M, mob/user) + if(!try_use_flash(user)) + return 0 if(iscarbon(M)) - var/safety = M:eyecheck() - if(safety <= 0) - M.Weaken(5) - flick("e_flash", M.flash) - - if(ishuman(M) && ishuman(user) && M.stat!=DEAD) - if(user.mind && user.mind in ticker.mode.head_revolutionaries) - var/revsafe = 0 - for(var/obj/item/weapon/implant/loyalty/L in M) - if(L && L.implanted) - revsafe = 1 - break - M.mind_initialize() //give them a mind datum if they don't have one. - if(M.mind.has_been_rev) - revsafe = 2 - if(!revsafe) - M.mind.has_been_rev = 1 - ticker.mode.add_revolutionary(M.mind) - else if(revsafe == 1) - user << "Something seems to be blocking the flash!" - else - user << "This mind seems resistant to the flash!" - user << "This mind is so vacant that it is not susceptible to influence!" - else - flashfail = 1 + flash_carbon(M, user, 5, 1) + user.visible_message("[user] blinds [M] with the flash!") + return 1 else if(issilicon(M)) M.Weaken(rand(5,10)) - else - flashfail = 1 + add_logs(M, user, "flashed", object="[src.name]") + user.visible_message("[user] overloads [M]'s sensors with the flash!") + return 1 - if(isrobot(user)) - spawn(0) - var/atom/movable/overlay/animation = new(user.loc) - animation.layer = user.layer + 1 - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = user - flick("blspell", animation) - sleep(5) - del(animation) - - if(!flashfail) - flick("flash2", src) - if(!issilicon(M)) - - user.visible_message("[user] blinds [M] with the flash!") - else - - user.visible_message("[user] overloads [M]'s sensors with the flash!") - else - - user.visible_message("[user] fails to blind [M] with the flash!") - - return + user.visible_message("[user] fails to blind [M] with the flash!") - - -/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) - if(!user || !clown_check(user)) return - if(broken) - user.show_message("The [src.name] is broken", 2) - return - - flash_recharge() - - //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking - //It will never break on the first use. - switch(times_used) - if(0 to 5) - if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break! - broken = 1 - user << "The bulb has burnt out!" - icon_state = "flashburnt" - return - times_used++ - else //can only use it 5 times a minute - user.show_message("*click* *click*", 2) - return - playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) - flick("flash2", src) - if(user && isrobot(user)) - spawn(0) - var/atom/movable/overlay/animation = new(user.loc) - animation.layer = user.layer + 1 - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = user - flick("blspell", animation) - sleep(5) - del(animation) - +/obj/item/device/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0) + if(!try_use_flash(user)) + return 0 for(var/mob/living/carbon/M in oviewers(3, null)) - if(prob(50)) - if (locate(/obj/item/weapon/cloaking_device, M)) - for(var/obj/item/weapon/cloaking_device/S in M) - S.active = 0 - S.icon_state = "shield0" - if(M.alpha < 255) - var/oldalpha = M.alpha - if(prob(80)) - M.alpha = 255 - M.visible_message("[M] suddenly becomes fully visible!",\ - "You see a bright flash of light and are suddenly fully visible again.") - spawn(50) - M.alpha = oldalpha - var/safety = M:eyecheck() - if(!safety) - if(!M.blinded) - flick("flash", M.flash) + flash_carbon(M, user, 3, 0) - return /obj/item/device/flash/emp_act(severity) - if(broken) return - flash_recharge() - switch(times_used) - if(0 to 5) - if(prob(2*times_used)) - broken = 1 - icon_state = "flashburnt" - return - times_used++ - if(istype(loc, /mob/living/carbon)) - var/mob/living/carbon/M = loc - var/safety = M.eyecheck() - if(safety <= 0) - M.Weaken(5) - flick("e_flash", M.flash) - for(var/mob/O in viewers(M, null)) - O.show_message("[M] is blinded by the flash!") + if(!try_use_flash()) + return 0 + for(var/mob/living/carbon/M in viewers(3, null)) + flash_carbon(M, null, 10, 0) + burn_out() ..() -/obj/item/device/flash/synthetic - name = "synthetic flash" - desc = "When a problem arises, SCIENCE is the solution." - icon_state = "sflash" - origin_tech = "magnets=2;combat=1" - var/construction_cost = list("metal"=750,"glass"=750) - var/construction_time=100 -/obj/item/device/flash/synthetic/attack(mob/living/M as mob, mob/user as mob) - ..() - if(!broken) - broken = 1 - user << "\red The bulb has burnt out!" - icon_state = "flashburnt" +/obj/item/device/flash/proc/terrible_conversion_proc(var/mob/M, var/mob/user) + if(ishuman(M) && ishuman(user) && M.stat != DEAD) + if(user.mind && ((user.mind in ticker.mode.head_revolutionaries))) + if(M.client) + if(M.stat == CONSCIOUS) + M.mind_initialize() //give them a mind datum if they don't have one. + var/resisted + if(!isloyal(M)) + if(user.mind in ticker.mode.head_revolutionaries) + if(!ticker.mode.add_revolutionary(M.mind)) + resisted = 1 + else + resisted = 1 -/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) + if(resisted) + user << "This mind seems resistant to the flash!" + else + user << "They must be conscious before you can convert them!" + else + user << "This mind is so vacant that it is not susceptible to influence!" + + +/obj/item/device/flash/cyborg + origin_tech = null + +/obj/item/device/flash/cyborg/attack(mob/living/M, mob/user) ..() - if(!broken) - broken = 1 - user << "\red The bulb has burnt out!" - icon_state = "flashburnt" + cyborg_flash_animation(user) + +/obj/item/device/flash/cyborg/attack_self(mob/user) + ..() + cyborg_flash_animation(user) + +/obj/item/device/flash/cyborg/proc/cyborg_flash_animation(var/mob/living/user) + var/atom/movable/overlay/animation = new(user.loc) + animation.layer = user.layer + 1 + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = user + flick("blspell", animation) + sleep(5) + del(animation) + +/obj/item/device/flash/synthetic //just a regular flash now \ No newline at end of file diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm index 7026cf6f74a..ba914f4f8ce 100644 --- a/code/game/objects/items/weapons/alien_specific.dm +++ b/code/game/objects/items/weapons/alien_specific.dm @@ -56,7 +56,7 @@ //SKREEEEEEEEEEEE tool -/obj/item/device/flash/alien +/obj/item/device/flash/cyborg/alien name = "eye flash" desc = "Useful for taking pictures, making friends and flash-frying chips." icon = 'icons/mob/alien.dmi' diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index fb273ff1ed2..d7e501ea6e1 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -3,29 +3,24 @@ desc = "A stun baton for incapacitating people with." icon_state = "stunbaton" item_state = "baton" - flags = FPRINT | TABLEPASS slot_flags = SLOT_BELT + flags = FPRINT | TABLEPASS force = 10 throwforce = 7 w_class = 3 origin_tech = "combat=2" attack_verb = list("beaten") - var/stunforce = 0 - var/agonyforce = 60 - var/status = 0 //whether the thing is on or not + var/stunforce = 7 + var/status = 0 var/obj/item/weapon/cell/high/bcell = null - var/mob/foundmob = "" //Used in throwing proc. - var/hitcost = 1500 //oh god why do power cells carry so much charge? We probably need to make a distinction between "industrial" sized power cells for APCs and power cells for everything else. - var/allowharm = 1 // Allow or disallow harming with the stunbaton + var/hitcost = 1500 /obj/item/weapon/melee/baton/suicide_act(mob/user) user.visible_message("[user] is putting the live [name] in \his mouth! It looks like \he's trying to commit suicide.") return (FIRELOSS) - -/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed. +/obj/item/weapon/melee/baton/New() ..() - bcell = new/obj/item/weapon/cell/high(src) update_icon() return @@ -33,25 +28,22 @@ bcell = locate(/obj/item/weapon/cell) in contents update_icon() +/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed. + ..() + bcell = new(src) + update_icon() + return + /obj/item/weapon/melee/baton/proc/deductcharge(var/chrgdeductamt) if(bcell) - if(bcell.rigged) - bcell.explode()//exploding baton of justice + if(bcell.charge < (hitcost+chrgdeductamt)) // If after the deduction the baton doesn't have enough charge for a stun hit it turns off. + status = 0 update_icon() - return + playsound(loc, "sparks", 75, 1, -1) + if(bcell.use(chrgdeductamt)) + return 1 else - bcell.charge -= max(chrgdeductamt,0) - if(bcell.charge < hitcost) - status = 0 - update_icon() - -/obj/item/weapon/melee/baton/examine() - set src in view(1) - ..() - if(bcell) - usr <<"The baton is [round(bcell.percent())]% charged." - if(!bcell) - usr <<"The baton does not have a power source installed." + return 0 /obj/item/weapon/melee/baton/update_icon() if(status) @@ -61,16 +53,27 @@ else icon_state = "[initial(icon_state)]" +/obj/item/weapon/melee/baton/examine(mob/user) + ..() + if(bcell) + user <<"The baton is [round(bcell.percent())]% charged." + if(!bcell) + user <<"The baton does not have a power source installed." + /obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user) if(istype(W, /obj/item/weapon/cell)) - if(!bcell) + var/obj/item/weapon/cell/C = W + if(bcell) + user << "[src] already has a cell." + else + if(C.maxcharge < hitcost) + user << "[src] requires a higher capacity cell." + return user.drop_item() W.loc = src bcell = W user << "You install a cell in [src]." update_icon() - else - user << "[src] already has a cell." else if(istype(W, /obj/item/weapon/screwdriver)) if(bcell) @@ -85,143 +88,88 @@ return /obj/item/weapon/melee/baton/attack_self(mob/user) - if(status && (M_CLUMSY in user.mutations) && prob(50)) - user << "\red You grab the [src] on the wrong side." - user.Weaken(stunforce*3) - deductcharge(hitcost) - return - if(bcell && bcell.charge) - if(bcell.charge < hitcost) - status = 0 - user << "[src] is out of charge." - else - status = !status - user << "[src] is now [status ? "on" : "off"]." - playsound(loc, "sparks", 75, 1, -1) - update_icon() + if(bcell && bcell.charge > hitcost) + status = !status + user << "[src] is now [status ? "on" : "off"]." + playsound(loc, "sparks", 75, 1, -1) else status = 0 if(!bcell) user << "[src] does not have a power source!" else user << "[src] is out of charge." + update_icon() add_fingerprint(user) -/obj/item/weapon/melee/baton/attack(mob/M, mob/user) +/obj/item/weapon/melee/baton/attack(mob/M, mob/living/user) if(status && (M_CLUMSY in user.mutations) && prob(50)) - user << "span class='danger'>You accidentally hit yourself with the [src]!" - user.Weaken(30) + user.visible_message("[user] accidentally hits themself with [src]!", \ + "You accidentally hit yourself with [src]!") + user.Weaken(stunforce*3) deductcharge(hitcost) return if(isrobot(M)) ..() return + if(!isliving(M)) + return - var/agony = agonyforce - var/stun = stunforce var/mob/living/L = M - var/target_zone = check_zone(user.zone_sel.selecting) - if(user.a_intent == "harm" && allowharm == 1) - if (!..()) //item/attack() does it's own messaging and logs - return 0 // item/attack() will return 1 if they hit, 0 if they missed. - agony *= 0.5 //whacking someone causes a much poorer contact than prodding them. - stun *= 0.5 - //we can't really extract the actual hit zone from ..(), unfortunately. Just act like they attacked the area they intended to. - else - //copied from human_defense.dm - human defence code should really be refactored some time. - if (ishuman(L)) - user.lastattacked = L //are these used at all, if we have logs? - L.lastattacker = user - - if (user != L) // Attacking yourself can't miss - target_zone = get_zone_with_miss_chance(user.zone_sel.selecting, L) - - if(!target_zone) - L.visible_message("\red [user] misses [L] with \the [src]!") - return 0 - - var/mob/living/carbon/human/H = L - var/datum/organ/external/affecting = H.get_organ(target_zone) - if (affecting) - if(!status) - L.visible_message("[L] has been prodded in the [affecting.display_name] with [src] by [user]. Luckily it was off.") - return 1 - else - H.visible_message("[L] has been prodded in the [affecting.display_name] with [src] by [user]!") + if(user.a_intent != "harm") + if(status) + baton_stun(L, user) else - if(!status) - L.visible_message("[L] has been prodded with [src] by [user]. Luckily it was off.") - return 1 - else - L.visible_message("[L] has been prodded with [src] by [user]!") + L.visible_message("[L] has been prodded with [src] by [user]. Luckily it was off.", \ + "You've been prodded with [src] by [user]. Luckily it was off") + return + else + ..() + if(status) + baton_stun(L, user) - //stun effects - L.stun_effect_act(stun, agony, target_zone, src) +/obj/item/weapon/melee/baton/proc/baton_stun(mob/living/L, mob/user) + user.lastattacked = L + L.lastattacker = user + + L.Stun(stunforce) + L.Weaken(stunforce) + L.apply_effect(STUTTER, stunforce) + + L.visible_message("[L] has been stunned with [src] by [user]!", \ + "You've been stunned with [src] by [user]!") playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - msg_admin_attack("[key_name(user)] stunned [key_name(L)] with the [src].") - deductcharge(hitcost) + if(isrobot(loc)) + var/mob/living/silicon/robot/R = loc + if(R && R.cell) + R.cell.use(hitcost) + else + deductcharge(hitcost) if(ishuman(L)) var/mob/living/carbon/human/H = L H.forcesay(hit_appends) - return 1 - - -/obj/item/weapon/melee/baton/throw_impact(atom/hit_atom) - . = ..() - if (prob(50)) - if(istype(hit_atom, /mob/living)) - var/mob/living/carbon/human/H = hit_atom - if(status) - //stun effects - if (stunforce) - H.Stun(stunforce) - H.Weaken(stunforce) - H.apply_effect(STUTTER, stunforce) - - if (agonyforce) - //Siemens coefficient? - //TODO: Merge this with taser effects - H.apply_effect(agonyforce,AGONY,0) - H.apply_effect(STUTTER, agonyforce/10) - H.apply_effect(EYE_BLUR, agonyforce/10) - H.flash_pain() - - deductcharge(hitcost) - - if(bcell.charge < hitcost) - status = 0 - update_icon() - - - for(var/mob/M in player_list) if(M.key == src.fingerprintslast) - foundmob = M - break - - H.visible_message("[src], thrown by [foundmob.name], strikes [H] and stuns them!") - - H.attack_log += "\[[time_stamp()]\] Stunned by thrown [src.name] last touched by ([src.fingerprintslast])" - log_attack("Flying [src.name], last touched by ([src.fingerprintslast]) stunned [H.name] ([H.ckey])" ) - - if(!iscarbon(foundmob)) - H.LAssailant = null - else - H.LAssailant = foundmob + add_logs(L, user, "stunned", object="stunbaton") /obj/item/weapon/melee/baton/emp_act(severity) if(bcell) - bcell.emp_act(severity) //let's not duplicate code everywhere if we don't have to please. + deductcharge(1000 / severity) + if(bcell.reliability != 100 && prob(50/severity)) + bcell.reliability -= 10 / severity ..() //secborg stun baton module /obj/item/weapon/melee/baton/robot hitcost = 500 +/obj/item/weapon/melee/baton/robot/New() + ..() + return + /obj/item/weapon/melee/baton/robot/attack_self(mob/user) //try to find our power cell var/mob/living/silicon/robot/R = loc @@ -246,16 +194,6 @@ item_state = "prod" force = 3 throwforce = 5 - stunforce = 0 - agonyforce = 42 //less than a stunbaton and uses way more charge. + stunforce = 5 hitcost = 3750 - attack_verb = list("poked") - slot_flags = null - -/obj/item/weapon/melee/baton/cattleprod/update_icon() - if(status) - icon_state = "stunprod_active" - else if(!bcell) - icon_state = "stunprod_nocell" - else - icon_state = "stunprod" + slot_flags = null \ No newline at end of file diff --git a/code/game/sound.dm b/code/game/sound.dm index 925dbb0fad2..8f76396ed4c 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -93,6 +93,10 @@ var/const/FALLOFF_SOUNDS = 0.5 S.environment = 2 src << S +/client/proc/playtitlemusic() + if(!ticker || !ticker.login_music) return + if(prefs.sound & SOUND_LOBBY) + src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index acd0a4585a4..e832922a0ef 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -310,6 +310,7 @@ datum/preferences dat += "-Color: [UI_style_color]
__

" dat += "-Alpha(transparence): [UI_style_alpha]
" dat += "Play admin midis: [(sound & SOUND_MIDI) ? "Yes" : "No"]
" + dat += "Play lobby music: [(sound & SOUND_LOBBY) ? "Yes" : "No"]
" dat += "Randomized Character Slot: [randomslot ? "Yes" : "No"]
" dat += "Ghost ears: [(toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]
" dat += "Ghost sight: [(toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]
" @@ -1291,6 +1292,13 @@ datum/preferences if("hear_midis") sound ^= SOUND_MIDI + if("lobby_music") + sound ^= SOUND_LOBBY + if(sound & SOUND_LOBBY) + user << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = 1) + else + user << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) + if("ghost_ears") toggles ^= CHAT_GHOSTEARS diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index a9b9d9aad9c..196674eefde 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -59,6 +59,21 @@ src << "You will [(prefs.toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat." feedback_add_details("admin_verb","TP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/toggletitlemusic() + set name = "Hear/Silence LobbyMusic" + set category = "Preferences" + set desc = "Toggles hearing the GameLobby music" + prefs.sound ^= SOUND_LOBBY + prefs.save_preferences(src) + if(prefs.sound & SOUND_LOBBY) + src << "You will now hear music in the game lobby." + if(istype(mob, /mob/new_player)) + playtitlemusic() + else + src << "You will no longer hear music in the game lobby." + if(istype(mob, /mob/new_player)) + src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jamsz + feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/togglemidis() set name = "Hear/Silence Midis" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 882d972ddd7..7d307c92aac 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -219,8 +219,6 @@ "\blue [M] gives [src] a [pick("hug","warm embrace")].", \ "\blue You hug [src].", \ ) - if(prob(10)) - src.emote("fart") /mob/living/carbon/proc/eyecheck() diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index a59a0c8d636..28afe49ab45 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -635,8 +635,11 @@ // Needed for M_TOXIC_FART if("fart") if(world.time-lastFart >= 600) - playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins voted no to fun - message = "[src] [pick("passes wind","farts")]." +// playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun + if(M_TOXIC_FARTS in mutations) + message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." + else + message = "[src] [pick("passes wind","farts")]." m_type = 2 var/turf/location = get_turf(src) @@ -644,38 +647,31 @@ if(M_SUPER_FART in mutations) aoe_range+=3 //Was 5 - // If we're wearing a suit, don't blast or gas those around us. + /* // If we're wearing a suit, don't blast or gas those around us. var/wearing_suit=0 var/wearing_mask=0 if(wear_suit && wear_suit.body_parts_covered & LOWER_TORSO) wearing_suit=1 if (internal != null && wear_mask && (wear_mask.flags & MASKINTERNALS)) - wearing_mask=1 + wearing_mask=1 */ // Process toxic farts first. if(M_TOXIC_FARTS in mutations) - if(wearing_suit) - if(!wearing_mask) - src << "\red You gas yourself!" - reagents.add_reagent("space_drugs", rand(10,20)) - else - // Was /turf/, now /mob/ - - for(var/mob/M in range(location,aoe_range)) - if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS)) - continue - if(!airborne_can_reach(location,M,aoe_range)) - continue - // Now, we don't have this: - //new /obj/effects/fart_cloud(T,L) - // But: - // <[REDACTED]> so, what it does is...imagine a 3x3 grid with the person in the center. When someone uses the emote *fart (it's not a spell style ability and has no cooldown), then anyone in the 8 tiles AROUND the person who uses it - // <[REDACTED]> gets between 1 and 10 units of jenkem added to them...we obviously don't have Jenkem, but Space Drugs do literally the same exact thing as Jenkem - // <[REDACTED]> the user, of course, isn't impacted because it's not an actual smoke cloud - // So, let's give 'em space drugs. - if (M == src) - continue - M.reagents.add_reagent("space_drugs",rand(1,10)) + for(var/mob/M in range(location,aoe_range)) + if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS)) + continue + if(!airborne_can_reach(location,M,aoe_range)) + continue + // Now, we don't have this: + //new /obj/effects/fart_cloud(T,L) + // But: + // <[REDACTED]> so, what it does is...imagine a 3x3 grid with the person in the center. When someone uses the emote *fart (it's not a spell style ability and has no cooldown), then anyone in the 8 tiles AROUND the person who uses it + // <[REDACTED]> gets between 1 and 10 units of jenkem added to them...we obviously don't have Jenkem, but Space Drugs do literally the same exact thing as Jenkem + // <[REDACTED]> the user, of course, isn't impacted because it's not an actual smoke cloud + // So, let's give 'em space drugs. + if (M == src) + continue + M.reagents.add_reagent("space_drugs",rand(1,10)) /* var/datum/effect/effect/system/smoke_spread/chem/fart/S = new /datum/effect/effect/system/smoke_spread/chem/fart S.attach(location) @@ -686,23 +682,21 @@ S.start() */ if(M_SUPER_FART in mutations) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) visible_message("\red [name] hunches down and grits their teeth!") if(do_after(usr,30)) visible_message("\red [name] unleashes a [pick("tremendous","gigantic","colossal")] fart!","You hear a [pick("tremendous","gigantic","colossal")] fart.") //playsound(L.loc, 'superfart.ogg', 50, 0) - if(!wearing_suit) - for(var/mob/living/V in range(location,aoe_range)) - shake_camera(V,10,5) - if (V == src) - continue - if(!airborne_can_reach(get_turf(src), get_turf(V))) - continue - V << "\red You are sent flying!" - V.Weaken(5) // why the hell was this set to 12 christ - step_away(V,location,15) - step_away(V,location,15) - step_away(V,location,15) + for(var/mob/living/V in range(location,aoe_range)) + shake_camera(V,10,5) + if (V == src) + continue + if(!airborne_can_reach(get_turf(src), get_turf(V))) + continue + V << "\red You are sent flying!" + V.Weaken(5) // why the hell was this set to 12 christ + step_away(V,location,15) + step_away(V,location,15) + step_away(V,location,15) else usr << "\red You were interrupted and couldn't fart! Rude!" lastFart=world.time diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 113f00e1fb9..73c5f3b1857 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -64,12 +64,13 @@ src <<"\red You have been hit by [P]!" del P return -*/ + if(istype(P, /obj/item/projectile/energy/electrode) || istype(P, /obj/item/projectile/bullet/stunshot)) stun_effect_act(0, P.agony, def_zone, P) src <<"\red You have been hit by [P]!" del P return +*/ //Armor var/absorb = run_armor_check(def_zone, P.flag) @@ -81,7 +82,7 @@ if(!P.nodamage) apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge) - + P.on_hit(src, absorb, def_zone) if(istype(P, /obj/item/projectile/beam/lightning)) if(P.damage >= 200) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index ecdfd40b84c..64f5c33dbc6 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -10,11 +10,11 @@ var/list/department_radio_keys = list( ":s" = "Security", "#s" = "Security", ".s" = "Security", ":w" = "whisper", "#w" = "whisper", ".w" = "whisper", ":b" = "binary", "#b" = "binary", ".b" = "binary", - ":d" = "drone", "#d" = "drone", ".d" = "drone", + ":d" = "drone", "#d" = "drone", ".d" = "drone", ":a" = "alientalk", "#a" = "alientalk", ".a" = "alientalk", ":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate", ":u" = "Supply", "#u" = "Supply", ".u" = "Supply", - ":z" = "Service", "#z" = "Service", ".z" = "Service", + ":z" = "Service", "#z" = "Service", ".z" = "Service", ":g" = "changeling", "#g" = "changeling", ".g" = "changeling", @@ -28,14 +28,14 @@ var/list/department_radio_keys = list( ":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering", ":S" = "Security", "#S" = "Security", ".S" = "Security", ":W" = "whisper", "#W" = "whisper", ".W" = "whisper", - ":D" = "drone", "#D" = "drone", ".D" = "drone", + ":D" = "drone", "#D" = "drone", ".D" = "drone", ":B" = "binary", "#B" = "binary", ".B" = "binary", ":A" = "alientalk", "#A" = "alientalk", ".A" = "alientalk", ":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate", ":U" = "Supply", "#U" = "Supply", ".U" = "Supply", ":Z" = "Service", "#Z" = "Service", ".Z" = "Service", ":G" = "changeling", "#G" = "changeling", ".G" = "changeling" - + /* //kinda localization -- rastaf0 //same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding. ":ê" = "right hand", "#ê" = "right hand", ".ê" = "right hand", @@ -185,8 +185,8 @@ var/list/department_radio_keys = list( if (!(istype(src,/mob/living/carbon/human) && !isAI(src) && !isrobot(src) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department") || isAI(src) && (message_mode=="department") || (message_mode in radiochannels))) message_mode = null //only humans can use headsets - if(src.stunned > 2 || (traumatic_shock > 61 && prob(50))) - message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it + if(traumatic_shock > 61 && prob(50)) + message_mode = null //people in shock will have a high chance of not being able to speak on radio; needed since people don't instantly pass out at 100 damage. message = capitalize(message) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 38fd15f0cd3..7f97febc907 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -24,7 +24,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.emag = new /obj/item/toy/sword(src) src.emag.name = "Placeholder Emag Item" // src.jetpack = new /obj/item/toy/sword(src) @@ -62,7 +62,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/loaded(src) src.modules += new /obj/item/weapon/extinguisher(src) src.modules += new /obj/item/weapon/wrench(src) @@ -80,7 +80,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src) src.modules += new /obj/item/weapon/scalpel(src) @@ -119,7 +119,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/device/reagent_scanner/adv(src) src.modules += new /obj/item/roller_holder(src) @@ -164,7 +164,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/extinguisher(src) src.modules += new /obj/item/weapon/rcd/borg(src) @@ -187,7 +187,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/extinguisher(src) src.modules += new /obj/item/weapon/weldingtool/largetank(src) @@ -228,7 +228,7 @@ New() src.modules += new /obj/item/device/flashlight/seclite(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/handcuffs/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src) @@ -244,7 +244,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/soap/nanotrasen(src) src.modules += new /obj/item/weapon/storage/bag/trash(src) src.modules += new /obj/item/weapon/mop(src) @@ -264,7 +264,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/reagent_containers/food/drinks/cans/beer(src) src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src) @@ -291,7 +291,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/weapon/pen/robopen(src) src.modules += new /obj/item/weapon/form_printer(src) src.modules += new /obj/item/device/taperecorder(src) @@ -312,7 +312,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/wrench(src) src.modules += new /obj/item/weapon/screwdriver(src) @@ -326,7 +326,7 @@ name = "NT advanced combat module" /obj/item/weapon/robot_module/deathsquad/New() - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/borg/sight/thermal(src) src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src) @@ -340,7 +340,7 @@ name = "syndicate robot module" /obj/item/weapon/robot_module/syndicate/New() - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src) src.modules += new /obj/item/weapon/gun/energy/crossbow/cyborg(src) @@ -356,7 +356,7 @@ New() src.modules += new /obj/item/device/flashlight(src) - src.modules += new /obj/item/device/flash(src) + src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/borg/sight/thermal(src) src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) @@ -371,7 +371,7 @@ New() src.modules += new /obj/item/weapon/melee/energy/alien/claws(src) - src.modules += new /obj/item/device/flash/alien(src) + src.modules += new /obj/item/device/flash/cyborg/alien(src) src.modules += new /obj/item/borg/sight/thermal/alien(src) var/obj/item/weapon/reagent_containers/spray/alien/stun/S = new /obj/item/weapon/reagent_containers/spray/alien/stun(src) S.reagents.add_reagent("stoxin",250) //nerfed to sleeptoxin to make it less instant drop. diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 6c4230439ea..a32e373fccd 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -33,3 +33,4 @@ spawn(40) if(client) handle_privacy_poll() + client.playtitlemusic() diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index a7f59cbecdf..e11a604b45e 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -19,7 +19,7 @@ charge_cost = 100 fire_sound = 'sound/weapons/Taser.ogg' user << "\red [src.name] is now set to stun." - projectile_type = "/obj/item/projectile/energy/electrode/revolver" + projectile_type = "/obj/item/projectile/energy/electrode" if(0) mode = 1 charge_cost = 100 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 06ae671bd87..6826924c6e5 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -232,3 +232,13 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. power_supply.give(5000) playsound(src.loc, 'sound/weapons/shotgunpump.ogg', 60, 1) return + + +/obj/item/weapon/gun/energy/disabler + name = "disabler" + desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." + icon_state = "disabler" + item_state = null + projectile_type = "/obj/item/projectile/energy/disabler" + cell_type = "/obj/item/weapon/cell" + charge_cost = 500 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 487ba361f9d..41e3764fdfe 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -6,7 +6,7 @@ item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/cell" + cell_type = "/obj/item/weapon/cell/crap" /obj/item/weapon/gun/energy/taser/cyborg name = "taser gun" @@ -29,7 +29,7 @@ /obj/item/weapon/gun/energy/taser/cyborg/process() //Every [recharge_time] ticks, recharge a shot for the cyborg return 1 - + /obj/item/weapon/gun/energy/taser/cyborg/process_chambered() if(in_chamber) return 1 @@ -46,9 +46,9 @@ name = "stun revolver" desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger." icon_state = "stunrevolver" - fire_sound = 'sound/weapons/Taser.ogg' + fire_sound = "sound/weapons/gunshot.ogg" origin_tech = "combat=3;materials=3;powerstorage=2" - projectile_type = "/obj/item/projectile/energy/electrode/revolver" + projectile_type = "/obj/item/projectile/energy/electrode" cell_type = "/obj/item/weapon/cell" @@ -77,10 +77,10 @@ /obj/item/weapon/gun/energy/crossbow/process() charge_tick++ - if(charge_tick < 4) + if(charge_tick < 4) return 0 charge_tick = 0 - if(!power_supply) + if(!power_supply) return 0 power_supply.give(1000) return 1 @@ -92,8 +92,8 @@ desc = "An energy-based crossbow that draws power from the cyborg's internal energy cell directly." /obj/item/weapon/gun/energy/crossbow/cyborg/process() - return 1 - + return 1 + /obj/item/weapon/gun/energy/crossbow/cyborg/process_chambered() if(in_chamber) return 1 diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 15e8b3af1fa..c5be6dcd6fa 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -10,13 +10,9 @@ name = "electrode" icon_state = "spark" nodamage = 1 - /* - stun = 10 - weaken = 10 - stutter = 10 - */ - agony = 40 - damage_type = HALLOSS + stun = 5 + weaken = 5 + stutter = 5 hitsound = 'sound/weapons/tase.ogg' //Damage will be handled on the MOB side, to prevent window shattering. @@ -74,3 +70,15 @@ damage = 20 damage_type = TOX irradiate = 20 + +/obj/item/projectile/energy/disabler + name = "disabler beam" + icon_state = "omnilaser" + damage = 34 + damage_type = HALLOSS + var/range = 8 + +/obj/item/projectile/energy/disabler/Range() + range-- + if(range <= 0) + del(src) \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 85ad55e083c..d9a69f652bd 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1602,7 +1602,7 @@ datum/design/mmi_radio category = "Misc" datum/design/synthetic_flash - name = "Synthetic Flash" + name = "Flash" desc = "When a problem arises, SCIENCE is the solution." id = "sflash" req_tech = list("magnets" = 3, "combat" = 2) diff --git a/code/setup.dm b/code/setup.dm index 8073c8c7648..227480126f7 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -698,7 +698,7 @@ var/list/TAGGERLOCATIONS = list("Disposals", #define SOUND_ADMINHELP 1 #define SOUND_MIDI 2 #define SOUND_AMBIENCE 4 -#define SOUND_LOBBY 8 //Removed, can be replaced with any other sound bitflag as needed. +#define SOUND_LOBBY 8 #define SOUND_STREAMING 16 #define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_STREAMING) diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 758e6dc1877..f206f2c013c 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ