From 3fa79f8d5195dbe128e12fe66a6ecf19bfa64959 Mon Sep 17 00:00:00 2001 From: Kelenius Date: Sat, 9 May 2015 17:27:19 +0300 Subject: [PATCH 01/94] Removes click cooldowns almost everywhere. Still have: doors, windoors, cameras, windows, grilles, blobs, resisting, alien stuff, mechas, spray bottles. Setting changeNextMove is now responsibility of the item being attacked. Adds a config option to eliminate click cooldowns completely. Intended to be used by devs. --- code/_onclick/ai.dm | 4 +- code/_onclick/click.dm | 99 +++++++------------ code/_onclick/cyborg.dm | 12 +-- code/_onclick/hud/screen_objects.dm | 11 +-- code/_onclick/item_attack.dm | 2 + code/_onclick/observer.dm | 4 +- code/_onclick/other_mobs.dm | 9 -- code/_onclick/telekinesis.dm | 20 ++-- code/controllers/configuration.dm | 4 + code/game/gamemodes/blob/theblob.dm | 1 + code/game/machinery/camera/camera.dm | 1 + code/game/machinery/deployable.dm | 1 + code/game/machinery/doors/door.dm | 1 + code/game/machinery/doors/windowdoor.dm | 1 + code/game/machinery/portable_turret.dm | 2 +- code/game/mecha/mecha.dm | 3 + code/game/objects/effects/aliens.dm | 3 + code/game/objects/items.dm | 1 - .../structures/crates_lockers/closets.dm | 7 +- code/game/objects/structures/grille.dm | 3 + code/game/objects/structures/window.dm | 3 + code/game/turfs/simulated/walls.dm | 2 + code/modules/mob/living/carbon/human/human.dm | 5 +- code/modules/mob/living/carbon/resist.dm | 23 ++--- code/modules/mob/living/living.dm | 6 +- .../simple_animal/borer/borer_captive.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 - code/modules/mob/mob.dm | 6 +- code/modules/mob/mob_grab.dm | 4 +- code/modules/projectiles/gun.dm | 4 +- .../projectiles/guns/launcher/rocket.dm | 2 +- .../reagents/reagent_containers/spray.dm | 2 + code/setup.dm | 4 - 33 files changed, 110 insertions(+), 144 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index e05cbeb9ba2..4dee15388de 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -15,7 +15,6 @@ return if(control_disabled || stat) return - next_move = world.time + 9 if(ismob(A)) ai_actual_track(A) @@ -52,9 +51,8 @@ CtrlClickOn(A) return - if(world.time <= next_move) + if(!canClick()) return - next_move = world.time + 9 if(aiCamera.in_camera_mode) aiCamera.camera_mode_off() diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b8caa45399d..5169676ad4a 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -4,7 +4,7 @@ */ // 1 decisecond click delay (above and beyond mob/next_move) -/mob/var/next_click = 0 +/mob/var/next_click = 0 /* Before anything else, defer these calls to a per-mobtype handler. This allows us to @@ -15,12 +15,14 @@ Note that this proc can be overridden, and is in the case of screen objects. */ -/atom/Click(location,control,params) + +/atom/Click(var/location, var/control, var/params) // This is their reaction to being clicked on (standard proc) if(src) usr.ClickOn(src, params) -/atom/DblClick(location,control,params) + +/atom/DblClick(var/location, var/control, var/params) if(src) - usr.DblClickOn(src,params) + usr.DblClickOn(src, params) /* Standard mob ClickOn() @@ -35,8 +37,8 @@ * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ -/mob/proc/ClickOn( var/atom/A, var/params ) - if(world.time <= next_click) +/mob/proc/ClickOn(var/atom/A, var/params) + if(world.time <= next_click) // Hard check, before anything else, to avoid crashing return next_click = world.time + 1 @@ -66,16 +68,17 @@ face_atom(A) // change direction to face what you clicked on - if(next_move > world.time) // in the year 2000... + if(!canClick()) // in the year 2000... return - if(istype(loc,/obj/mecha)) - if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled + if(istype(loc, /obj/mecha)) + if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled return var/obj/mecha/M = loc - return M.click_action(A,src) + return M.click_action(A, src) if(restrained()) + changeNextMove(10) RestrainedClickOn(A) return @@ -83,79 +86,65 @@ throw_item(A) return - if(!istype(A,/obj/item/weapon/gun) && !isturf(A) && !istype(A,/obj/screen)) + if(!istype(A, /obj/item/weapon/gun) && !isturf(A) && !istype(A, /obj/screen)) last_target_click = world.time var/obj/item/W = get_active_hand() - if(W == A) - next_move = world.time + 6 - if(W.flags&USEDELAY) - next_move += 5 + if(W == A) // Handle attack_self W.attack_self(src) if(hand) update_inv_l_hand(0) else update_inv_r_hand(0) - return - // operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src) - var/sdepth = A.storage_depth(src) - if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1)) - - // faster access to objects already on you - if(A in contents) - next_move = world.time + 6 // on your person - else - next_move = world.time + 8 // in a box/bag or in your square - - // No adjacency needed + // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); but not next to you and not in a box in a backpack on you + if(!isturf(A) && A == loc || (A in contents) || (A.loc in contents)) if(W) - if(W.flags&USEDELAY) - next_move += 5 - - var/resolved = A.attackby(W,src) + var/resolved = A.attackby(W, src) if(!resolved && A && W) - W.afterattack(A,src,1,params) // 1 indicates adjacency + W.afterattack(A, src, 1, params) // 1 indicates adjacency else + if(ismob(A)) // No instant mob attacking + changeNextMove(8) UnarmedAttack(A, 1) return if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that return - // Allows you to click on a box's contents, if that box is on the ground, but no deeper than that - sdepth = A.storage_depth_turf() - if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1)) - next_move = world.time + 10 - + // A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack) + if(isturf(A) || isturf(A.loc) || isturf(A.loc.loc)) if(A.Adjacent(src)) // see adjacent.dm if(W) - if(W.flags&USEDELAY) - next_move += 5 - - // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) - var/resolved = A.attackby(W,src) + var/resolved = A.attackby(W, src) // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) if(!resolved && A && W) - W.afterattack(A,src,1,params) // 1: clicking something Adjacent + W.afterattack(A, src, 1, params) // 1: clicking something Adjacent else + if(ismob(A)) // No instant mob attacking + changeNextMove(8) UnarmedAttack(A, 1) return else // non-adjacent click if(W) - W.afterattack(A,src,0,params) // 0: not Adjacent + W.afterattack(A, src, 0, params) // 0: not Adjacent else RangedAttack(A, params) return -/mob/proc/changeNext_move(num) +/mob/proc/changeNextMove(var/num) next_move = world.time + num -// Default behavior: ignore double clicks, consider them normal clicks instead +/mob/proc/canClick() + if(config.no_click_cooldown || next_move <= world.time) + return 1 + return 0 + +// Default behavior: ignore double clicks, the second click that makes the doubleclick call already calls for a normal click /mob/proc/DblClickOn(var/atom/A, var/params) - ClickOn(A,params) + return /* Translates into attack_hand, etc. @@ -198,17 +187,6 @@ if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(TK in mutations) - switch(get_dist(src,A)) - if(0) - ; - if(1 to 5) // not adjacent may mean blocked by window - next_move += 2 - if(5 to 7) - next_move += 5 - if(8 to tk_maxrange) - next_move += 10 - else - return A.attack_tk(src) /* Restrained ClickOn @@ -234,8 +212,7 @@ if(back) var/obj/item/weapon/rig/rig = back if(istype(rig) && rig.selected_module) - if(world.time <= next_move) return - next_move = world.time + 8 + if(!canClick()) return rig.selected_module.engage(A) return @@ -316,7 +293,7 @@ return /mob/living/LaserEyes(atom/A) - next_move = world.time + 6 + changeNextMove(4) var/turf/T = get_turf(src) var/turf/U = get_turf(A) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 59860116889..414071a964a 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -35,7 +35,7 @@ if(stat || lockcharge || weakened || stunned || paralysis) return - if(next_move >= world.time) + if(!canClick()) return face_atom(A) // change direction to face what you clicked on @@ -68,9 +68,6 @@ return if(W == A) - next_move = world.time + 8 - if(W.flags&USEDELAY) - next_move += 5 W.attack_self(src) return @@ -78,9 +75,6 @@ // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) if(A == loc || (A in loc) || (A in contents)) // No adjacency checks - next_move = world.time + 8 - if(W.flags&USEDELAY) - next_move += 5 var/resolved = A.attackby(W,src) if(!resolved && A && W) @@ -93,16 +87,12 @@ // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) if(isturf(A) || isturf(A.loc)) if(A.Adjacent(src)) // see adjacent.dm - next_move = world.time + 10 - if(W.flags&USEDELAY) - next_move += 5 var/resolved = A.attackby(W, src) if(!resolved && A && W) W.afterattack(A, src, 1, params) return else - next_move = world.time + 10 W.afterattack(A, src, 0, params) return return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 4a7d6f2acbe..03f97187c3e 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -48,9 +48,8 @@ /obj/screen/item_action/Click() if(!usr || !owner) return 1 - if(usr.next_move >= world.time) + if(!usr.canClick()) return - usr.next_move = world.time + 6 if(usr.stat || usr.restrained() || usr.stunned || usr.lying) return 1 @@ -85,7 +84,7 @@ name = "storage" /obj/screen/storage/Click() - if(world.time <= usr.next_move) + if(!usr.canClick()) return 1 if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) return 1 @@ -95,7 +94,6 @@ var/obj/item/I = usr.get_active_hand() if(I) usr.ClickOn(master) - usr.next_move = world.time+2 return 1 /obj/screen/gun @@ -481,7 +479,7 @@ /obj/screen/inventory/Click() // At this point in client Click() code we have passed the 1/10 sec check and little else // We don't even know if it's a middle click - if(world.time <= usr.next_move) + if(!usr.canClick()) return 1 if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) return 1 @@ -492,12 +490,10 @@ if(iscarbon(usr)) var/mob/living/carbon/C = usr C.activate_hand("r") - usr.next_move = world.time+2 if("l_hand") if(iscarbon(usr)) var/mob/living/carbon/C = usr C.activate_hand("l") - usr.next_move = world.time+2 if("swap") usr:swap_hand() if("hand") @@ -506,5 +502,4 @@ if(usr.attack_ui(slot_id)) usr.update_inv_l_hand(0) usr.update_inv_r_hand(0) - usr.next_move = world.time+6 return 1 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1d68fb54e8e..1b548c6596c 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -6,11 +6,13 @@ // No comment /atom/proc/attackby(obj/item/W, mob/user) return + /atom/movable/attackby(obj/item/W, mob/user) if(!(W.flags&NOBLUDGEON)) visible_message("[src] has been hit by [user] with [W].") /mob/living/attackby(obj/item/I, mob/user) + user.changeNextMove(8) if(istype(I) && ismob(user)) I.attack(src, user) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 168ae47c863..585949d4108 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -32,8 +32,8 @@ if(client.buildmode) build_click(src, client.buildmode, params, A) return - if(world.time <= next_move) return - next_move = world.time + 8 + if(!canClick()) return + changeNextMove(4) // You are responsible for checking config.ghost_interaction when you override this function // Not all of them require checking, see below A.attack_ghost(src) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 477fb04b7ad..f7726666519 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -38,15 +38,6 @@ return else if(TK in mutations) - switch(get_dist(src,A)) - if(1 to 5) // not adjacent may mean blocked by window - next_move += 2 - if(5 to 7) - next_move += 5 - if(8 to 15) - next_move += 10 - if(16 to 128) - return A.attack_tk(src) /mob/living/RestrainedClickOn(var/atom/A) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index ae57895cd6a..920db53fa66 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -108,20 +108,12 @@ var/const/tk_maxrange = 15 return var/d = get_dist(user, target) - if(focus) d = max(d,get_dist(user,focus)) // whichever is further - switch(d) - if(0) - ; - if(1 to 5) // not adjacent may mean blocked by window - if(!proximity) - user.next_move += 2 - if(5 to 7) - user.next_move += 5 - if(8 to tk_maxrange) - user.next_move += 10 - else - user << "\blue Your mind won't reach that far." - return + if(focus) + d = max(d,get_dist(user,focus)) // whichever is further + + if(d > tk_maxrange) + user << "Your mind won't reach that far." + return if(!focus) focus_object(target, user) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 171080fb32d..c99ed827861 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -126,6 +126,7 @@ var/list/gamemode_cache = list() var/welder_vision = 1 var/generate_asteroid = 0 + var/no_click_cooldown = 0 //Used for modifying movement speed for mobs. //Unversal modifiers @@ -316,6 +317,9 @@ var/list/gamemode_cache = list() if ("generate_asteroid") config.generate_asteroid = 1 + if ("no_click_cooldown") + config.no_click_cooldown = 1 + if("allow_admin_ooccolor") config.allow_admin_ooccolor = 1 diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 6e9c3d9b686..df3b8e5aee3 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -157,6 +157,7 @@ attackby(var/obj/item/weapon/W, var/mob/user) + user.changeNextMove(8) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) src.visible_message("The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") var/damage = 0 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 5670ef20603..e60b634ac95 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -187,6 +187,7 @@ src.bugged = 1 else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras + user.changeNextMove(8) if (W.force >= src.toughness) visible_message("[src] has been [pick(W.attack_verb)] with [W] by [user]!") if (istype(W, /obj/item)) //is it even possible to get into attackby() with non-items? diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index e49fb262836..7a5e2706c9c 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -80,6 +80,7 @@ for reference: return return else + user.changeNextMove(8) switch(W.damtype) if("fire") src.health -= W.force * 1 diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index e02be363f4e..7f87c651991 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -263,6 +263,7 @@ //psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them. if(src.density && istype(I, /obj/item/weapon) && user.a_intent == I_HURT && !istype(I, /obj/item/weapon/card)) var/obj/item/weapon/W = I + user.changeNextMove(8) if(W.damtype == BRUTE || W.damtype == BURN) if(W.force < min_force) user.visible_message("\red \The [user] hits \the [src] with \the [W] with no visible effect." ) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index b91270ad609..ae4ea0214e8 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -225,6 +225,7 @@ //If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway) if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card)) + user.changeNextMove(8) var/aforce = I.force playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) visible_message("\red [src] was hit by [I].") diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index a056cbc0f98..3e36f080c02 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -331,7 +331,7 @@ else //if the turret was attacked with the intention of harming it: - user.changeNext_move(NEXT_MOVE_DELAY) + user.changeNextMove(8) take_damage(I.force * 0.5) if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 479d55cb8b4..5cbc013f3bb 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -511,6 +511,7 @@ return /obj/mecha/attack_hand(mob/user as mob) + user.changeNextMove(8) src.log_message("Attack by hand/paw. Attacker - [user].",1) if(istype(user,/mob/living/carbon/human)) @@ -674,6 +675,7 @@ return /obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + user.changeNextMove(8) src.log_message("Attacked by [W]. Attacker - [user]") if(prob(src.deflect_chance)) user << "\red \The [W] bounces off [src.name]." @@ -1788,6 +1790,7 @@ /obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message) + user.changeNextMove(8) if(!damage) return 0 diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index e6b166792f7..93e578d55f5 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -103,6 +103,7 @@ return /obj/effect/alien/resin/attack_hand() + usr.changeNextMove(8) if (HULK in usr.mutations) usr << "\blue You easily destroy the [name]." for(var/mob/O in oviewers(src)) @@ -129,6 +130,7 @@ /obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob) + user.changeNextMove(8) var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) @@ -236,6 +238,7 @@ Alien plants should do something if theres a lot of poison return /obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user) + user.changeNextMove(8) if(W.attack_verb.len) visible_message("\red \The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") else diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 1c29aa80880..500979572ed 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -159,7 +159,6 @@ else if(isliving(src.loc)) return - user.next_move = max(user.next_move+2,world.time + 2) user.put_in_active_hand(src) if(src.loc == user) src.pickup(user) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 5e1a551cecf..d703608ea7e 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -325,9 +325,12 @@ if(!req_breakout()) return + if(!escapee.canClick()) + return + + escapee.changeNextMove(100) + //okay, so the closet is either welded or locked... resist!!! - escapee.next_move = world.time + 100 - escapee.last_special = world.time + 100 escapee << "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)" visible_message("The [src] begins to shake violently!") diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index b18658d4a6c..eced2855121 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -33,6 +33,7 @@ /obj/structure/grille/attack_hand(mob/user as mob) + user.changeNextMove(8) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) var/damage_dealt = 1 @@ -154,8 +155,10 @@ //window placing end else if(istype(W, /obj/item/weapon/shard)) + user.changeNextMove(8) health -= W.force * 0.1 else if(!shock(user, 70)) + user.changeNextMove(8) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) switch(W.damtype) if("fire") diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 36d5bcc657f..5ccd7efa21f 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -175,6 +175,7 @@ playsound(loc, 'sound/effects/Glasshit.ogg', 50, 1) /obj/structure/window/attack_hand(mob/user as mob) + user.changeNextMove(8) if(HULK in user.mutations) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) user.visible_message("[user] smashes through [src]!") @@ -200,6 +201,7 @@ return /obj/structure/window/attack_generic(var/mob/user, var/damage) + user.changeNextMove(8) if(!damage) return if(damage >= 10) @@ -268,6 +270,7 @@ new glasstype(loc) qdel(src) else + user.changeNextMove(8) if(W.damtype == BRUTE || W.damtype == BURN) hit(W.force) if(health <= 7) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index ef7dd74e8fb..2d8fe8ca2bb 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -272,6 +272,7 @@ //Interactions /turf/simulated/wall/attack_hand(mob/user as mob) + user.changeNextMove(8) if (HULK in user.mutations) if (prob(hulk_destroy_prob) || rotting) usr << text("\blue You smash through the wall.") @@ -298,6 +299,7 @@ return 0 /turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) + user.changeNextMove(8) if(!damage || !wallbreaker) user << "You push the wall but nothing happens." return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 498b46345d4..1b40b9fa008 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1311,9 +1311,10 @@ set desc = "Pop a joint back into place. Extremely painful." set src in view(1) - if(!isliving(usr) || usr.next_move > world.time) + if(!isliving(usr) || !usr.canClick()) return - usr.next_move = world.time + 20 + + usr.changeNextMove(20) if(usr.stat > 0) usr << "You are unconcious and cannot do that!" diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index 95ee36b1f6b..5724c11997f 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -27,10 +27,10 @@ ..() /mob/living/carbon/proc/escape_handcuffs() - if(!(last_special <= world.time)) return - - next_move = world.time + 100 - last_special = world.time + 100 + if(!canClick()) + return + + changeNextMove(100) if(can_break_cuffs()) //Don't want to do a lot of logic gating here. break_handcuffs() @@ -61,10 +61,10 @@ drop_from_inventory(handcuffed) /mob/living/carbon/proc/escape_legcuffs() - if(!(last_special <= world.time)) return - - next_move = world.time + 100 - last_special = world.time + 100 + if(!canClick()) + return + + changeNextMove(100) if(can_break_cuffs()) //Don't want to do a lot of logic gating here. break_legcuffs() @@ -149,14 +149,15 @@ return ..() /mob/living/carbon/escape_buckle() + if(!canClick()) + return + + changeNextMove(100) if(!buckled) return - if(!(last_special <= world.time)) return if(!restrained()) ..() else - next_move = world.time + 100 - last_special = world.time + 100 visible_message( "[usr] attempts to unbuckle themself!", "You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d723cb5556a..dc6923db6d1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -572,7 +572,7 @@ default behaviour is: set category = "IC" if(can_resist()) - next_move = world.time + 20 + changeNextMove(20) process_resist() /mob/living/proc/can_resist() @@ -580,7 +580,7 @@ default behaviour is: //so just check weakened instead. if(stat || weakened) return 0 - if(next_move > world.time) + if(!canClick()) return 0 return 1 @@ -605,7 +605,7 @@ default behaviour is: /mob/living/proc/escape_inventory(obj/item/weapon/holder/H) if(H != src.loc) return - + var/mob/M = H.loc //Get our mob holder (if any). if(istype(M)) diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm index c0b2999b2fe..e666f7ac716 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm @@ -35,7 +35,7 @@ return /mob/living/captive_brain/can_resist() - return !(stat || next_move > world.time) + return !(stat || !canClick()) /mob/living/captive_brain/process_resist() //Resisting control by an alien mind. diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 881cb2d76a8..74094fcbfdf 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -266,7 +266,6 @@ /mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/stack/medical)) - user.changeNext_move(4) if(stat != DEAD) var/obj/item/stack/medical/MED = O if(health < maxHealth) @@ -284,7 +283,6 @@ if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) harvest(user) else - user.changeNext_move(8) if(O.force > resistance) var/damage = O.force if (O.damtype == HALLOSS) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e9cae30755d..d31fe2c6f6b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -241,8 +241,6 @@ if (W) W.attack_self(src) update_inv_r_hand() - if(next_move < world.time) - next_move = world.time + 2 return /* @@ -945,9 +943,9 @@ mob/proc/yank_out_object() set desc = "Remove an embedded item at the cost of bleeding and pain." set src in view(1) - if(!isliving(usr) || usr.next_move > world.time) + if(!isliving(usr) || !usr.canClick()) return - usr.next_move = world.time + 20 + usr.changeNextMove(20) if(usr.stat == 1) usr << "You are unconcious and cannot do that!" diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 73c5ee1de7b..31e6ee65a0f 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -120,7 +120,7 @@ return if(state == GRAB_UPGRADING) return - if(assailant.next_move > world.time) + if(!assailant.canClick()) return if(world.time < (last_upgrade + UPGRADE_COOLDOWN)) return @@ -170,7 +170,7 @@ assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") - assailant.next_move = world.time + 10 + affecting.changeNextMove(10) affecting.losebreath += 1 else assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 2f17c0783d0..89cda207f3f 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -169,7 +169,7 @@ var/_move_delay = firemode.move_delay var/shoot_time = (_burst - 1)*_burst_delay - user.next_move = world.time + shoot_time //no clicking on things while shooting + user.changeNextMove(shoot_time) if(user.client) user.client.move_delay = world.time + shoot_time //no moving while shooting either next_fire_time = world.time + shoot_time @@ -202,7 +202,7 @@ update_held_icon() //update timing - user.next_move = world.time + 4 + user.changeNextMove(4) if(user.client) user.client.move_delay = world.time + _move_delay next_fire_time = world.time + _fire_delay diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm index fd86302fb8d..f468431bddf 100644 --- a/code/modules/projectiles/guns/launcher/rocket.dm +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -7,7 +7,7 @@ throw_speed = 2 throw_range = 10 force = 5.0 - flags = CONDUCT | USEDELAY + flags = CONDUCT slot_flags = 0 origin_tech = "combat=8;materials=5" fire_sound = 'sound/effects/bang.ogg' diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 2e929c6d12d..62e24b83e2c 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -50,6 +50,8 @@ playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) + user.changeNextMove(4) + if(reagents.has_reagent("sacid")) message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src].") log_game("[key_name(user)] fired sulphuric acid from \a [src].") diff --git a/code/setup.dm b/code/setup.dm index 68c2b94c754..3e2328f596d 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -190,12 +190,10 @@ // To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. #define NOBLUDGEON 2 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler. #define AIRTIGHT 4 // Functions with internals. -#define USEDELAY 8 // 1 second extra delay on use. (Can be used once every 2s) #define NOSHIELD 16 // Weapon not affected by shield. #define CONDUCT 32 // Conducts electricity. (metal etc.) #define ON_BORDER 64 // Item has priority to check when entering or leaving. #define NOBLOODY 512 // Used for items if they don't want to get a blood overlay. -#define NODELAY 8192 // 1 second attack-by delay skipped (Can be used once every 0.2s). Most objects have a 1s attack-by delay, which doesn't require a flag. //Use these flags to indicate if an item obscures the specified slots from view, whereas body_parts_covered seems to be used to indicate what body parts the item protects. #define GLASSESCOVERSEYES 256 @@ -865,8 +863,6 @@ var/list/be_special_flags = list( #define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL) -#define NEXT_MOVE_DELAY 8 - #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 #define DROPLIMB_BURN 2 From 027275a7cb4433c547363cb3de83c0f7d546c89b Mon Sep 17 00:00:00 2001 From: Kelenius Date: Sat, 9 May 2015 20:53:00 +0300 Subject: [PATCH 02/94] Re-adds click cooldowns to trays and vines --- code/modules/hydroponics/spreading/spreading.dm | 1 + code/modules/hydroponics/trays/tray.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 7edcca6303c..0a8857d1acb 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -221,6 +221,7 @@ /obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user) + user.changeNextMove(8) plant_controller.add_plant(src) if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel)) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index f8b7a82be4d..4e688ecc4c1 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -530,6 +530,7 @@ A.hydrotray_type = src.type qdel(src) else if(O.force && seed) + user.changeNextMove(8) user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") if(!dead) health -= O.force From 695392e1508947fbb3f7165ed60a2547bd2f4612 Mon Sep 17 00:00:00 2001 From: Kelenius Date: Sun, 10 May 2015 15:11:32 +0300 Subject: [PATCH 03/94] Fixes webbings and coats --- code/_onclick/click.dm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 5169676ad4a..0b453ff215c 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -99,8 +99,9 @@ update_inv_r_hand(0) return - // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); but not next to you and not in a box in a backpack on you - if(!isturf(A) && A == loc || (A in contents) || (A.loc in contents)) + // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because webbings and coat pockets are hacky + var/sdepth = A.storage_depth(src) + if(!isturf(A) && A == loc || (sdepth != -1 && sdepth <= 1)) if(W) var/resolved = A.attackby(W, src) if(!resolved && A && W) @@ -115,7 +116,8 @@ return // A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack) - if(isturf(A) || isturf(A.loc) || isturf(A.loc.loc)) + sdepth = A.storage_depth_turf() + if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1)) if(A.Adjacent(src)) // see adjacent.dm if(W) var/resolved = A.attackby(W, src) // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) From 4ae7cbce5ddd45131aafca547193ad4138a0c215 Mon Sep 17 00:00:00 2001 From: Vivalas Date: Sun, 21 Jun 2015 15:42:37 -0500 Subject: [PATCH 04/94] Re-adds the new uplink item --- .../objects/items/devices/uplink_items.dm | 6 +++++ .../items/weapons/storage/uplink_kits.dm | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm index 97655196222..6e4ef338b90 100644 --- a/code/game/objects/items/devices/uplink_items.dm +++ b/code/game/objects/items/devices/uplink_items.dm @@ -345,6 +345,12 @@ datum/uplink_item/dd_SortValue() ..() antag_roles = list(MODE_MERCENARY) +/datum/uplink_item/item/tools/money + name = "Operations Funding" + item_cost = 3 + path = /obj/item/weapon/storage/secure/briefcase/money + desc = "A briefcase with 10,000 untraceable thalers for funding your sneaky activities." + /*********** * Implants * ***********/ diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 6b3fdd04ae5..cb764342b7f 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -234,3 +234,26 @@ ..() new /obj/item/rig_module/electrowarfare_suite(src) new /obj/item/rig_module/voice(src) + + +/obj/item/weapon/storage/secure/briefcase/money + name = "Suspicious Briefcase" + desc = "An imposing briefcase that has an old reeking smell to it, and gives off an ominous aurora." + + + + +/obj/item/weapon/storage/secure/briefcase/money/New() + ..() + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + new /obj/item/weapon/spacecash/c1000(src) + + From cdc3c1f0d5b627aa7167b104f58af66926fec6f9 Mon Sep 17 00:00:00 2001 From: Vivalas Date: Sun, 21 Jun 2015 15:47:48 -0500 Subject: [PATCH 05/94] Update uplink_kits.dm --- code/game/objects/items/weapons/storage/uplink_kits.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index cb764342b7f..2fde00eb34e 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -238,7 +238,7 @@ /obj/item/weapon/storage/secure/briefcase/money name = "Suspicious Briefcase" - desc = "An imposing briefcase that has an old reeking smell to it, and gives off an ominous aurora." + desc = "An ominous briefcase that has the unmistakeable smell of old, stale, cigarette smoke, and gives those who look at it a bad feeling." From ec7f3c73bae0cb2170d1743195045e66caa3b3b9 Mon Sep 17 00:00:00 2001 From: Vivalas Date: Sun, 21 Jun 2015 16:20:49 -0500 Subject: [PATCH 06/94] Adds Changelog --- html/changelogs/Vivalas-Uplink.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/Vivalas-Uplink.yml diff --git a/html/changelogs/Vivalas-Uplink.yml b/html/changelogs/Vivalas-Uplink.yml new file mode 100644 index 00000000000..7be346cf6d7 --- /dev/null +++ b/html/changelogs/Vivalas-Uplink.yml @@ -0,0 +1,5 @@ +author: Vivalas +delete-after: True +changes: + - rscadd: "A new uplink item has been added! A briefcase full 'o thalla can now be bought by traitors for bribes and such!" + From 5a8e075fb23378b47e0f200e747bead09eb1728d Mon Sep 17 00:00:00 2001 From: Vivalas Date: Sun, 21 Jun 2015 16:21:51 -0500 Subject: [PATCH 07/94] Update uplink_kits.dm --- code/game/objects/items/weapons/storage/uplink_kits.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 2fde00eb34e..5b46e990f0b 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -237,7 +237,7 @@ /obj/item/weapon/storage/secure/briefcase/money - name = "Suspicious Briefcase" + name = "suspicious briefcase" desc = "An ominous briefcase that has the unmistakeable smell of old, stale, cigarette smoke, and gives those who look at it a bad feeling." From 32b95445e3810b8d78fb58c10d14cd30bcc7b333 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 28 Jun 2015 23:07:58 -0400 Subject: [PATCH 08/94] Gives changeNextMove() a better name, default define --- code/__defines/mobs.dm | 3 +++ code/_onclick/click.dm | 12 ++++++------ code/_onclick/item_attack.dm | 2 +- code/_onclick/observer.dm | 2 +- code/_onclick/rig.dm | 2 +- code/game/gamemodes/blob/theblob.dm | 2 +- code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/deployable.dm | 2 +- code/game/machinery/doors/door.dm | 2 +- code/game/machinery/doors/windowdoor.dm | 2 +- code/game/machinery/portable_turret.dm | 2 +- code/game/mecha/mecha.dm | 6 +++--- code/game/objects/effects/aliens.dm | 6 +++--- .../objects/structures/crates_lockers/closets.dm | 2 +- code/game/objects/structures/grille.dm | 4 ++-- code/game/objects/structures/window.dm | 6 +++--- code/game/turfs/simulated/wall_attacks.dm | 6 +++--- code/modules/hydroponics/spreading/spreading.dm | 2 +- code/modules/hydroponics/trays/tray.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/mob/living/carbon/resist.dm | 6 +++--- code/modules/mob/living/living.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 +- code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_grab.dm | 2 +- code/modules/projectiles/gun.dm | 4 ++-- code/modules/reagents/reagent_containers/spray.dm | 2 +- 27 files changed, 46 insertions(+), 43 deletions(-) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index d7874d2b049..bcecfa7d863 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -79,6 +79,9 @@ #define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR) #define APPEARANCE_ALL 511 +// Click cooldown +#define DEFAULT_ATTACK_COOLDOWN 8 //Default timeout for aggressive actions + #define MIN_SUPPLIED_LAW_NUMBER 15 #define MAX_SUPPLIED_LAW_NUMBER 50 \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 3218212dda0..a250b12e436 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -78,7 +78,7 @@ return M.click_action(A, src) if(restrained()) - changeNextMove(10) + setClickCooldown(10) RestrainedClickOn(A) return @@ -108,7 +108,7 @@ W.afterattack(A, src, 1, params) // 1 indicates adjacency else if(ismob(A)) // No instant mob attacking - changeNextMove(8) + setClickCooldown(DEFAULT_ATTACK_COOLDOWN) UnarmedAttack(A, 1) return @@ -126,7 +126,7 @@ W.afterattack(A, src, 1, params) // 1: clicking something Adjacent else if(ismob(A)) // No instant mob attacking - changeNextMove(8) + setClickCooldown(DEFAULT_ATTACK_COOLDOWN) UnarmedAttack(A, 1) return else // non-adjacent click @@ -137,8 +137,8 @@ return -/mob/proc/changeNextMove(var/num) - next_move = world.time + num +/mob/proc/setClickCooldown(var/timeout) + next_move = max(world.time + timeout, next_move) /mob/proc/canClick() if(config.no_click_cooldown || next_move <= world.time) @@ -285,7 +285,7 @@ return /mob/living/LaserEyes(atom/A) - changeNextMove(4) + setClickCooldown(4) var/turf/T = get_turf(src) var/turf/U = get_turf(A) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 977b4d2334e..0cca5569c25 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -12,7 +12,7 @@ visible_message("[src] has been hit by [user] with [W].") /mob/living/attackby(obj/item/I, mob/user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(istype(I) && ismob(user)) I.attack(src, user) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 4323747496d..324dcc234d9 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -33,7 +33,7 @@ build_click(src, client.buildmode, params, A) return if(!canClick()) return - changeNextMove(4) + setClickCooldown(4) // You are responsible for checking config.ghost_interaction when you override this function // Not all of them require checking, see below A.attack_ghost(src) diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm index 6087cf2c297..600d8c56193 100644 --- a/code/_onclick/rig.dm +++ b/code/_onclick/rig.dm @@ -55,7 +55,7 @@ if(istype(rig) && rig.selected_module) rig.selected_module.engage(A) if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns - changeNextMove(8) + setClickCooldown(DEFAULT_ATTACK_COOLDOWN) return 1 return 0 diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 2d8891bb0b7..123bb97a3fe 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -157,7 +157,7 @@ attackby(var/obj/item/weapon/W, var/mob/user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) src.visible_message("The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") var/damage = 0 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 649a11b60d3..a96e94eb0c2 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -190,7 +190,7 @@ src.bugged = 1 else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if (W.force >= src.toughness) user.do_attack_animation(src) visible_message("[src] has been [pick(W.attack_verb)] with [W] by [user]!") diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index cb77a513a45..bce1ac5b570 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -97,7 +97,7 @@ for reference: return return else - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) switch(W.damtype) if("fire") src.health -= W.force * 1 diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 4a246a93271..077bd4ff9b2 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -260,7 +260,7 @@ //psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them. if(src.density && istype(I, /obj/item/weapon) && user.a_intent == I_HURT && !istype(I, /obj/item/weapon/card)) var/obj/item/weapon/W = I - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(W.damtype == BRUTE || W.damtype == BURN) user.do_attack_animation(src) if(W.force < min_force) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 8b7094b7728..e50af2bcf0a 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -229,7 +229,7 @@ //If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway) if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card)) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) var/aforce = I.force playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) visible_message("[src] was hit by [I].") diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 655108cc3c2..04b4dffe3cf 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -322,7 +322,7 @@ else //if the turret was attacked with the intention of harming it: - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) take_damage(I.force * 0.5) if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index e1c898da18c..573ede3fb0f 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -505,7 +505,7 @@ return /obj/mecha/attack_hand(mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) src.log_message("Attack by hand/paw. Attacker - [user].",1) if(istype(user,/mob/living/carbon/human)) @@ -665,7 +665,7 @@ return /obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) src.log_message("Attacked by [W]. Attacker - [user]") if(prob(src.deflect_chance)) user << "\The [W] bounces off [src.name]." @@ -1685,7 +1685,7 @@ /obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(!damage) return 0 diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 58ac1ee3a68..27d29b3cd63 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -98,7 +98,7 @@ return /obj/effect/alien/resin/attack_hand() - usr.changeNextMove(8) + usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if (HULK in usr.mutations) usr << "You easily destroy the [name]." for(var/mob/O in oviewers(src)) @@ -125,7 +125,7 @@ /obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) @@ -233,7 +233,7 @@ Alien plants should do something if theres a lot of poison return /obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(W.attack_verb.len) visible_message("\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") else diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 84224bff4be..891f280520b 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -349,7 +349,7 @@ if(!escapee.canClick()) return - escapee.changeNextMove(100) + escapee.setClickCooldown(100) //okay, so the closet is either welded or locked... resist!!! escapee << "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)" diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 126aa6eac29..ff540c46ba7 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -30,7 +30,7 @@ /obj/structure/grille/attack_hand(mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) user.do_attack_animation(src) @@ -156,7 +156,7 @@ //window placing end else if(!(W.flags & CONDUCT) || !shock(user, 70)) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) switch(W.damtype) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 6a82e64f37d..8574054263a 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -171,7 +171,7 @@ playsound(loc, 'sound/effects/Glasshit.ogg', 50, 1) /obj/structure/window/attack_hand(mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(HULK in user.mutations) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!")) user.visible_message("[user] smashes through [src]!") @@ -199,7 +199,7 @@ return /obj/structure/window/attack_generic(var/mob/user, var/damage) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(!damage) return if(damage >= 10) @@ -269,7 +269,7 @@ new glasstype(loc) qdel(src) else - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(W.damtype == BRUTE || W.damtype == BURN) user.do_attack_animation(src) hit(W.force) diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 9ebd9cee87b..dc560612186 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -56,7 +56,7 @@ radiate() add_fingerprint(user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) var/rotting = (locate(/obj/effect/overlay/wallrot) in src) if (HULK in user.mutations) if (rotting || !prob(material.hardness)) @@ -70,7 +70,7 @@ /turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) radiate() - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) var/rotting = (locate(/obj/effect/overlay/wallrot) in src) if(!damage || !wallbreaker) try_touch(user, rotting) @@ -88,7 +88,7 @@ /turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if (!user.) user << "You don't have the dexterity to do this!" return diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index b50ac8c1f18..d9b477ba28f 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -234,7 +234,7 @@ /obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) plant_controller.add_plant(src) if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel)) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 7bfe605b455..b8a92cdff97 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -545,7 +545,7 @@ A.hydrotray_type = src.type qdel(src) else if(O.force && seed) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") if(!dead) health -= O.force diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 658e7d32845..8bc45588394 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1308,7 +1308,7 @@ if(!isliving(usr) || !usr.canClick()) return - usr.changeNextMove(20) + usr.setClickCooldown(20) if(usr.stat > 0) usr << "You are unconcious and cannot do that!" diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index 0b43a98058c..a5ad3f58450 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -31,7 +31,7 @@ //These two lines represent a significant buff to grabs... if(!canClick()) return - changeNextMove(100) + setClickCooldown(100) if(can_break_cuffs()) //Don't want to do a lot of logic gating here. break_handcuffs() @@ -65,7 +65,7 @@ if(!canClick()) return - changeNextMove(100) + setClickCooldown(100) if(can_break_cuffs()) //Don't want to do a lot of logic gating here. break_legcuffs() @@ -153,7 +153,7 @@ if(!canClick()) return - changeNextMove(100) + setClickCooldown(100) if(!buckled) return if(!restrained()) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fb85edd73bb..f8b199cb9dd 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -575,7 +575,7 @@ default behaviour is: set category = "IC" if(can_resist()) - changeNextMove(20) + setClickCooldown(20) process_resist() /mob/living/proc/can_resist() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c5035eb4477..875bb4c1cee 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -290,7 +290,7 @@ //TODO: refactor mob attackby(), attacked_by(), and friends. /mob/living/simple_animal/proc/attacked_with_item(var/obj/item/O, var/mob/user) - user.changeNextMove(8) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) if(!O.force) visible_message("[user] gently taps [src] with \the [O].") return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3acd11ae69a..f722bc31edf 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -843,7 +843,7 @@ mob/proc/yank_out_object() if(!isliving(usr) || !usr.canClick()) return - usr.changeNextMove(20) + usr.setClickCooldown(20) if(usr.stat == 1) usr << "You are unconcious and cannot do that!" diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index d25cd59925e..b5ba0a0c4ff 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -259,7 +259,7 @@ assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") - affecting.changeNextMove(10) + affecting.setClickCooldown(10) affecting.losebreath += 1 affecting.set_dir(WEST) adjust_position() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 7de74612f22..3c3af1f19d3 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -169,7 +169,7 @@ var/_move_delay = firemode.move_delay var/shoot_time = (_burst - 1)*_burst_delay - user.changeNextMove(shoot_time) + user.setClickCooldown(shoot_time) if(user.client) user.client.move_delay = world.time + shoot_time //no moving while shooting either next_fire_time = world.time + shoot_time @@ -202,7 +202,7 @@ update_held_icon() //update timing - user.changeNextMove(4) + user.setClickCooldown(4) if(user.client) user.client.move_delay = world.time + _move_delay next_fire_time = world.time + _fire_delay diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 8d9e8b9869b..b4dee5f366f 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -39,7 +39,7 @@ playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) - user.changeNextMove(4) + user.setClickCooldown(4) if(reagents.has_reagent("sacid")) message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src].") From 06000a69844e7a6e379d7d405a4f309896c78e98 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 28 Jun 2015 23:12:11 -0400 Subject: [PATCH 09/94] Adds setMoveCooldown() --- code/ZAS/Airflow.dm | 5 +++-- code/modules/mob/mob_movement.dm | 3 +++ code/modules/projectiles/gun.dm | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index 9f6451adf93..70c3c0651e1 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -116,8 +116,9 @@ obj/item/check_airflow_movable(n) if(!istype(loc, /turf)) break step_towards(src, src.airflow_dest) - if(ismob(src) && src:client) - src:client:move_delay = world.time + vsc.airflow_mob_slowdown + if(ismob(src)) + var/mob/M = src + M.setMoveCooldown(vsc.airflow_mob_slowdown) airflow_dest = null airflow_speed = 0 airflow_time = 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 8ba66ffe317..b37192ed762 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -10,6 +10,9 @@ return (!mover.density || !density || lying) return +/mob/setMoveCooldown(var/timeout) + if(client) + client.move_delay = max(world.time + timeout, client.move_delay) /client/North() ..() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 3c3af1f19d3..922e5debf44 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -170,7 +170,7 @@ var/shoot_time = (_burst - 1)*_burst_delay user.setClickCooldown(shoot_time) - if(user.client) user.client.move_delay = world.time + shoot_time //no moving while shooting either + user.setMoveCooldown(shoot_time) //no moving while shooting either next_fire_time = world.time + shoot_time //actually attempt to shoot @@ -203,7 +203,7 @@ //update timing user.setClickCooldown(4) - if(user.client) user.client.move_delay = world.time + _move_delay + user.setMoveCooldown(_move_delay) next_fire_time = world.time + _fire_delay if(muzzle_flash) From 92a3d3f9ae59ccecc4074acc2dd64da62614fb81 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Fri, 3 Jul 2015 09:46:02 +0200 Subject: [PATCH 10/94] An active AI core now provides camera coverage. --- baystation12.dme | 1 + code/_helpers/unsorted.dm | 5 ++- code/game/machinery/camera/camera.dm | 3 ++ code/modules/mob/freelook/ai/chunk.dm | 16 +++++++++ .../mob/freelook/ai/update_triggers.dm | 34 ++++++++++++++++--- code/modules/mob/freelook/eye.dm | 8 +++-- code/modules/mob/freelook/mask/chunk.dm | 17 ++++------ .../mob/living/silicon/ai/ai_movement.dm | 2 ++ 8 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 code/modules/mob/living/silicon/ai/ai_movement.dm diff --git a/baystation12.dme b/baystation12.dme index ba02f28f659..0e8eb3aaeb8 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1264,6 +1264,7 @@ #include "code\modules\mob\living\silicon\silicon.dm" #include "code\modules\mob\living\silicon\subystems.dm" #include "code\modules\mob\living\silicon\ai\ai.dm" +#include "code\modules\mob\living\silicon\ai\ai_movement.dm" #include "code\modules\mob\living\silicon\ai\death.dm" #include "code\modules\mob\living\silicon\ai\examine.dm" #include "code\modules\mob\living\silicon\ai\icons.dm" diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index e44a60ebc2b..94b23b2b162 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -579,10 +579,13 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl return toReturn //Step-towards method of determining whether one atom can see another. Similar to viewers() -/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. +/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldn't be arsed to do actual raycasting :I This is horribly inaccurate. var/turf/current = get_turf(source) var/turf/target_turf = get_turf(target) var/steps = 0 + + if(!current || !target_turf) + return 0 while(current != target_turf) if(steps > length) return 0 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 4be87495884..c5553d09b56 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -305,6 +305,9 @@ /obj/machinery/camera/proc/can_see() var/list/see = null var/turf/pos = get_turf(src) + if(!pos) + return list() + if(isXRay()) see = range(view_range, pos) else diff --git a/code/modules/mob/freelook/ai/chunk.dm b/code/modules/mob/freelook/ai/chunk.dm index 89a07bb465c..5d82f66d662 100644 --- a/code/modules/mob/freelook/ai/chunk.dm +++ b/code/modules/mob/freelook/ai/chunk.dm @@ -24,6 +24,10 @@ for(var/turf/t in c.can_see()) visible[t] = t + for(var/mob/living/silicon/ai/AI in living_mob_list) + for(var/turf/t in AI.seen_camera_turfs()) + visible[t] = t + // Create a new camera chunk, since the chunks are made as they are needed. /datum/chunk/camera/New(loc, x, y, z) @@ -31,3 +35,15 @@ if(c.can_use()) cameras += c ..() + +/mob/living/silicon/proc/provides_camera_vision() + return 0 + +/mob/living/silicon/ai/provides_camera_vision() + return stat != DEAD + +/mob/living/silicon/robot/provides_camera_vision() + return src.camera && src.camera.network.len + +/mob/living/silicon/ai/proc/seen_camera_turfs() + return seen_turfs_in_range(src, world.view) diff --git a/code/modules/mob/freelook/ai/update_triggers.dm b/code/modules/mob/freelook/ai/update_triggers.dm index 8a91d0540e6..f4fea0aa58f 100644 --- a/code/modules/mob/freelook/ai/update_triggers.dm +++ b/code/modules/mob/freelook/ai/update_triggers.dm @@ -4,13 +4,13 @@ // Update the portable camera everytime the Robot moves. // This might be laggy, comment it out if there are problems. -/mob/living/silicon/robot/var/updating = 0 +/mob/living/silicon/var/updating = 0 /mob/living/silicon/robot/Move() var/oldLoc = src.loc . = ..() if(.) - if(src.camera && src.camera.network.len) + if(provides_camera_vision()) if(!updating) updating = 1 spawn(BORG_CAMERA_BUFFER) @@ -18,6 +18,21 @@ cameranet.updatePortableCamera(src.camera) updating = 0 +/mob/living/silicon/AI/Move() + var/oldLoc = src.loc + . = ..() + if(.) + if(provides_camera_vision()) + if(!updating) + updating = 1 + spawn(BORG_CAMERA_BUFFER) + if(oldLoc != src.loc) + cameranet.updateVisibility(oldLoc, 0) + cameranet.updateVisibility(loc, 0) + updating = 0 + +#undef BORG_CAMERA_BUFFER + // CAMERA // An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not. @@ -42,8 +57,19 @@ update_coverage(1) /obj/machinery/camera/Destroy() - cameranet.cameras -= src clear_all_networks() + cameranet.cameras -= src ..() -#undef BORG_CAMERA_BUFFER +// Mobs +/mob/living/silicon/ai/rejuvenate() + var/was_dead = stat == DEAD + ..() + if(was_dead && stat != DEAD) + // Arise! + cameranet.updateVisibility(src, 0) + +/mob/living/silicon/ai/death(gibbed) + if(..()) + // If true, the mob went from living to dead (assuming everyone has been overriding as they should...) + cameranet.updateVisibility(src, 0) diff --git a/code/modules/mob/freelook/eye.dm b/code/modules/mob/freelook/eye.dm index fb2b04a4348..437b2979dcc 100644 --- a/code/modules/mob/freelook/eye.dm +++ b/code/modules/mob/freelook/eye.dm @@ -41,12 +41,15 @@ mob/eye/Destroy() updateallghostimages() ..() -// Movement code. Returns 0 to stop air movement from moving it. /mob/eye/Move(n, direct) if(owner == src) - EyeMove(n, direct) + return EyeMove(n, direct) return 0 +/mob/eye/airflow_hit(atom/A) + airflow_speed = 0 + airflow_dest = null + /mob/eye/examinate() set popup_menu = 0 set src = usr.contents @@ -110,3 +113,4 @@ mob/eye/Destroy() sprint = min(sprint + 0.5, max_sprint) else sprint = initial + return 1 diff --git a/code/modules/mob/freelook/mask/chunk.dm b/code/modules/mob/freelook/mask/chunk.dm index b0973951cc2..f98a9b936bb 100644 --- a/code/modules/mob/freelook/mask/chunk.dm +++ b/code/modules/mob/freelook/mask/chunk.dm @@ -11,27 +11,24 @@ /datum/chunk/cult/acquireVisibleTurfs(var/list/visible) for(var/mob/living/L in living_mob_list) - for(var/turf/t in L.seen_turfs()) + for(var/turf/t in L.seen_cult_turfs()) visible[t] = t -/mob/living/proc/seen_turfs() +/mob/living/proc/seen_cult_turfs() return seen_turfs_in_range(src, 3) -/mob/living/carbon/human/seen_turfs() - /*if(src.isSynthetic()) - return list()*/ - +/mob/living/carbon/human/seen_cult_turfs() if(mind in cult.current_antagonists) - return seen_turfs_in_range(src, client ? client.view : 7) + return seen_turfs_in_range(src, world.view) return ..() -/mob/living/silicon/seen_turfs() +/mob/living/silicon/seen_cult_turfs() return list() -/mob/living/simple_animal/seen_turfs() +/mob/living/simple_animal/seen_cult_turfs() return seen_turfs_in_range(src, 1) -/mob/living/simple_animal/shade/narsie/seen_turfs() +/mob/living/simple_animal/shade/narsie/seen_cult_turfs() return view(2, src) /proc/seen_turfs_in_range(var/source, var/range) diff --git a/code/modules/mob/living/silicon/ai/ai_movement.dm b/code/modules/mob/living/silicon/ai/ai_movement.dm new file mode 100644 index 00000000000..456d11a9817 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/ai_movement.dm @@ -0,0 +1,2 @@ +/mob/living/silicon/ai/SelfMove(turf/n, direct) + return 0 From 06466abdb5101b715a496f426626ca890e50d15a Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Fri, 3 Jul 2015 09:48:21 +0200 Subject: [PATCH 11/94] Changelog entry. --- html/changelogs/PsiOmegaDelta-AISight.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/PsiOmegaDelta-AISight.yml diff --git a/html/changelogs/PsiOmegaDelta-AISight.yml b/html/changelogs/PsiOmegaDelta-AISight.yml new file mode 100644 index 00000000000..329cda695d7 --- /dev/null +++ b/html/changelogs/PsiOmegaDelta-AISight.yml @@ -0,0 +1,5 @@ +author: PsiOmegaDelta +delete-after: True + +changes: + - tweak: "Active AI cores now provides coverage on the AI camera network. Does not utilize actual cameras, thus will not show up on security consoles." From 94685082268d69ec2981a7ac2dcc5bb16d4a852c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 5 Jul 2015 12:51:55 -0400 Subject: [PATCH 12/94] Adds move cooldown for inventory management, clicking on adjacent atoms --- code/_onclick/click.dm | 23 +++++++++++++++++++++-- code/modules/mob/mob_movement.dm | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index a250b12e436..763ee91f8da 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -99,9 +99,16 @@ update_inv_r_hand(0) return - // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because webbings and coat pockets are hacky + //Atoms on your person + // A is your location but is not a turf; or is on you (backpack); or is on something on you (box in backpack); sdepth is needed here because contents depth does not equate inventory storage depth. var/sdepth = A.storage_depth(src) - if(!isturf(A) && A == loc || (sdepth != -1 && sdepth <= 1)) + if((!isturf(A) && A == loc) || (sdepth != -1 && sdepth <= 1)) + // faster access to objects already on you + if(A in contents) + setMoveCooldown(5) //taking an item off of an inventory slot + else + setMoveCooldown(10) //getting something out of a backpack + if(W) var/resolved = W.resolve_attackby(A, src) if(!resolved && A && W) @@ -115,10 +122,13 @@ if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that return + //Atoms on turfs (not on your person) // A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack) sdepth = A.storage_depth_turf() if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1)) if(A.Adjacent(src)) // see adjacent.dm + setMoveCooldown(10) + if(W) // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) var/resolved = W.resolve_attackby(A,src) @@ -190,6 +200,15 @@ if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(TK in mutations) + switch(get_dist(src,A)) + if(1 to 5) // not adjacent may mean blocked by window + setMoveCooldown(2) + if(5 to 7) + setMoveCooldown(5) + if(8 to tk_maxrange) + setMoveCooldown(10) + else + return A.attack_tk(src) /* Restrained ClickOn diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index b37192ed762..7da4f731e8b 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -10,7 +10,7 @@ return (!mover.density || !density || lying) return -/mob/setMoveCooldown(var/timeout) +/mob/proc/setMoveCooldown(var/timeout) if(client) client.move_delay = max(world.time + timeout, client.move_delay) From 0adebcb2bfd24198ff8509fab92507e3d0c8057f Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Sun, 5 Jul 2015 20:53:33 +0200 Subject: [PATCH 13/94] Admin secrets refactor. Turns the entries in the secret admin secrets panel into datums, which will make it much easier to add, edit, and remove new entries. This initial commit only contains an initial proof of concept entry implementation and the supporting code. Next commit will contain all relevant entries. --- baystation12.dme | 2 + code/modules/admin/admin.dm | 114 +--- code/modules/admin/admin_secrets.dm | 66 +++ code/modules/admin/secrets/gravity.dm | 29 + code/modules/admin/topic.dm | 736 +------------------------- 5 files changed, 111 insertions(+), 836 deletions(-) create mode 100644 code/modules/admin/admin_secrets.dm create mode 100644 code/modules/admin/secrets/gravity.dm diff --git a/baystation12.dme b/baystation12.dme index ba02f28f659..7bc13ae072f 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -828,6 +828,7 @@ #include "code\modules\admin\admin_investigate.dm" #include "code\modules\admin\admin_memo.dm" #include "code\modules\admin\admin_ranks.dm" +#include "code\modules\admin\admin_secrets.dm" #include "code\modules\admin\admin_verbs.dm" #include "code\modules\admin\banjob.dm" #include "code\modules\admin\create_mob.dm" @@ -842,6 +843,7 @@ #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" +#include "code\modules\admin\secrets\gravity.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 447178ecb30..dba65192968 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -604,109 +604,17 @@ proc/admin_notice(var/message, var/rights) if(!check_rights(0)) return var/dat = "The first rule of adminbuse is: you don't talk about the adminbuse.
" - - if(check_rights(R_ADMIN,0)) - dat += {" - Admin Secrets
-
- Bombing List
- Show current traitors and objectives
- Show last [length(lastsignalers)] signalers
- Show last [length(lawchanges)] law changes
- Show AI Laws
- Show Game Mode
- Show Crew Manifest
- List DNA (Blood)
- List Fingerprints

-
- "} - - if(check_rights(R_FUN,0)) - dat += {" - 'Random' Events
-
- Toggle station artificial gravity
- Spawn a wave of meteors (aka lagocolyptic shower)
- Spawn a gravitational anomaly (aka lagitational anomolag)
- Spawn wormholes
- Spawn blob
- Trigger a Xenomorph infestation
- Trigger a Cortical Borer infestation
- Spawn an Alien silently
- Trigger a Spider infestation
- Send in a space ninja
- Send in a strike team
- Trigger an Carp migration
- Irradiate the station
- Trigger a Prison Break
- Trigger a Virus Outbreak
- Spawn an Immovable Rod
- Toggle a "lights out" event
- Spawn an Ion Storm
- Spawn Space-Vines
- Trigger a communication blackout
-
- Fun Secrets
-
- Remove 'internal' clothing
- Remove ALL clothing
- Turn all humans into monkeys
- Remove firesuits, grilles, and pods
- Make all areas powered
- Make all areas unpowered
- Power all SMES
- Toggle Prison Shuttle Status(Use with S/R)
- Send Prison Shuttle
- Return Prison Shuttle
- Warp all Players to Prison
- Triple AI mode (needs to be used in the lobby)
- Everyone is the traitor
- There can only be one!
- Ghost Mode
- Make all players retarded
- Make all items look like guns
- Paintball Mode
- Japanese Animes Mode
- Egalitarian Station Mode
- Launch a shuttle
- Force launch a shuttle
- Jump a shuttle
- Move a shuttle
- Break all lights
- Fix all lights
- Best Friend AI
- The floor is lava! (DANGEROUS: extremely lame)
- "} - - if(check_rights(R_SERVER,0)) - dat += "Toggle bomb cap
" - - if(check_rights(R_SERVER|R_FUN,0)) - dat += {" -
- Final Solutions
- (Warning, these will end the round!)
-
- Summon Nar-Sie
- Start a Supermatter Cascade
- "} - - dat += "
" - - if(check_rights(R_DEBUG,0)) - dat += {" - Security Level Elevated
-
- Change all maintenance doors to engie/brig access only
- Change all maintenance doors to brig access only
- Remove cap on security officers
-
- Coder Secrets
-
- Show Job Debug
- Admin Log
-
- "} + for(var/datum/admin_secret_category/category in admin_secrets.categories) + if(!category.can_view(usr)) + continue + dat += "[category.name]
" + if(category.desc) + dat += "[category.desc]
" + dat += "
" + for(var/datum/admin_secret_item/item in category.items) + if(!item.can_execute(usr)) + continue + dat += "[item.name]
" usr << browse(dat, "window=secrets") return diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm new file mode 100644 index 00000000000..87c04ea625f --- /dev/null +++ b/code/modules/admin/admin_secrets.dm @@ -0,0 +1,66 @@ +var/datum/admin_secrets/admin_secrets = new() + +/datum/admin_secrets + var/list/datum/admin_secret_category/categories + var/list/datum/admin_secret_item/items + +/datum/admin_secrets/New() + ..() + categories = init_subtypes(/datum/admin_secret_category) + items = list() + var/list/category_assoc = list() + for(var/datum/category in categories) + category_assoc[category.type] = category + + for(var/item_type in (typesof(/datum/admin_secret_item) - /datum/admin_secret_item)) + var/datum/admin_secret_item/secret_item = item_type + if(!initial(secret_item.name)) + continue + + var/datum/admin_secret_item/item = new item_type() + var/datum/admin_secret_category/category = category_assoc[item.category] + category.items += item + items += item + +/datum/admin_secret_category + var/name = "" + var/desc = "" + var/list/datum/admin_secret_item/items + +/datum/admin_secret_category + ..() + items = list() + +/datum/admin_secret_category/proc/can_view(var/mob/user) + for(var/datum/admin_secret_item/item in items) + if(item.can_execute(user)) + return 1 + return 0 + +/datum/admin_secret_item + var/name = "" + var/category = null + var/permissions = R_HOST + +/datum/admin_secret_item/proc/can_execute(var/mob/user) + return check_rights(permissions, 0, user) + +/datum/admin_secret_item/proc/execute(var/mob/user) + if(!can_execute(user)) + return 0 + + log_admin("[key_name(user)] used secret [name]") + return 1 + +/************************* +* Pre-defined categories * +*************************/ +/datum/admin_secret_category/random_events + name = "'Random' Events" + +/************************* +* Pre-defined base items * +*************************/ +/datum/admin_secret_item/random_event + category = /datum/admin_secret_category/random_events + permissions = R_FUN diff --git a/code/modules/admin/secrets/gravity.dm b/code/modules/admin/secrets/gravity.dm new file mode 100644 index 00000000000..8ff9c915d43 --- /dev/null +++ b/code/modules/admin/secrets/gravity.dm @@ -0,0 +1,29 @@ +/********** +* Gravity * +**********/ +/datum/admin_secret_item/random_event/gravity + name = "Toggle station artificial gravity" + +/datum/admin_secret_item/random_event/gravity/execute(var/mob/user) + . = ..() + if(!.) + return + + if(!(ticker && ticker.mode)) + user << "Please wait until the game starts! Not sure how it will work otherwise." + return + + gravity_is_on = !gravity_is_on + for(var/area/A in world) + A.gravitychange(gravity_is_on,A) + + feedback_inc("admin_secrets_fun_used",1) + feedback_add_details("admin_secrets_fun_used","Grav") + if(gravity_is_on) + log_admin("[key_name(usr)] toggled gravity on.", 1) + message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) + command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") + else + log_admin("[key_name(usr)] toggled gravity off.", 1) + message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) + command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index e681c9ba95f..7f46170b5ea 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1645,739 +1645,9 @@ break return - else if(href_list["secretsfun"]) - if(!check_rights(R_FUN)) return - - var/ok = 0 - switch(href_list["secretsfun"]) - if("sec_clothes") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SC") - for(var/obj/item/clothing/under/O in world) - qdel(O) - ok = 1 - if("sec_all_clothes") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SAC") - for(var/obj/item/clothing/O in world) - qdel(O) - ok = 1 - if("sec_classic1") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SC1") - for(var/obj/item/clothing/suit/fire/O in world) - qdel(O) - for(var/obj/structure/grille/O in world) - qdel(O) -/* for(var/obj/machinery/vehicle/pod/O in world) - for(var/mob/M in src) - M.loc = src.loc - if (M.client) - M.client.perspective = MOB_PERSPECTIVE - M.client.eye = M - qdel(O) - ok = 1*/ - if("monkey") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","M") - for(var/mob/living/carbon/human/H in mob_list) - spawn(0) - H.monkeyize() - ok = 1 - if("corgi") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","M") - for(var/mob/living/carbon/human/H in mob_list) - spawn(0) - H.corgize() - ok = 1 - if("striketeam") - if(usr.client.strike_team()) - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Strike") - if("tripleAI") - usr.client.triple_ai() - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","TriAI") - if("gravity") - if(!(ticker && ticker.mode)) - usr << "Please wait until the game starts! Not sure how it will work otherwise." - return - gravity_is_on = !gravity_is_on - for(var/area/A in world) - A.gravitychange(gravity_is_on,A) - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Grav") - if(gravity_is_on) - log_admin("[key_name(usr)] toggled gravity on.", 1) - message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) - command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") - else - log_admin("[key_name(usr)] toggled gravity off.", 1) - message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) - command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") - if("wave") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Meteor") - log_admin("[key_name(usr)] spawned a meteor wave", 1) - message_admins("\blue [key_name_admin(usr)] spawned a meteor wave.", 1) - new /datum/event/meteor_wave - if("goblob") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Blob") - log_admin("[key_name(usr)] spawned a blob", 1) - message_admins("\blue [key_name_admin(usr)] spawned a blob.", 1) - new /datum/event/blob - - if("aliens") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Aliens") - log_admin("[key_name(usr)] spawned an alien infestation", 1) - message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1) - xenomorphs.attempt_random_spawn() - if("borers") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","Borers") - log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1) - message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1) - borers.attempt_random_spawn() - - if("power") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","P") - log_admin("[key_name(usr)] made all areas powered", 1) - message_admins("\blue [key_name_admin(usr)] made all areas powered", 1) - power_restore() - if("unpower") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","UP") - log_admin("[key_name(usr)] made all areas unpowered", 1) - message_admins("\blue [key_name_admin(usr)] made all areas unpowered", 1) - power_failure() - if("quickpower") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","QP") - log_admin("[key_name(usr)] made all SMESs powered", 1) - message_admins("\blue [key_name_admin(usr)] made all SMESs powered", 1) - power_restore_quick() - if("activateprison") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","AP") - world << "\blue Transit signature detected." - world << "\blue Incoming shuttle." - /* - var/A = locate(/area/shuttle_prison) - for(var/atom/movable/AM as mob|obj in A) - AM.z = 1 - AM.Move() - */ - message_admins("\blue [key_name_admin(usr)] sent the prison shuttle to the station.", 1) - if("deactivateprison") - /* - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","DP") - var/A = locate(/area/shuttle_prison) - for(var/atom/movable/AM as mob|obj in A) - AM.z = 2 - AM.Move() - */ - message_admins("\blue [key_name_admin(usr)] sent the prison shuttle back.", 1) - if("toggleprisonstatus") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","TPS") - for(var/obj/machinery/computer/prison_shuttle/PS in world) - PS.allowedtocall = !(PS.allowedtocall) - message_admins("\blue [key_name_admin(usr)] toggled status of prison shuttle to [PS.allowedtocall].", 1) - if("prisonwarp") - if(!ticker) - alert("The game hasn't started yet!", null, null, null, null, null) - return - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","PW") - message_admins("\blue [key_name_admin(usr)] teleported all players to the prison station.", 1) - for(var/mob/living/carbon/human/H in mob_list) - var/turf/loc = find_loc(H) - var/security = 0 - if(loc.z > 1 || prisonwarped.Find(H)) -//don't warp them if they aren't ready or are already there - continue - H.Paralyse(5) - if(H.wear_id) - var/obj/item/weapon/card/id/id = H.get_idcard() - for(var/A in id.access) - if(A == access_security) - security++ - if(!security) - //strip their stuff before they teleport into a cell :downs: - for(var/obj/item/weapon/W in H) - if(istype(W, /obj/item/organ/external)) - continue - //don't strip organs - H.drop_from_inventory(W) - //teleport person to cell - H.loc = pick(prisonwarp) - H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), slot_shoes) - else - //teleport security person - H.loc = pick(prisonsecuritywarp) - prisonwarped += H - if("launchshuttle") - if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created. - - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","ShL") - - var/list/valid_shuttles = list() - for (var/shuttle_tag in shuttle_controller.shuttles) - if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) - valid_shuttles += shuttle_tag - - var/shuttle_tag = input("Which shuttle do you want to launch?") as null|anything in valid_shuttles - - if (!shuttle_tag) - return - - var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] - if (S.can_launch()) - S.launch(usr) - message_admins("\blue [key_name_admin(usr)] launched the [shuttle_tag] shuttle", 1) - log_admin("[key_name(usr)] launched the [shuttle_tag] shuttle") - else - alert("The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.") - - if("forcelaunchshuttle") - if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created. - - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","ShFL") - - var/list/valid_shuttles = list() - for (var/shuttle_tag in shuttle_controller.shuttles) - if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) - valid_shuttles += shuttle_tag - - var/shuttle_tag = input("Which shuttle's launch do you want to force?") as null|anything in valid_shuttles - - if (!shuttle_tag) - return - - var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] - if (S.can_force()) - S.force_launch(usr) - message_admins("\blue [key_name_admin(usr)] has forced the [shuttle_tag] shuttle launch", 1) - log_admin("[key_name(usr)] has forced the [shuttle_tag] shuttle launch") - else - alert("The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.") - - if("jumpshuttle") - if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created. - - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","ShJ") - - var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles - if (!shuttle_tag) return - - var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] - - var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world - if (!origin_area) return - - var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world - if (!destination_area) return - - var/long_jump = alert("Is there a transition area for this jump?","", "Yes", "No") - if (long_jump == "Yes") - var/transition_area = input("Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world - if (!transition_area) return - - var/move_duration = input("How many seconds will this jump take?") as num - - S.long_jump(origin_area, destination_area, transition_area, move_duration) - message_admins("\blue [key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle", 1) - log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle") - else - S.short_jump(origin_area, destination_area) - message_admins("\blue [key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle", 1) - log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle") - - if("moveshuttle") - - if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created. - - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","ShM") - - var/confirm = alert("This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", "Ok", "Cancel") - if (confirm == "Cancel") - return - - var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles - if (!shuttle_tag) return - - var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] - - var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world - if (!origin_area) return - - var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world - if (!destination_area) return - - S.move(origin_area, destination_area) - message_admins("\blue [key_name_admin(usr)] moved the [shuttle_tag] shuttle", 1) - log_admin("[key_name(usr)] moved the [shuttle_tag] shuttle") - - if("togglebombcap") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","BC") - switch(max_explosion_range) - if(14) max_explosion_range = 16 - if(16) max_explosion_range = 20 - if(20) max_explosion_range = 28 - if(28) max_explosion_range = 56 - if(56) max_explosion_range = 128 - if(128) max_explosion_range = 14 - var/range_dev = max_explosion_range *0.25 - var/range_high = max_explosion_range *0.5 - var/range_low = max_explosion_range - message_admins("\red [key_name_admin(usr)] changed the bomb cap to [range_dev], [range_high], [range_low]", 1) - log_admin("[key_name_admin(usr)] changed the bomb cap to [max_explosion_range]") - - if("flicklights") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","FL") - while(!usr.stat) -//knock yourself out to stop the ghosts - for(var/mob/M in player_list) - if(M.stat != 2 && prob(25)) - var/area/AffectedArea = get_area(M) - if(AffectedArea.name != "Space" && AffectedArea.name != "Engine Walls" && AffectedArea.name != "Chemical Lab Test Chamber" && AffectedArea.name != "Escape Shuttle" && AffectedArea.name != "Arrival Area" && AffectedArea.name != "Arrival Shuttle" && AffectedArea.name != "start area" && AffectedArea.name != "Engine Combustion Chamber") - AffectedArea.power_light = 0 - AffectedArea.power_change() - spawn(rand(55,185)) - AffectedArea.power_light = 1 - AffectedArea.power_change() - var/Message = rand(1,4) - switch(Message) - if(1) - M.show_message(text("\blue You shudder as if cold..."), 1) - if(2) - M.show_message(text("\blue You feel something gliding across your back..."), 1) - if(3) - M.show_message(text("\blue Your eyes twitch, you feel like something you can't see is here..."), 1) - if(4) - M.show_message(text("\blue You notice something moving out of the corner of your eye, but nothing is there..."), 1) - for(var/obj/W in orange(5,M)) - if(prob(25) && !W.anchored) - step_rand(W) - sleep(rand(100,1000)) - for(var/mob/M in player_list) - if(M.stat != 2) - M.show_message(text("\blue The chilling wind suddenly stops..."), 1) -/* if("shockwave") - ok = 1 - world << "\red ALERT: STATION STRESS CRITICAL" - sleep(60) - world << "\red ALERT: STATION STRESS CRITICAL. TOLERABLE LEVELS EXCEEDED!" - sleep(80) - world << "\red ALERT: STATION STRUCTURAL STRESS CRITICAL. SAFETY MECHANISMS FAILED!" - sleep(40) - for(var/mob/M in world) - shake_camera(M, 400, 1) - for(var/obj/structure/window/W in world) - spawn(0) - sleep(rand(10,400)) - W.ex_act(rand(2,1)) - for(var/obj/structure/grille/G in world) - spawn(0) - sleep(rand(20,400)) - G.ex_act(rand(2,1)) - for(var/obj/machinery/door/D in world) - spawn(0) - sleep(rand(20,400)) - D.ex_act(rand(2,1)) - for(var/turf/station/floor/Floor in world) - spawn(0) - sleep(rand(30,400)) - Floor.ex_act(rand(2,1)) - for(var/obj/structure/cable/Cable in world) - spawn(0) - sleep(rand(30,400)) - Cable.ex_act(rand(2,1)) - for(var/obj/structure/closet/Closet in world) - spawn(0) - sleep(rand(30,400)) - Closet.ex_act(rand(2,1)) - for(var/obj/machinery/Machinery in world) - spawn(0) - sleep(rand(30,400)) - Machinery.ex_act(rand(1,3)) - for(var/turf/station/wall/Wall in world) - spawn(0) - sleep(rand(30,400)) - Wall.ex_act(rand(2,1)) */ - if("wave") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","MW") - new /datum/event/meteor_wave - - if("gravanomalies") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","GA") - command_announcement.Announce("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/AI/granomalies.ogg') - var/turf/T = pick(blobstart) - var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) - spawn(rand(100, 600)) - qdel(bh) - - if("timeanomalies") //dear god this code was awful :P Still needs further optimisation - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","STA") - //moved to its own dm so I could split it up and prevent the spawns copying variables over and over - //can be found in code\game\game_modes\events\wormholes.dm - wormhole_event() - - if("goblob") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","BL") - mini_blob_event() - message_admins("[key_name_admin(usr)] has spawned blob", 1) - if("aliens") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","AL") - if(xenomorphs.attempt_random_spawn()) - message_admins("[key_name_admin(usr)] has spawned aliens", 1) - if("spiders") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SL") - new /datum/event/spider_infestation - message_admins("[key_name_admin(usr)] has spawned spiders", 1) - if("comms_blackout") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","CB") - var/answer = alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No") - if(answer == "Yes") - communications_blackout(0) - else - communications_blackout(1) - message_admins("[key_name_admin(usr)] triggered a communications blackout.", 1) - if("carp") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","C") - var/choice = input("You sure you want to spawn carp?") in list("Badmin", "Cancel") - if(choice == "Badmin") - message_admins("[key_name_admin(usr)] has spawned carp.", 1) - new /datum/event/carp_migration - if("radiation") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","R") - message_admins("[key_name_admin(usr)] has has irradiated the station", 1) - new /datum/event/radiation_storm - if("immovable") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","IR") - message_admins("[key_name_admin(usr)] has sent an immovable rod to the station", 1) - immovablerod() - if("prison_break") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","PB") - message_admins("[key_name_admin(usr)] has allowed a prison break", 1) - prison_break() - if("lightout") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","LO") - message_admins("[key_name_admin(usr)] has broke a lot of lights", 1) - lightsout(1,2) - if("blackout") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","BO") - message_admins("[key_name_admin(usr)] broke all lights", 1) - lightsout(0,0) - if("whiteout") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","WO") - for(var/obj/machinery/light/L in world) - L.fix() - message_admins("[key_name_admin(usr)] fixed all lights", 1) - if("friendai") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","FA") - for(var/mob/aiEye/aE in mob_list) - aE.icon_state = "ai_friend" - for(var/obj/machinery/M in machines) - if(istype(M, /obj/machinery/ai_status_display)) - var/obj/machinery/ai_status_display/A = M - A.emotion = "Friend Computer" - else if(istype(M, /obj/machinery/status_display)) - var/obj/machinery/status_display/A = M - A.friendc = 1 - message_admins("[key_name_admin(usr)] turned all AIs into best friends.", 1) - if("floorlava") - if(floorIsLava) - usr << "The floor is lava already." - return - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","LF") - - //Options - var/length = input(usr, "How long will the lava last? (in seconds)", "Length", 180) as num - length = min(abs(length), 1200) - - var/damage = input(usr, "How deadly will the lava be?", "Damage", 2) as num - damage = min(abs(damage), 100) - - var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "YES!", "Nah") - if(sure == "Nah") - return - floorIsLava = 1 - - message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.", 1) - - for(var/turf/simulated/floor/F in world) - if(F.z in config.station_levels) - F.name = "lava" - F.desc = "The floor is LAVA!" - F.overlays += "lava" - F.lava = 1 - - spawn(0) - for(var/i = i, i < length, i++) // 180 = 3 minutes - if(damage) - for(var/mob/living/carbon/L in living_mob_list) - if(istype(L.loc, /turf/simulated/floor)) // Are they on LAVA?! - var/turf/simulated/floor/F = L.loc - if(F.lava) - var/safe = 0 - for(var/obj/structure/O in F.contents) - if(O.level > F.level && !istype(O, /obj/structure/window)) // Something to stand on and it isn't under the floor! - safe = 1 - break - if(!safe) - L.adjustFireLoss(damage) - - - sleep(10) - - for(var/turf/simulated/floor/F in world) // Reset everything. - if(F.z in config.station_levels) - F.name = initial(F.name) - F.desc = initial(F.desc) - F.overlays.Cut() - F.lava = 0 - F.update_icon() - floorIsLava = 0 - return - if("virus") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","V") - var/answer = alert("Do you want this to be a greater disease or a lesser one?",,"Greater","Lesser") - if(answer=="Lesser") - virus2_lesser_infection() - message_admins("[key_name_admin(usr)] has triggered a lesser virus outbreak.", 1) - else - virus2_greater_infection() - message_admins("[key_name_admin(usr)] has triggered a greater virus outbreak.", 1) - if("retardify") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","RET") - for(var/mob/living/carbon/human/H in player_list) - H << "\red You suddenly feel stupid." - H.setBrainLoss(60) - message_admins("[key_name_admin(usr)] made everybody retarded") - if("fakeguns") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","FG") - for(var/obj/item/W in world) - if(istype(W, /obj/item/clothing) || istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/weapon/disk) || istype(W, /obj/item/weapon/tank)) - continue - W.icon = 'icons/obj/gun.dmi' - W.icon_state = "revolver" - W.item_state = "gun" - message_admins("[key_name_admin(usr)] made every item look like a gun") - if("schoolgirl") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SG") - for(var/obj/item/clothing/under/W in world) - W.icon_state = "schoolgirl" - W.item_state = "w_suit" - message_admins("[key_name_admin(usr)] activated Japanese Animes mode") - world << sound('sound/AI/animes.ogg') - if("paintball") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","PB") - for(var/species in all_species) - var/datum/species/S = all_species[species] - S.blood_color = "rainbow" - for(var/obj/effect/decal/cleanable/blood/B in world) - B.basecolor = "rainbow" - B.update_icon() - message_admins("[key_name_admin(usr)] activated Paintball mode") - if("eagles")//SCRAW - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","EgL") - for(var/obj/machinery/door/airlock/W in world) - if(W.z in config.station_levels && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) - W.req_access = list() - message_admins("[key_name_admin(usr)] activated Egalitarian Station mode") - command_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg') - if("dorf") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","DF") - for(var/mob/living/carbon/human/B in mob_list) - B.f_style = "Dward Beard" - B.update_hair() - message_admins("[key_name_admin(usr)] activated dorf mode") - if("ionstorm") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","I") - IonStorm() - message_admins("[key_name_admin(usr)] triggered an ion storm") - var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No") - if(show_log == "Yes") - command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", new_sound = 'sound/AI/ionstorm.ogg') - if("onlyone") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","OO") - only_one() - message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)") - - if("togglenarsie") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","NA") - var/choice = input("How do you wish for narsie to interact with her surroundings?") in list("CultStation13", "Nar-Singulo") - if(choice == "CultStation13") - message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"CultStation13\".") - narsie_behaviour = "CultStation13" - if(choice == "Nar-Singulo") - message_admins("[key_name_admin(usr)] has set narsie's behaviour to \"Nar-Singulo\".") - narsie_behaviour = "Nar-Singulo" - if("hellonearth") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","NS") - var/choice = input("You sure you want to end the round and summon narsie at your location? Misuse of this could result in removal of flags or hilarity.") in list("PRAISE SATAN", "Cancel") - if(choice == "PRAISE SATAN") - new /obj/singularity/narsie/large(get_turf(usr)) - message_admins("[key_name_admin(usr)] has summoned narsie and brought about a new realm of suffering.") - if("supermattercascade") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SC") - var/choice = input("You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.") in list("NO TIME TO EXPLAIN", "Cancel") - if(choice == "NO TIME TO EXPLAIN") - explosion(get_turf(usr), 8, 16, 24, 32, 1) - new /turf/unsimulated/wall/supermatter(get_turf(usr)) - SetUniversalState(/datum/universal_state/supermatter_cascade) - message_admins("[key_name_admin(usr)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(usr)]") - if(usr) - log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]") - if (ok) - world << text("A secret has been activated by []!", usr.key) - - else if(href_list["secretsadmin"]) - if(!check_rights(R_ADMIN)) return - - var/ok = 0 - switch(href_list["secretsadmin"]) - if("clear_bombs") - //I do nothing - if("list_bombers") - var/dat = "Bombing List
" - for(var/l in bombers) - dat += text("[l]
") - usr << browse(dat, "window=bombers") - if("list_signalers") - var/dat = "Showing last [length(lastsignalers)] signalers.
" - for(var/sig in lastsignalers) - dat += "[sig]
" - usr << browse(dat, "window=lastsignalers;size=800x500") - if("list_lawchanges") - var/dat = "Showing last [length(lawchanges)] law changes.
" - for(var/sig in lawchanges) - dat += "[sig]
" - usr << browse(dat, "window=lawchanges;size=800x500") - if("list_job_debug") - var/dat = "Job Debug info.
" - if(job_master) - for(var/line in job_master.job_debug) - dat += "[line]
" - dat+= "*******

" - for(var/datum/job/job in job_master.occupations) - if(!job) continue - dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions]
" - usr << browse(dat, "window=jobdebug;size=600x500") - if("showailaws") - output_ai_laws() - if("showgm") - if(!ticker) - alert("The game hasn't started yet!") - else if (ticker.mode) - alert("The game mode is [ticker.mode.name]") - else alert("For some reason there's a ticker, but not a game mode") - if("manifest") - var/dat = "Showing Crew Manifest.
" - dat += "" - for(var/mob/living/carbon/human/H in mob_list) - if(H.ckey) - dat += text("", H.name, H.get_assignment()) - dat += "
NamePosition
[][]
" - usr << browse(dat, "window=manifest;size=440x410") - if("check_antagonist") - check_antagonists() - if("DNA") - var/dat = "Showing DNA from blood.
" - dat += "" - for(var/mob/living/carbon/human/H in mob_list) - if(H.dna && H.ckey) - dat += "" - dat += "
NameDNABlood Type
[H][H.dna.unique_enzymes][H.b_type]
" - usr << browse(dat, "window=DNA;size=440x410") - if("fingerprints") - var/dat = "Showing Fingerprints.
" - dat += "" - for(var/mob/living/carbon/human/H in mob_list) - if(H.ckey) - if(H.dna && H.dna.uni_identity) - dat += "" - else if(H.dna && !H.dna.uni_identity) - dat += "" - else if(!H.dna) - dat += "" - dat += "
NameFingerprints
[H][md5(H.dna.uni_identity)]
[H]H.dna.uni_identity = null
[H]H.dna = null
" - usr << browse(dat, "window=fingerprints;size=440x410") - else - if (usr) - log_admin("[key_name(usr)] used secret [href_list["secretsadmin"]]") - if (ok) - world << text("A secret has been activated by []!", usr.key) - - else if(href_list["secretscoder"]) - if(!check_rights(R_DEBUG)) return - - switch(href_list["secretscoder"]) - if("spawn_objects") - var/dat = "Admin Log
" - for(var/l in admin_log) - dat += "
  • [l]
  • " - if(!admin_log.len) - dat += "No-one has done anything this round!" - usr << browse(dat, "window=admin_log") - if("maint_access_brig") - for(var/obj/machinery/door/airlock/maintenance/M in world) - if (access_maint_tunnels in M.req_access) - M.req_access = list(access_brig) - message_admins("[key_name_admin(usr)] made all maint doors brig access-only.") - if("maint_access_engiebrig") - for(var/obj/machinery/door/airlock/maintenance/M in world) - if (access_maint_tunnels in M.req_access) - M.req_access = list() - M.req_one_access = list(access_brig,access_engine) - message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.") - if("infinite_sec") - var/datum/job/J = job_master.GetJob("Security Officer") - if(!J) return - J.total_positions = -1 - J.spawn_positions = -1 - message_admins("[key_name_admin(usr)] has removed the cap on security officers.") + else if(href_list["admin_secrets"]) + var/datum/admin_secret_item/item = locate(href_list["admin_secrets"]) in admin_secrets.items + item.execute(usr) else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster. From 7f24dc948e476aac557aa212c4946d471b7d00ee Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Mon, 6 Jul 2015 14:58:27 +0200 Subject: [PATCH 14/94] Re-implements Admin secrets as datums. --- baystation12.dme | 11 ++++++++++- code/modules/admin/admin.dm | 5 ++--- code/modules/admin/admin_secrets.dm | 16 +++++++++++++++- .../secrets/admin_secrets/bombing_list.dm | 12 ++++++++++++ .../admin/secrets/admin_secrets/list_dna.dm | 14 ++++++++++++++ .../admin_secrets/list_fingerprints.dm | 19 +++++++++++++++++++ .../secrets/admin_secrets/show_ai_laws.dm | 7 +++++++ .../admin_secrets/show_crew_manifest.dm | 12 ++++++++++++ .../secrets/admin_secrets/show_game_mode.dm | 14 ++++++++++++++ .../secrets/admin_secrets/show_law_changes.dm | 15 +++++++++++++++ .../secrets/admin_secrets/show_signalers.dm | 15 +++++++++++++++ .../admin_secrets/traitors_and_objectives.dm | 7 +++++++ .../secrets/{ => random_events}/gravity.dm | 10 ++++++---- code/modules/mob/dead/observer/observer.dm | 2 +- 14 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 code/modules/admin/secrets/admin_secrets/bombing_list.dm create mode 100644 code/modules/admin/secrets/admin_secrets/list_dna.dm create mode 100644 code/modules/admin/secrets/admin_secrets/list_fingerprints.dm create mode 100644 code/modules/admin/secrets/admin_secrets/show_ai_laws.dm create mode 100644 code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm create mode 100644 code/modules/admin/secrets/admin_secrets/show_game_mode.dm create mode 100644 code/modules/admin/secrets/admin_secrets/show_law_changes.dm create mode 100644 code/modules/admin/secrets/admin_secrets/show_signalers.dm create mode 100644 code/modules/admin/secrets/admin_secrets/traitors_and_objectives.dm rename code/modules/admin/secrets/{ => random_events}/gravity.dm (89%) diff --git a/baystation12.dme b/baystation12.dme index 7bc13ae072f..b45515e6d0d 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -843,7 +843,16 @@ #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" -#include "code\modules\admin\secrets\gravity.dm" +#include "code\modules\admin\secrets\admin_secrets\bombing_list.dm" +#include "code\modules\admin\secrets\admin_secrets\list_dna.dm" +#include "code\modules\admin\secrets\admin_secrets\list_fingerprints.dm" +#include "code\modules\admin\secrets\admin_secrets\show_ai_laws.dm" +#include "code\modules\admin\secrets\admin_secrets\show_crew_manifest.dm" +#include "code\modules\admin\secrets\admin_secrets\show_game_mode.dm" +#include "code\modules\admin\secrets\admin_secrets\show_law_changes.dm" +#include "code\modules\admin\secrets\admin_secrets\show_signalers.dm" +#include "code\modules\admin\secrets\admin_secrets\traitors_and_objectives.dm" +#include "code\modules\admin\secrets\random_events\gravity.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index dba65192968..06adf11b571 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -610,12 +610,11 @@ proc/admin_notice(var/message, var/rights) dat += "[category.name]
    " if(category.desc) dat += "[category.desc]
    " - dat += "
    " for(var/datum/admin_secret_item/item in category.items) if(!item.can_execute(usr)) continue - dat += "[item.name]
    " - + dat += "[item.name()]
    " + dat += "
    " usr << browse(dat, "window=secrets") return diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index 87c04ea625f..b8c4b2ef6b7 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -40,8 +40,12 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_item var/name = "" var/category = null + var/log = 1 var/permissions = R_HOST +/datum/admin_secret_item/proc/name() + return name + /datum/admin_secret_item/proc/can_execute(var/mob/user) return check_rights(permissions, 0, user) @@ -49,18 +53,28 @@ var/datum/admin_secrets/admin_secrets = new() if(!can_execute(user)) return 0 - log_admin("[key_name(user)] used secret [name]") + if(log) + log_admin("[key_name(user)] used secret '[name()]'") return 1 /************************* * Pre-defined categories * *************************/ +/datum/admin_secret_category/admin_secrets + name = "Admin Secrets" + /datum/admin_secret_category/random_events name = "'Random' Events" /************************* * Pre-defined base items * *************************/ +/datum/admin_secret_item/admin_secret + category = /datum/admin_secret_category/admin_secrets + log = 0 + permissions = R_ADMIN + + /datum/admin_secret_item/random_event category = /datum/admin_secret_category/random_events permissions = R_FUN diff --git a/code/modules/admin/secrets/admin_secrets/bombing_list.dm b/code/modules/admin/secrets/admin_secrets/bombing_list.dm new file mode 100644 index 00000000000..fa3f2683968 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/bombing_list.dm @@ -0,0 +1,12 @@ +/datum/admin_secret_item/admin_secret/bombing_list + name = "Bombing List" + +/datum/admin_secret_item/admin_secret/bombing_list/execute(var/mob/user) + . = ..() + if(!.) + return + + var/dat = "Bombing List
    " + for(var/l in bombers) + dat += text("[l]
    ") + user << browse(dat, "window=bombers") diff --git a/code/modules/admin/secrets/admin_secrets/list_dna.dm b/code/modules/admin/secrets/admin_secrets/list_dna.dm new file mode 100644 index 00000000000..f1c49f48972 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/list_dna.dm @@ -0,0 +1,14 @@ +/datum/admin_secret_item/admin_secret/list_dna + name = "List DNA (Blood)" + +/datum/admin_secret_item/admin_secret/list_dna/execute(var/mob/user) + . = ..() + if(!.) + return + var/dat = "Showing DNA from blood.
    " + dat += "" + for(var/mob/living/carbon/human/H in mob_list) + if(H.dna && H.ckey) + dat += "" + dat += "
    NameDNABlood Type
    [H][H.dna.unique_enzymes][H.b_type]
    " + user << browse(dat, "window=DNA;size=440x410") diff --git a/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm b/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm new file mode 100644 index 00000000000..710cdaf4fed --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm @@ -0,0 +1,19 @@ +/datum/admin_secret_item/admin_secret/list_fingerprints + name = "List Fingerprints" + +/datum/admin_secret_item/admin_secret/list_fingerprints/execute(var/mob/user) + . = ..() + if(!.) + return + var/dat = "Showing Fingerprints.
    " + dat += "" + for(var/mob/living/carbon/human/H in mob_list) + if(H.ckey) + if(H.dna && H.dna.uni_identity) + dat += "" + else if(H.dna && !H.dna.uni_identity) + dat += "" + else if(!H.dna) + dat += "" + dat += "
    NameFingerprints
    [H][md5(H.dna.uni_identity)]
    [H]H.dna.uni_identity = null
    [H]H.dna = null
    " + usr << browse(dat, "window=fingerprints;size=440x410") diff --git a/code/modules/admin/secrets/admin_secrets/show_ai_laws.dm b/code/modules/admin/secrets/admin_secrets/show_ai_laws.dm new file mode 100644 index 00000000000..c76ff2d9c18 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/show_ai_laws.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/admin_secret/show_ai_laws + name = "Show AI laws" + +/datum/admin_secret_item/admin_secret/show_ai_laws/execute(var/mob/user) + . = ..() + if(.) + user.client.holder.output_ai_laws() diff --git a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm new file mode 100644 index 00000000000..f4bb82224ba --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm @@ -0,0 +1,12 @@ +/datum/admin_secret_item/admin_secret/show_crew_manifest + name = "Show Crew Manifest" + +/datum/admin_secret_item/admin_secret/show_crew_manifest/execute(var/mob/user) + . = ..() + if(!.) + return + var/dat + dat += "

    Crew Manifest

    " + dat += data_core.get_manifest() + + user << browse(dat, "window=manifest;size=370x420;can_close=1") diff --git a/code/modules/admin/secrets/admin_secrets/show_game_mode.dm b/code/modules/admin/secrets/admin_secrets/show_game_mode.dm new file mode 100644 index 00000000000..b586e108466 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/show_game_mode.dm @@ -0,0 +1,14 @@ +/datum/admin_secret_item/admin_secret/show_game_mode + name = "Show Game Mode" + +/datum/admin_secret_item/admin_secret/show_game_mode/can_execute(var/mob/user) + if(!ticker) + return 0 + return ..() + +/datum/admin_secret_item/admin_secret/show_game_mode/execute(var/mob/user) + . = ..() + if(!.) + return + if (ticker.mode) alert("The game mode is [ticker.mode.name]") + else alert("For some reason there's a ticker, but not a game mode") diff --git a/code/modules/admin/secrets/admin_secrets/show_law_changes.dm b/code/modules/admin/secrets/admin_secrets/show_law_changes.dm new file mode 100644 index 00000000000..190de7b47a9 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/show_law_changes.dm @@ -0,0 +1,15 @@ +/datum/admin_secret_item/admin_secret/show_law_changes + name = "Show law changes" + +/datum/admin_secret_item/admin_secret/show_law_changes/name() + return "Show last [length(lawchanges)] law changes" + +/datum/admin_secret_item/admin_secret/show_law_changes/execute(var/mob/user) + . = ..() + if(!.) + return + + var/dat = "Showing last [length(lawchanges)] law changes.
    " + for(var/sig in lawchanges) + dat += "[sig]
    " + user << browse(dat, "window=lawchanges;size=800x500") diff --git a/code/modules/admin/secrets/admin_secrets/show_signalers.dm b/code/modules/admin/secrets/admin_secrets/show_signalers.dm new file mode 100644 index 00000000000..0e1269ea37b --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/show_signalers.dm @@ -0,0 +1,15 @@ +/datum/admin_secret_item/admin_secret/show_signalers + name = "Show last signalers" + +/datum/admin_secret_item/admin_secret/show_signalers/name() + return "Show last [length(lastsignalers)] signalers" + +/datum/admin_secret_item/admin_secret/show_signalers/execute(var/mob/user) + . = ..() + if(!.) + return + + var/dat = "Showing last [length(lastsignalers)] signalers.
    " + for(var/sig in lastsignalers) + dat += "[sig]
    " + user << browse(dat, "window=lastsignalers;size=800x500") diff --git a/code/modules/admin/secrets/admin_secrets/traitors_and_objectives.dm b/code/modules/admin/secrets/admin_secrets/traitors_and_objectives.dm new file mode 100644 index 00000000000..591c13bd3fb --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/traitors_and_objectives.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/admin_secret/traitors_and_objectives + name = "Show current traitors and objectives" + +/datum/admin_secret_item/admin_secret/traitors_and_objectives/execute(var/mob/user) + . = ..() + if(.) + user.client.holder.check_antagonists() diff --git a/code/modules/admin/secrets/gravity.dm b/code/modules/admin/secrets/random_events/gravity.dm similarity index 89% rename from code/modules/admin/secrets/gravity.dm rename to code/modules/admin/secrets/random_events/gravity.dm index 8ff9c915d43..51f8f1d1871 100644 --- a/code/modules/admin/secrets/gravity.dm +++ b/code/modules/admin/secrets/random_events/gravity.dm @@ -4,15 +4,17 @@ /datum/admin_secret_item/random_event/gravity name = "Toggle station artificial gravity" +/datum/admin_secret_item/random_event/gravity/can_execute(var/mob/user) + if(!(ticker && ticker.mode)) + return 0 + + return ..() + /datum/admin_secret_item/random_event/gravity/execute(var/mob/user) . = ..() if(!.) return - if(!(ticker && ticker.mode)) - user << "Please wait until the game starts! Not sure how it will work otherwise." - return - gravity_is_on = !gravity_is_on for(var/area/A in world) A.gravitychange(gravity_is_on,A) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 85b71aef4fd..edf8ae950e2 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -464,7 +464,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent." /mob/dead/observer/verb/view_manfiest() - set name = "View Crew Manifest" + set name = "Show Crew Manifest" set category = "Ghost" var/dat From 5703fdfe851fd0753cc8f4fd8170fd3c909e40b0 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Mon, 6 Jul 2015 15:59:26 +0200 Subject: [PATCH 15/94] Re-implements admin fun events as datums. --- baystation12.dme | 24 ++++++++++ baystation12.int | 15 +++--- code/controllers/Processes/initialize.dm | 31 ++++++++++++ code/modules/admin/admin_secrets.dm | 25 ++++++++-- .../secrets/admin_secrets/alter_narsie.dm | 14 ++++++ .../secrets/admin_secrets/jump_shuttle.dm | 36 ++++++++++++++ .../secrets/admin_secrets/launch_shutter.dm | 26 ++++++++++ .../admin_secrets/launch_shuttle_forced.dm | 26 ++++++++++ .../secrets/admin_secrets/move_shuttle.dm | 28 +++++++++++ .../secrets/admin_secrets/prison_warp.dm | 38 +++++++++++++++ .../secrets/admin_secrets/show_law_changes.dm | 2 +- .../secrets/admin_secrets/show_signalers.dm | 4 +- .../secrets/fun_secrets/break_all_lights.dm | 7 +++ .../secrets/fun_secrets/break_some_lights.dm | 7 +++ .../secrets/fun_secrets/fix_all_lights.dm | 10 ++++ .../admin/secrets/fun_secrets/ghost_mode.dm | 48 +++++++++++++++++++ .../fun_secrets/make_all_areas_powered.dm | 7 +++ .../fun_secrets/make_all_areas_unpowered.dm | 7 +++ .../admin/secrets/fun_secrets/only_one.dm | 7 +++ .../secrets/fun_secrets/paintball_mode.dm | 14 ++++++ .../secrets/fun_secrets/power_all_smes.dm | 7 +++ .../fun_secrets/remove_all_clothing.dm | 10 ++++ .../fun_secrets/remove_internal_clothing.dm | 10 ++++ .../secrets/fun_secrets/send_strike_team.dm | 11 +++++ .../secrets/fun_secrets/toggle_bomb_cap.dm | 21 ++++++++ .../secrets/fun_secrets/triple_ai_mode.dm | 13 +++++ .../fun_secrets/turn_humans_into_corgies.dm | 11 +++++ .../fun_secrets/turn_humans_into_monkeys.dm | 11 +++++ .../admin/secrets/random_events/gravity.dm | 2 +- .../trigger_cordical_borer_infestation.dm | 7 +++ .../trigger_xenomorph_infestation.dm | 7 +++ 31 files changed, 472 insertions(+), 14 deletions(-) create mode 100644 code/controllers/Processes/initialize.dm create mode 100644 code/modules/admin/secrets/admin_secrets/alter_narsie.dm create mode 100644 code/modules/admin/secrets/admin_secrets/jump_shuttle.dm create mode 100644 code/modules/admin/secrets/admin_secrets/launch_shutter.dm create mode 100644 code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm create mode 100644 code/modules/admin/secrets/admin_secrets/move_shuttle.dm create mode 100644 code/modules/admin/secrets/admin_secrets/prison_warp.dm create mode 100644 code/modules/admin/secrets/fun_secrets/break_all_lights.dm create mode 100644 code/modules/admin/secrets/fun_secrets/break_some_lights.dm create mode 100644 code/modules/admin/secrets/fun_secrets/fix_all_lights.dm create mode 100644 code/modules/admin/secrets/fun_secrets/ghost_mode.dm create mode 100644 code/modules/admin/secrets/fun_secrets/make_all_areas_powered.dm create mode 100644 code/modules/admin/secrets/fun_secrets/make_all_areas_unpowered.dm create mode 100644 code/modules/admin/secrets/fun_secrets/only_one.dm create mode 100644 code/modules/admin/secrets/fun_secrets/paintball_mode.dm create mode 100644 code/modules/admin/secrets/fun_secrets/power_all_smes.dm create mode 100644 code/modules/admin/secrets/fun_secrets/remove_all_clothing.dm create mode 100644 code/modules/admin/secrets/fun_secrets/remove_internal_clothing.dm create mode 100644 code/modules/admin/secrets/fun_secrets/send_strike_team.dm create mode 100644 code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm create mode 100644 code/modules/admin/secrets/fun_secrets/triple_ai_mode.dm create mode 100644 code/modules/admin/secrets/fun_secrets/turn_humans_into_corgies.dm create mode 100644 code/modules/admin/secrets/fun_secrets/turn_humans_into_monkeys.dm create mode 100644 code/modules/admin/secrets/random_events/trigger_cordical_borer_infestation.dm create mode 100644 code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm diff --git a/baystation12.dme b/baystation12.dme index b45515e6d0d..9946956dfbb 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -843,16 +843,40 @@ #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" +#include "code\modules\admin\secrets\admin_secrets\alter_narsie.dm" #include "code\modules\admin\secrets\admin_secrets\bombing_list.dm" +#include "code\modules\admin\secrets\admin_secrets\jump_shuttle.dm" +#include "code\modules\admin\secrets\admin_secrets\launch_shutter.dm" +#include "code\modules\admin\secrets\admin_secrets\launch_shuttle_forced.dm" #include "code\modules\admin\secrets\admin_secrets\list_dna.dm" #include "code\modules\admin\secrets\admin_secrets\list_fingerprints.dm" +#include "code\modules\admin\secrets\admin_secrets\move_shuttle.dm" +#include "code\modules\admin\secrets\admin_secrets\prison_warp.dm" #include "code\modules\admin\secrets\admin_secrets\show_ai_laws.dm" #include "code\modules\admin\secrets\admin_secrets\show_crew_manifest.dm" #include "code\modules\admin\secrets\admin_secrets\show_game_mode.dm" #include "code\modules\admin\secrets\admin_secrets\show_law_changes.dm" #include "code\modules\admin\secrets\admin_secrets\show_signalers.dm" #include "code\modules\admin\secrets\admin_secrets\traitors_and_objectives.dm" +#include "code\modules\admin\secrets\fun_secrets\break_all_lights.dm" +#include "code\modules\admin\secrets\fun_secrets\break_some_lights.dm" +#include "code\modules\admin\secrets\fun_secrets\fix_all_lights.dm" +#include "code\modules\admin\secrets\fun_secrets\ghost_mode.dm" +#include "code\modules\admin\secrets\fun_secrets\make_all_areas_powered.dm" +#include "code\modules\admin\secrets\fun_secrets\make_all_areas_unpowered.dm" +#include "code\modules\admin\secrets\fun_secrets\only_one.dm" +#include "code\modules\admin\secrets\fun_secrets\paintball_mode.dm" +#include "code\modules\admin\secrets\fun_secrets\power_all_smes.dm" +#include "code\modules\admin\secrets\fun_secrets\remove_all_clothing.dm" +#include "code\modules\admin\secrets\fun_secrets\remove_internal_clothing.dm" +#include "code\modules\admin\secrets\fun_secrets\send_strike_team.dm" +#include "code\modules\admin\secrets\fun_secrets\toggle_bomb_cap.dm" +#include "code\modules\admin\secrets\fun_secrets\triple_ai_mode.dm" +#include "code\modules\admin\secrets\fun_secrets\turn_humans_into_corgies.dm" +#include "code\modules\admin\secrets\fun_secrets\turn_humans_into_monkeys.dm" #include "code\modules\admin\secrets\random_events\gravity.dm" +#include "code\modules\admin\secrets\random_events\trigger_cordical_borer_infestation.dm" +#include "code\modules\admin\secrets\random_events\trigger_xenomorph_infestation.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" diff --git a/baystation12.int b/baystation12.int index b82874fded5..cfd9890d63b 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,9 @@ -// BEGIN_INTERNALS -/* -MAP_ICON_TYPE: 0 -AUTO_FILE_DIR: OFF -*/ -// END_INTERNALS +// BEGIN_INTERNALS +/* +DIR: code code\modules code\modules\mob code\modules\mob\freelook code\modules\mob\living code\modules\mob\living\carbon code\modules\mob\living\carbon\alien code\modules\mob\living\carbon\alien\diona code\modules\mob\living\carbon\alien\larva code\modules\mob\living\carbon\human +AUTO_FILE_DIR: OFF +MAP_ICON_TYPE: 0 +WINDOW: code\modules\mob\living\carbon\human\life.dm +FILE: code\modules\mob\living\carbon\human\life.dm +*/ +// END_INTERNALS diff --git a/code/controllers/Processes/initialize.dm b/code/controllers/Processes/initialize.dm new file mode 100644 index 00000000000..055a056bed5 --- /dev/null +++ b/code/controllers/Processes/initialize.dm @@ -0,0 +1,31 @@ +var/list/pending_init_objects + +/datum/controller/process/initialize + var/list/objects_to_initialize + +/datum/controller/process/initialize/setup() + name = "init" + schedule_interval = 1 // Every tick, scary + objects_to_initialize = pending_init_objects + +/datum/controller/process/initialize/doWork() + for(var/atom/movable/A in objects_to_initialize) + A.initialize() + scheck() + objects_to_initialize.Remove(A) + + if(!objects_to_initialize.len) + disable() + +/proc/initialize_object(var/atom/movable/obj_to_init) + if(processScheduler.hasProcess("init")) + var/datum/controller/process/initialize/init = processScheduler.getProcess("init") + init.objects_to_initialize += obj_to_init + init.enable() + else + world.log << "Not yet" + if(!pending_init_objects) pending_init_objects = list() + pending_init_objects += obj_to_init + +/datum/controller/process/initialize/getStatName() + return ..()+"([objects_to_initialize.len])" diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index b8c4b2ef6b7..2ce43a79620 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -9,7 +9,7 @@ var/datum/admin_secrets/admin_secrets = new() categories = init_subtypes(/datum/admin_secret_category) items = list() var/list/category_assoc = list() - for(var/datum/category in categories) + for(var/datum/admin_secret_category/category in categories) category_assoc[category.type] = category for(var/item_type in (typesof(/datum/admin_secret_item) - /datum/admin_secret_item)) @@ -19,7 +19,7 @@ var/datum/admin_secrets/admin_secrets = new() var/datum/admin_secret_item/item = new item_type() var/datum/admin_secret_category/category = category_assoc[item.category] - category.items += item + dd_insertObjectList(category.items, item) items += item /datum/admin_secret_category @@ -41,6 +41,7 @@ var/datum/admin_secrets/admin_secrets = new() var/name = "" var/category = null var/log = 1 + var/feedback = 1 var/permissions = R_HOST /datum/admin_secret_item/proc/name() @@ -54,7 +55,10 @@ var/datum/admin_secrets/admin_secrets = new() return 0 if(log) - log_admin("[key_name(user)] used secret '[name()]'") + log_and_message_admins("used secret '[name]'", user) + if(feedback) + feedback_inc("admin_secrets_used",1) + feedback_add_details("admin_secrets_used","[name]") return 1 /************************* @@ -66,6 +70,12 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_category/random_events name = "'Random' Events" +/datum/admin_secret_category/fun_secrets + name = "Fun Secrets" + +/datum/admin_secret_category/final_solutions + name = "Final Solutions" + /************************* * Pre-defined base items * *************************/ @@ -74,7 +84,14 @@ var/datum/admin_secrets/admin_secrets = new() log = 0 permissions = R_ADMIN - /datum/admin_secret_item/random_event category = /datum/admin_secret_category/random_events permissions = R_FUN + +/datum/admin_secret_item/fun_secret + category = /datum/admin_secret_category/fun_secrets + permissions = R_FUN + +/datum/admin_secret_item/final_solution + category = /datum/admin_secret_category/final_solutions + permissions = R_FUN|R_SERVER|R_ADMIN diff --git a/code/modules/admin/secrets/admin_secrets/alter_narsie.dm b/code/modules/admin/secrets/admin_secrets/alter_narsie.dm new file mode 100644 index 00000000000..75281adca8f --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/alter_narsie.dm @@ -0,0 +1,14 @@ +/datum/admin_secret_item/admin_secret/alter_narise + name = "Alter Nar-Sie" + +/datum/admin_secret_item/admin_secret/alter_narise/execute(var/mob/user) + . = ..() + if(!.) + return + var/choice = input(user, "How do you wish for Nar-Sie to interact with its surroundings?") as null|anything in list("CultStation13", "Nar-Singulo") + if(choice == "CultStation13") + log_and_message_admins("has set narsie's behaviour to \"CultStation13\".", user) + narsie_behaviour = choice + if(choice == "Nar-Singulo") + log_and_message_admins("has set narsie's behaviour to \"Nar-Singulo\".", user) + narsie_behaviour = choice diff --git a/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm b/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm new file mode 100644 index 00000000000..1453ae35ce6 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm @@ -0,0 +1,36 @@ +/datum/admin_secret_item/admin_secret/jump_shuttle + name = "Jump a Shuttle" + +/datum/admin_secret_item/admin_secret/jump_shuttle/can_execute(var/mob/user) + if(!shuttle_controller) return 0 + return ..() + +/datum/admin_secret_item/admin_secret/jump_shuttle/execute(var/mob/user) + . = ..() + if(!.) + return + var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles + if (!shuttle_tag) return + + var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] + + var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + if (!origin_area) return + + var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + if (!destination_area) return + + var/long_jump = alert("Is there a transition area for this jump?","", "Yes", "No") + if (long_jump == "Yes") + var/transition_area = input("Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + if (!transition_area) return + + var/move_duration = input("How many seconds will this jump take?") as num + + S.long_jump(origin_area, destination_area, transition_area, move_duration) + message_admins("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle", 1) + log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle") + else + S.short_jump(origin_area, destination_area) + message_admins("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle", 1) + log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle") diff --git a/code/modules/admin/secrets/admin_secrets/launch_shutter.dm b/code/modules/admin/secrets/admin_secrets/launch_shutter.dm new file mode 100644 index 00000000000..30867fca051 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/launch_shutter.dm @@ -0,0 +1,26 @@ +/datum/admin_secret_item/admin_secret/launch_shuttle + name = "Launch a Shuttle" + +/datum/admin_secret_item/admin_secret/launch_shuttle/can_execute(var/mob/user) + if(!shuttle_controller) return 0 + return ..() + +/datum/admin_secret_item/admin_secret/launch_shuttle/execute(var/mob/user) + . = ..() + if(!.) + return + var/list/valid_shuttles = list() + for (var/shuttle_tag in shuttle_controller.shuttles) + if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) + valid_shuttles += shuttle_tag + + var/shuttle_tag = input("Which shuttle do you want to launch?") as null|anything in valid_shuttles + if (!shuttle_tag) + return + + var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] + if (S.can_launch()) + S.launch(usr) + log_and_message_admins("launched the [shuttle_tag] shuttle", user) + else + alert("The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.") diff --git a/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm b/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm new file mode 100644 index 00000000000..250d04b0443 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm @@ -0,0 +1,26 @@ +/datum/admin_secret_item/admin_secret/launch_shuttle_forced + name = "Launch a Shuttle (Forced)" + +/datum/admin_secret_item/admin_secret/launch_shuttle_forced/can_execute(var/mob/user) + if(!shuttle_controller) return 0 + return ..() + +/datum/admin_secret_item/admin_secret/launch_shuttle_forced/execute(var/mob/user) + . = ..() + if(!.) + return + var/list/valid_shuttles = list() + for (var/shuttle_tag in shuttle_controller.shuttles) + if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) + valid_shuttles += shuttle_tag + + var/shuttle_tag = input("Which shuttle's launch do you want to force?") as null|anything in valid_shuttles + if (!shuttle_tag) + return + + var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] + if (S.can_force()) + S.force_launch(usr) + log_and_message_admins("forced the [shuttle_tag] shuttle", user) + else + alert("The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.") diff --git a/code/modules/admin/secrets/admin_secrets/move_shuttle.dm b/code/modules/admin/secrets/admin_secrets/move_shuttle.dm new file mode 100644 index 00000000000..e58863afde2 --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/move_shuttle.dm @@ -0,0 +1,28 @@ +/datum/admin_secret_item/admin_secret/move_shuttle + name = "Move a Shuttle" + +/datum/admin_secret_item/admin_secret/move_shuttle/can_execute(var/mob/user) + if(!shuttle_controller) return 0 + return ..() + +/datum/admin_secret_item/admin_secret/move_shuttle/execute(var/mob/user) + . = ..() + if(!.) + return + var/confirm = alert("This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", "Ok", "Cancel") + if (confirm == "Cancel") + return + + var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles + if (!shuttle_tag) return + + var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] + + var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + if (!origin_area) return + + var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + if (!destination_area) return + + S.move(origin_area, destination_area) + log_and_message_admins("[key_name_admin(usr)] moved the [shuttle_tag] shuttle", user) diff --git a/code/modules/admin/secrets/admin_secrets/prison_warp.dm b/code/modules/admin/secrets/admin_secrets/prison_warp.dm new file mode 100644 index 00000000000..eec85c2f04b --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/prison_warp.dm @@ -0,0 +1,38 @@ +/datum/admin_secret_item/admin_secret/prison_warp + name = "Prison Warp" + +/datum/admin_secret_item/admin_secret/prison_warp/can_execute(var/mob/user) + if(!ticker) return 0 + return ..() + +/datum/admin_secret_item/admin_secret/prison_warp/execute(var/mob/user) + . = ..() + if(!.) + return + for(var/mob/living/carbon/human/H in mob_list) + var/turf/T = get_turf(H) + var/security = 0 + if((T && T in config.admin_levels) || prisonwarped.Find(H)) + //don't warp them if they aren't ready or are already there + continue + H.Paralyse(5) + if(H.wear_id) + var/obj/item/weapon/card/id/id = H.get_idcard() + for(var/A in id.access) + if(A == access_security) + security++ + if(!security) + //strip their stuff before they teleport into a cell :downs: + for(var/obj/item/weapon/W in H) + if(istype(W, /obj/item/organ/external)) + continue + //don't strip organs + H.drop_from_inventory(W) + //teleport person to cell + H.loc = pick(prisonwarp) + H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), slot_shoes) + else + //teleport security person + H.loc = pick(prisonsecuritywarp) + prisonwarped += H diff --git a/code/modules/admin/secrets/admin_secrets/show_law_changes.dm b/code/modules/admin/secrets/admin_secrets/show_law_changes.dm index 190de7b47a9..877e2c217de 100644 --- a/code/modules/admin/secrets/admin_secrets/show_law_changes.dm +++ b/code/modules/admin/secrets/admin_secrets/show_law_changes.dm @@ -2,7 +2,7 @@ name = "Show law changes" /datum/admin_secret_item/admin_secret/show_law_changes/name() - return "Show last [length(lawchanges)] law changes" + return "Show Last [length(lawchanges)] Law change\s" /datum/admin_secret_item/admin_secret/show_law_changes/execute(var/mob/user) . = ..() diff --git a/code/modules/admin/secrets/admin_secrets/show_signalers.dm b/code/modules/admin/secrets/admin_secrets/show_signalers.dm index 0e1269ea37b..32a77cbef2e 100644 --- a/code/modules/admin/secrets/admin_secrets/show_signalers.dm +++ b/code/modules/admin/secrets/admin_secrets/show_signalers.dm @@ -1,8 +1,8 @@ /datum/admin_secret_item/admin_secret/show_signalers - name = "Show last signalers" + name = "Show Last Signalers" /datum/admin_secret_item/admin_secret/show_signalers/name() - return "Show last [length(lastsignalers)] signalers" + return "Show Last [length(lastsignalers)] Signaler\s" /datum/admin_secret_item/admin_secret/show_signalers/execute(var/mob/user) . = ..() diff --git a/code/modules/admin/secrets/fun_secrets/break_all_lights.dm b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm new file mode 100644 index 00000000000..5c65e389af7 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/break_all_lights + name = "Break All Lights" + +/datum/admin_secret_item/fun_secret/make_all_areas_powered/execute(var/mob/user) + . = ..() + if(.) + lightsout(0,0) diff --git a/code/modules/admin/secrets/fun_secrets/break_some_lights.dm b/code/modules/admin/secrets/fun_secrets/break_some_lights.dm new file mode 100644 index 00000000000..0c9aae1b166 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/break_some_lights.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/break_some_lights + name = "Break Some Lights" + +/datum/admin_secret_item/fun_secret/break_some_lights/execute(var/mob/user) + . = ..() + if(.) + lightsout(1,2) diff --git a/code/modules/admin/secrets/fun_secrets/fix_all_lights.dm b/code/modules/admin/secrets/fun_secrets/fix_all_lights.dm new file mode 100644 index 00000000000..387f6d3ce72 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/fix_all_lights.dm @@ -0,0 +1,10 @@ +/datum/admin_secret_item/fun_secret/fix_all_lights + name = "Fix All Lights" + +/datum/admin_secret_item/fun_secret/fix_all_lights/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/obj/machinery/light/L in world) + L.fix() diff --git a/code/modules/admin/secrets/fun_secrets/ghost_mode.dm b/code/modules/admin/secrets/fun_secrets/ghost_mode.dm new file mode 100644 index 00000000000..dfa84e4cf6a --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/ghost_mode.dm @@ -0,0 +1,48 @@ +/datum/admin_secret_item/fun_secret/ghost_mode + name = "Ghost Mode" + var/list/affected_mobs + +/datum/admin_secret_item/fun_secret/ghost_mode/New() + ..() + affected_mobs = list() + +/datum/admin_secret_item/fun_secret/ghost_mode/execute(var/mob/user) + . = ..() + if(!.) + return + + var/list/affected_areas = list() + for(var/mob/M in living_mob_list) + if(M.stat == CONSCIOUS && !(M in affected_mobs)) + affected_mobs |= M + switch(rand(1,4)) + if(1) + M.show_message(text("You shudder as if cold..."), 1) + if(2) + M.show_message(text("You feel something gliding across your back..."), 1) + if(3) + M.show_message(text("Your eyes twitch, you feel like something you can't see is here..."), 1) + if(4) + M.show_message(text("You notice something moving out of the corner of your eye, but nothing is there..."), 1) + + for(var/obj/W in orange(5,M)) + if(prob(25) && !W.anchored) + step_rand(W) + + var/area/A = get_area(M) + if(A.requires_power && !A.always_unpowered && A.power_light && (A.z in config.player_levels)) + affected_areas |= get_area(M) + + affected_mobs |= user + for(var/area/AffectedArea in affected_areas) + AffectedArea.power_light = 0 + AffectedArea.power_change() + spawn(rand(25,50)) + AffectedArea.power_light = 1 + AffectedArea.power_change() + + sleep(100) + for(var/mob/M in affected_mobs) + M.show_message(text("The chilling wind suddenly stops..."), 1) + affected_mobs.Cut() + affected_areas.Cut() diff --git a/code/modules/admin/secrets/fun_secrets/make_all_areas_powered.dm b/code/modules/admin/secrets/fun_secrets/make_all_areas_powered.dm new file mode 100644 index 00000000000..33091900289 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/make_all_areas_powered.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/make_all_areas_powered + name = "Make All Areas Powered" + +/datum/admin_secret_item/fun_secret/make_all_areas_powered/execute(var/mob/user) + . = ..() + if(.) + power_restore() diff --git a/code/modules/admin/secrets/fun_secrets/make_all_areas_unpowered.dm b/code/modules/admin/secrets/fun_secrets/make_all_areas_unpowered.dm new file mode 100644 index 00000000000..a840006a23c --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/make_all_areas_unpowered.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/make_all_areas_unpowered + name = "Make All Areas Unpowered" + +/datum/admin_secret_item/fun_secret/make_all_areas_unpowered/execute(var/mob/user) + . = ..() + if(.) + power_failure() diff --git a/code/modules/admin/secrets/fun_secrets/only_one.dm b/code/modules/admin/secrets/fun_secrets/only_one.dm new file mode 100644 index 00000000000..bc0c962b29b --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/only_one.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/only_one + name = "There Can Be Only One" + +/datum/admin_secret_item/fun_secret/only_one/execute(var/mob/user) + . = ..() + if(.) + only_one() diff --git a/code/modules/admin/secrets/fun_secrets/paintball_mode.dm b/code/modules/admin/secrets/fun_secrets/paintball_mode.dm new file mode 100644 index 00000000000..8225b96b296 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/paintball_mode.dm @@ -0,0 +1,14 @@ +/datum/admin_secret_item/fun_secret/paintbal_mode + name = "Paintball Mode" + +/datum/admin_secret_item/fun_secret/paintbal_mode/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/species in all_species) + var/datum/species/S = all_species[species] + S.blood_color = "rainbow" + for(var/obj/effect/decal/cleanable/blood/B in world) + B.basecolor = "rainbow" + B.update_icon() diff --git a/code/modules/admin/secrets/fun_secrets/power_all_smes.dm b/code/modules/admin/secrets/fun_secrets/power_all_smes.dm new file mode 100644 index 00000000000..277edd5a438 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/power_all_smes.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/fun_secret/power_all_smes + name = "Power All SMES" + +/datum/admin_secret_item/fun_secret/power_all_smes/execute(var/mob/user) + . = ..() + if(.) + power_restore_quick() diff --git a/code/modules/admin/secrets/fun_secrets/remove_all_clothing.dm b/code/modules/admin/secrets/fun_secrets/remove_all_clothing.dm new file mode 100644 index 00000000000..28e9497f53f --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/remove_all_clothing.dm @@ -0,0 +1,10 @@ +/datum/admin_secret_item/fun_secret/remove_all_clothing + name = "Remove ALL Clothing" + +/datum/admin_secret_item/fun_secret/remove_all_clothing/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/obj/item/clothing/O in world) + qdel(O) diff --git a/code/modules/admin/secrets/fun_secrets/remove_internal_clothing.dm b/code/modules/admin/secrets/fun_secrets/remove_internal_clothing.dm new file mode 100644 index 00000000000..73dba4ce4f9 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/remove_internal_clothing.dm @@ -0,0 +1,10 @@ +/datum/admin_secret_item/fun_secret/remove_internal_clothing + name = "Remove 'Internal' Clothing" + +/datum/admin_secret_item/fun_secret/remove_internal_clothing/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/obj/item/clothing/under/O in world) + qdel(O) diff --git a/code/modules/admin/secrets/fun_secrets/send_strike_team.dm b/code/modules/admin/secrets/fun_secrets/send_strike_team.dm new file mode 100644 index 00000000000..3ec1bacb2c0 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/send_strike_team.dm @@ -0,0 +1,11 @@ +/datum/admin_secret_item/fun_secret/send_strike_team + name = "Send Strike Team" + +/datum/admin_secret_item/fun_secret/send_strike_team/can_execute(var/mob/user) + if(!ticker) return 0 + return ..() + +/datum/admin_secret_item/fun_secret/send_strike_team/execute(var/mob/user) + . = ..() + if(.) + return user.client.strike_team() diff --git a/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm b/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm new file mode 100644 index 00000000000..28cd3327c43 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm @@ -0,0 +1,21 @@ +/datum/admin_secret_item/fun_secret/toggle_bomb_cap + name = "Toggle Bomb Cap" + permissions = R_SERVER + +/datum/admin_secret_item/fun_secret/toggle_bomb_cap/execute(var/mob/user) + . = ..() + if(!.) + return + + switch(max_explosion_range) + if(14) max_explosion_range = 16 + if(16) max_explosion_range = 20 + if(20) max_explosion_range = 28 + if(28) max_explosion_range = 56 + if(56) max_explosion_range = 128 + if(128) max_explosion_range = 14 + var/range_dev = max_explosion_range *0.25 + var/range_high = max_explosion_range *0.5 + var/range_low = max_explosion_range + message_admins("[key_name_admin(usr)] changed the bomb cap to [range_dev], [range_high], [range_low]", 1) + log_admin("[key_name_admin(usr)] changed the bomb cap to [max_explosion_range]") diff --git a/code/modules/admin/secrets/fun_secrets/triple_ai_mode.dm b/code/modules/admin/secrets/fun_secrets/triple_ai_mode.dm new file mode 100644 index 00000000000..81b77eabb64 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/triple_ai_mode.dm @@ -0,0 +1,13 @@ +/datum/admin_secret_item/fun_secret/triple_ai_mode + name = "Triple AI Mode" + +/datum/admin_secret_item/fun_secret/triple_ai_mode/can_execute(var/mob/user) + if(ticker && ticker.current_state > GAME_STATE_PREGAME) + return 0 + + return ..() + +/datum/admin_secret_item/admin_secret/triple_ai_mode/execute(var/mob/user) + . = ..() + if(.) + user.client.triple_ai() diff --git a/code/modules/admin/secrets/fun_secrets/turn_humans_into_corgies.dm b/code/modules/admin/secrets/fun_secrets/turn_humans_into_corgies.dm new file mode 100644 index 00000000000..ae6f36a1ac1 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/turn_humans_into_corgies.dm @@ -0,0 +1,11 @@ +/datum/admin_secret_item/fun_secret/turn_humans_into_corgies + name = "Turn All Humans Into Corgies" + +/datum/admin_secret_item/fun_secret/turn_humans_into_corgies/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/mob/living/carbon/human/H in mob_list) + spawn(0) + H.corgize() diff --git a/code/modules/admin/secrets/fun_secrets/turn_humans_into_monkeys.dm b/code/modules/admin/secrets/fun_secrets/turn_humans_into_monkeys.dm new file mode 100644 index 00000000000..99b1573adef --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/turn_humans_into_monkeys.dm @@ -0,0 +1,11 @@ +/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys + name = "Turn All Humans Into Monkeys" + +/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys/execute(var/mob/user) + . = ..() + if(!.) + return + + for(var/mob/living/carbon/human/H in mob_list) + spawn(0) + H.monkeyize() diff --git a/code/modules/admin/secrets/random_events/gravity.dm b/code/modules/admin/secrets/random_events/gravity.dm index 51f8f1d1871..637bb7129ff 100644 --- a/code/modules/admin/secrets/random_events/gravity.dm +++ b/code/modules/admin/secrets/random_events/gravity.dm @@ -2,7 +2,7 @@ * Gravity * **********/ /datum/admin_secret_item/random_event/gravity - name = "Toggle station artificial gravity" + name = "Toggle Station Artificial Gravity" /datum/admin_secret_item/random_event/gravity/can_execute(var/mob/user) if(!(ticker && ticker.mode)) diff --git a/code/modules/admin/secrets/random_events/trigger_cordical_borer_infestation.dm b/code/modules/admin/secrets/random_events/trigger_cordical_borer_infestation.dm new file mode 100644 index 00000000000..f96004565d8 --- /dev/null +++ b/code/modules/admin/secrets/random_events/trigger_cordical_borer_infestation.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation + name = "Trigger a Cortical Borer infestation" + +/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation/execute(var/mob/user) + . = ..() + if(.) + return borers.attempt_random_spawn() diff --git a/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm b/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm new file mode 100644 index 00000000000..11dad2e84c6 --- /dev/null +++ b/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/random_event/trigger_xenomorph_infestation + name = "Trigger a Xenomorph Infestation" + +/datum/admin_secret_item/random_event/trigger_xenomorph_infestation/execute(var/mob/user) + . = ..() + if(.) + return xenomorphs.attempt_random_spawn() From 457987046b9a1355f2eadff6817bae8fc891dc42 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 7 Jul 2015 11:24:09 +0200 Subject: [PATCH 16/94] Re-implements world end events as datums. --- baystation12.dme | 5 ++++- baystation12.int | 15 ++++++-------- code/_helpers/lists.dm | 2 +- code/modules/admin/admin_secrets.dm | 4 ++++ .../admin/secrets/admin_secrets/admin_logs.dm | 13 ++++++++++++ .../secrets/admin_secrets/jump_shuttle.dm | 20 +++++++++---------- .../{launch_shutter.dm => launch_shuttle.dm} | 6 +++--- .../admin_secrets/launch_shuttle_forced.dm | 6 +++--- .../admin_secrets/list_fingerprints.dm | 2 +- .../secrets/admin_secrets/move_shuttle.dm | 10 +++++----- .../secrets/final_solutions/summon_narsie.dm | 11 ++++++++++ .../final_solutions/supermatter_cascade.dm | 13 ++++++++++++ .../secrets/fun_secrets/break_all_lights.dm | 2 +- .../secrets/fun_secrets/toggle_bomb_cap.dm | 4 ++-- .../admin/secrets/random_events/gravity.dm | 12 +++++------ 15 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 code/modules/admin/secrets/admin_secrets/admin_logs.dm rename code/modules/admin/secrets/admin_secrets/{launch_shutter.dm => launch_shuttle.dm} (74%) create mode 100644 code/modules/admin/secrets/final_solutions/summon_narsie.dm create mode 100644 code/modules/admin/secrets/final_solutions/supermatter_cascade.dm diff --git a/baystation12.dme b/baystation12.dme index 9946956dfbb..a8b4f311eff 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -843,10 +843,11 @@ #include "code\modules\admin\ToRban.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" +#include "code\modules\admin\secrets\admin_secrets\admin_logs.dm" #include "code\modules\admin\secrets\admin_secrets\alter_narsie.dm" #include "code\modules\admin\secrets\admin_secrets\bombing_list.dm" #include "code\modules\admin\secrets\admin_secrets\jump_shuttle.dm" -#include "code\modules\admin\secrets\admin_secrets\launch_shutter.dm" +#include "code\modules\admin\secrets\admin_secrets\launch_shuttle.dm" #include "code\modules\admin\secrets\admin_secrets\launch_shuttle_forced.dm" #include "code\modules\admin\secrets\admin_secrets\list_dna.dm" #include "code\modules\admin\secrets\admin_secrets\list_fingerprints.dm" @@ -858,6 +859,8 @@ #include "code\modules\admin\secrets\admin_secrets\show_law_changes.dm" #include "code\modules\admin\secrets\admin_secrets\show_signalers.dm" #include "code\modules\admin\secrets\admin_secrets\traitors_and_objectives.dm" +#include "code\modules\admin\secrets\final_solutions\summon_narsie.dm" +#include "code\modules\admin\secrets\final_solutions\supermatter_cascade.dm" #include "code\modules\admin\secrets\fun_secrets\break_all_lights.dm" #include "code\modules\admin\secrets\fun_secrets\break_some_lights.dm" #include "code\modules\admin\secrets\fun_secrets\fix_all_lights.dm" diff --git a/baystation12.int b/baystation12.int index cfd9890d63b..b82874fded5 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,9 +1,6 @@ -// BEGIN_INTERNALS -/* -DIR: code code\modules code\modules\mob code\modules\mob\freelook code\modules\mob\living code\modules\mob\living\carbon code\modules\mob\living\carbon\alien code\modules\mob\living\carbon\alien\diona code\modules\mob\living\carbon\alien\larva code\modules\mob\living\carbon\human -AUTO_FILE_DIR: OFF -MAP_ICON_TYPE: 0 -WINDOW: code\modules\mob\living\carbon\human\life.dm -FILE: code\modules\mob\living\carbon\human\life.dm -*/ -// END_INTERNALS +// BEGIN_INTERNALS +/* +MAP_ICON_TYPE: 0 +AUTO_FILE_DIR: OFF +*/ +// END_INTERNALS diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index fb4cd3874eb..b4f70b32b1d 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -592,7 +592,7 @@ proc/dd_sortedTextList(list/incoming) return dd_sortedtextlist(incoming, case_sensitive) -datum/proc/dd_SortValue() +/datum/proc/dd_SortValue() return "[src]" /obj/machinery/dd_SortValue() diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index 2ce43a79620..88a58ff6e83 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -44,6 +44,9 @@ var/datum/admin_secrets/admin_secrets = new() var/feedback = 1 var/permissions = R_HOST +/datum/admin_secret_item/dd_SortValue() + return "[name]" + /datum/admin_secret_item/proc/name() return name @@ -75,6 +78,7 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_category/final_solutions name = "Final Solutions" + desc = "(Warning, these will end the round!)" /************************* * Pre-defined base items * diff --git a/code/modules/admin/secrets/admin_secrets/admin_logs.dm b/code/modules/admin/secrets/admin_secrets/admin_logs.dm new file mode 100644 index 00000000000..d2664f1e2be --- /dev/null +++ b/code/modules/admin/secrets/admin_secrets/admin_logs.dm @@ -0,0 +1,13 @@ +/datum/admin_secret_item/admin_secret/admin_logs + name = "Admin Logs" + +/datum/admin_secret_item/admin_secret/admin_logs/execute(var/mob/user) + . = ..() + if(!.) + return + var/dat = "Admin Log
    " + for(var/l in admin_log) + dat += "
  • [l]
  • " + if(!admin_log.len) + dat += "No-one has done anything this round!" + user << browse(dat, "window=admin_log") diff --git a/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm b/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm index 1453ae35ce6..4097632aa30 100644 --- a/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm +++ b/code/modules/admin/secrets/admin_secrets/jump_shuttle.dm @@ -9,28 +9,28 @@ . = ..() if(!.) return - var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles + var/shuttle_tag = input(user, "Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles if (!shuttle_tag) return var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] - var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + var/origin_area = input(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world if (!origin_area) return - var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + var/destination_area = input(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world if (!destination_area) return - var/long_jump = alert("Is there a transition area for this jump?","", "Yes", "No") + var/long_jump = alert(user, "Is there a transition area for this jump?","", "Yes", "No") if (long_jump == "Yes") - var/transition_area = input("Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + var/transition_area = input(user, "Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world if (!transition_area) return - var/move_duration = input("How many seconds will this jump take?") as num + var/move_duration = input(user, "How many seconds will this jump take?") as num S.long_jump(origin_area, destination_area, transition_area, move_duration) - message_admins("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle", 1) - log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle") + message_admins("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle", 1) + log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle") else S.short_jump(origin_area, destination_area) - message_admins("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle", 1) - log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle") + message_admins("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle", 1) + log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle") diff --git a/code/modules/admin/secrets/admin_secrets/launch_shutter.dm b/code/modules/admin/secrets/admin_secrets/launch_shuttle.dm similarity index 74% rename from code/modules/admin/secrets/admin_secrets/launch_shutter.dm rename to code/modules/admin/secrets/admin_secrets/launch_shuttle.dm index 30867fca051..9d6ce44a2d2 100644 --- a/code/modules/admin/secrets/admin_secrets/launch_shutter.dm +++ b/code/modules/admin/secrets/admin_secrets/launch_shuttle.dm @@ -14,13 +14,13 @@ if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) valid_shuttles += shuttle_tag - var/shuttle_tag = input("Which shuttle do you want to launch?") as null|anything in valid_shuttles + var/shuttle_tag = input(user, "Which shuttle do you want to launch?") as null|anything in valid_shuttles if (!shuttle_tag) return var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] if (S.can_launch()) - S.launch(usr) + S.launch(user) log_and_message_admins("launched the [shuttle_tag] shuttle", user) else - alert("The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.") + alert(user, "The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.") diff --git a/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm b/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm index 250d04b0443..d1a86fec98d 100644 --- a/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm +++ b/code/modules/admin/secrets/admin_secrets/launch_shuttle_forced.dm @@ -14,13 +14,13 @@ if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry)) valid_shuttles += shuttle_tag - var/shuttle_tag = input("Which shuttle's launch do you want to force?") as null|anything in valid_shuttles + var/shuttle_tag = input(user, "Which shuttle's launch do you want to force?") as null|anything in valid_shuttles if (!shuttle_tag) return var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag] if (S.can_force()) - S.force_launch(usr) + S.force_launch(user) log_and_message_admins("forced the [shuttle_tag] shuttle", user) else - alert("The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.") + alert(user, "The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.") diff --git a/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm b/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm index 710cdaf4fed..03cb9701c41 100644 --- a/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm +++ b/code/modules/admin/secrets/admin_secrets/list_fingerprints.dm @@ -16,4 +16,4 @@ else if(!H.dna) dat += "[H]H.dna = null" dat += "" - usr << browse(dat, "window=fingerprints;size=440x410") + user << browse(dat, "window=fingerprints;size=440x410") diff --git a/code/modules/admin/secrets/admin_secrets/move_shuttle.dm b/code/modules/admin/secrets/admin_secrets/move_shuttle.dm index e58863afde2..5772bbed54c 100644 --- a/code/modules/admin/secrets/admin_secrets/move_shuttle.dm +++ b/code/modules/admin/secrets/admin_secrets/move_shuttle.dm @@ -9,20 +9,20 @@ . = ..() if(!.) return - var/confirm = alert("This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", "Ok", "Cancel") + var/confirm = alert(user, "This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", "Ok", "Cancel") if (confirm == "Cancel") return - var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles + var/shuttle_tag = input(user, "Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles if (!shuttle_tag) return var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag] - var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + var/origin_area = input(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world if (!origin_area) return - var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world + var/destination_area = input(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world if (!destination_area) return S.move(origin_area, destination_area) - log_and_message_admins("[key_name_admin(usr)] moved the [shuttle_tag] shuttle", user) + log_and_message_admins("moved the [shuttle_tag] shuttle", user) diff --git a/code/modules/admin/secrets/final_solutions/summon_narsie.dm b/code/modules/admin/secrets/final_solutions/summon_narsie.dm new file mode 100644 index 00000000000..8062f767526 --- /dev/null +++ b/code/modules/admin/secrets/final_solutions/summon_narsie.dm @@ -0,0 +1,11 @@ +/datum/admin_secret_item/final_solution/summon_narsie + name = "Summon Nar-Sie" + +/datum/admin_secret_item/final_solution/summon_narsie/execute(var/mob/user) + . = ..() + if(!.) + return + var/choice = input(user, "You sure you want to end the round and summon Nar-Sie at your location? Misuse of this could result in removal of flags or hilarity.") in list("PRAISE SATAN", "Cancel") + if(choice == "PRAISE SATAN") + new /obj/singularity/narsie/large(get_turf(user)) + log_and_message_admins("has summoned Nar-Sie and brought about a new realm of suffering.", user) diff --git a/code/modules/admin/secrets/final_solutions/supermatter_cascade.dm b/code/modules/admin/secrets/final_solutions/supermatter_cascade.dm new file mode 100644 index 00000000000..a50596985c1 --- /dev/null +++ b/code/modules/admin/secrets/final_solutions/supermatter_cascade.dm @@ -0,0 +1,13 @@ +/datum/admin_secret_item/final_solution/supermatter_cascade + name = "Supermatter Cascade" + +/datum/admin_secret_item/final_solution/supermatter_cascade/execute(var/mob/user) + . = ..() + if(!.) + return + var/choice = input(user, "You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.") in list("NO TIME TO EXPLAIN", "Cancel") + if(choice == "NO TIME TO EXPLAIN") + explosion(get_turf(user), 8, 16, 24, 32, 1) + new /turf/unsimulated/wall/supermatter(get_turf(user)) + SetUniversalState(/datum/universal_state/supermatter_cascade) + message_admins("[key_name_admin(user)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(user)]") diff --git a/code/modules/admin/secrets/fun_secrets/break_all_lights.dm b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm index 5c65e389af7..ea54952a7e1 100644 --- a/code/modules/admin/secrets/fun_secrets/break_all_lights.dm +++ b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm @@ -1,7 +1,7 @@ /datum/admin_secret_item/fun_secret/break_all_lights name = "Break All Lights" -/datum/admin_secret_item/fun_secret/make_all_areas_powered/execute(var/mob/user) +/datum/admin_secret_item/fun_secret/break_all_lights/execute(var/mob/user) . = ..() if(.) lightsout(0,0) diff --git a/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm b/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm index 28cd3327c43..33ba8a861ce 100644 --- a/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm +++ b/code/modules/admin/secrets/fun_secrets/toggle_bomb_cap.dm @@ -17,5 +17,5 @@ var/range_dev = max_explosion_range *0.25 var/range_high = max_explosion_range *0.5 var/range_low = max_explosion_range - message_admins("[key_name_admin(usr)] changed the bomb cap to [range_dev], [range_high], [range_low]", 1) - log_admin("[key_name_admin(usr)] changed the bomb cap to [max_explosion_range]") + message_admins("[key_name_admin(user)] changed the bomb cap to [range_dev], [range_high], [range_low]", 1) + log_admin("[key_name_admin(user)] changed the bomb cap to [max_explosion_range]") diff --git a/code/modules/admin/secrets/random_events/gravity.dm b/code/modules/admin/secrets/random_events/gravity.dm index 637bb7129ff..8d4cad49604 100644 --- a/code/modules/admin/secrets/random_events/gravity.dm +++ b/code/modules/admin/secrets/random_events/gravity.dm @@ -22,10 +22,10 @@ feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Grav") if(gravity_is_on) - log_admin("[key_name(usr)] toggled gravity on.", 1) - message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) - command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") + log_admin("[key_name(user)] toggled gravity on.", 1) + message_admins("[key_name_admin(user)] toggled gravity on.", 1) + command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") else - log_admin("[key_name(usr)] toggled gravity off.", 1) - message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) - command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") + log_admin("[key_name(user)] toggled gravity off.", 1) + message_admins("[key_name_admin(usr)] toggled gravity off.", 1) + command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") From 39825d6810eee4c3d33a7a78d641de646c70cd1d Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 11 Aug 2015 15:03:57 +0200 Subject: [PATCH 17/94] Secret entries can now give a warning before being triggered. --- code/modules/admin/admin.dm | 2 +- code/modules/admin/admin_secrets.dm | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 06adf11b571..3ed148c6b17 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -611,7 +611,7 @@ proc/admin_notice(var/message, var/rights) if(category.desc) dat += "[category.desc]
    " for(var/datum/admin_secret_item/item in category.items) - if(!item.can_execute(usr)) + if(!item.can_view(usr)) continue dat += "[item.name()]
    " dat += "
    " diff --git a/code/modules/admin/admin_secrets.dm b/code/modules/admin/admin_secrets.dm index 88a58ff6e83..38bebb844a4 100644 --- a/code/modules/admin/admin_secrets.dm +++ b/code/modules/admin/admin_secrets.dm @@ -33,7 +33,7 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_category/proc/can_view(var/mob/user) for(var/datum/admin_secret_item/item in items) - if(item.can_execute(user)) + if(item.can_view(user)) return 1 return 0 @@ -43,6 +43,7 @@ var/datum/admin_secrets/admin_secrets = new() var/log = 1 var/feedback = 1 var/permissions = R_HOST + var/warn_before_use = 0 /datum/admin_secret_item/dd_SortValue() return "[name]" @@ -50,9 +51,15 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_item/proc/name() return name -/datum/admin_secret_item/proc/can_execute(var/mob/user) +/datum/admin_secret_item/proc/can_view(var/mob/user) return check_rights(permissions, 0, user) +/datum/admin_secret_item/proc/can_execute(var/mob/user) + if(can_view(user)) + if(!warn_before_use || alert("Execute the command '[name]'?", name, "No","Yes") == "Yes") + return 1 + return 0 + /datum/admin_secret_item/proc/execute(var/mob/user) if(!can_execute(user)) return 0 @@ -91,10 +98,12 @@ var/datum/admin_secrets/admin_secrets = new() /datum/admin_secret_item/random_event category = /datum/admin_secret_category/random_events permissions = R_FUN + warn_before_use = 1 /datum/admin_secret_item/fun_secret category = /datum/admin_secret_category/fun_secrets permissions = R_FUN + warn_before_use = 1 /datum/admin_secret_item/final_solution category = /datum/admin_secret_category/final_solutions From 0d4152f9d95d3d5fb90dbee46998857e84532e40 Mon Sep 17 00:00:00 2001 From: Kelenius Date: Thu, 13 Aug 2015 09:05:06 +0300 Subject: [PATCH 18/94] Changelog --- html/changelogs/Kelenius-ofClicksAndCooldowns.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/Kelenius-ofClicksAndCooldowns.yml diff --git a/html/changelogs/Kelenius-ofClicksAndCooldowns.yml b/html/changelogs/Kelenius-ofClicksAndCooldowns.yml new file mode 100644 index 00000000000..a6768a8573e --- /dev/null +++ b/html/changelogs/Kelenius-ofClicksAndCooldowns.yml @@ -0,0 +1,6 @@ +author: Kelenius + +delete-after: True + +changes: + - experiment: "Click cooldowns have been removed on pretty much everything that isn't an attack." From 59d0e28aff1198fa8d1b5cd4987028ea1279213a Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Fri, 31 Jul 2015 02:41:18 +0930 Subject: [PATCH 19/94] Allowed pAIs and AIs loaded into hardsuits to move and rest when control is enabled or the user is unconcious/dead. Allows AIs/pAIs in rigs to use the selected module via middle click. --- code/_onclick/ai.dm | 20 ++- code/_onclick/rig.dm | 4 +- code/game/objects/items/devices/aicard.dm | 14 +- code/game/objects/items/devices/paicard.dm | 12 +- .../clothing/spacesuits/rig/modules/ninja.dm | 10 +- code/modules/clothing/spacesuits/rig/rig.dm | 139 +++++++++++++++++- code/modules/mob/living/carbon/human/death.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 5 + .../mob/living/carbon/human/human_damage.dm | 3 + .../mob/living/carbon/human/human_movement.dm | 4 + code/modules/mob/living/carbon/human/life.dm | 4 + code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 10 ++ code/modules/mob/living/silicon/pai/pai.dm | 15 +- code/modules/mob/mob.dm | 70 +++++---- code/modules/mob/mob_movement.dm | 2 - 16 files changed, 251 insertions(+), 67 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index e05cbeb9ba2..61b67770096 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -99,6 +99,14 @@ /mob/living/silicon/ai/MiddleClickOn(var/atom/A) A.AIMiddleClick(src) +/* + Sticking a minor pAI override into this because I can. +*/ +/mob/living/silicon/pai/MiddleClickOn(var/atom/A) + if(src.loc == src.card) + return A.AIMiddleClick(src) + return ..() + /* The following criminally helpful code is just the previous code cleaned up; I have no idea why it was in atoms.dm instead of respective files. @@ -152,10 +160,18 @@ /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets Topic(src, list("src"= "\ref[src]", "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!) -/atom/proc/AIMiddleClick() - return +/atom/proc/AIMiddleClick(var/mob/living/silicon/user) + var/obj/item/weapon/rig/rig = user.get_rig() + if(rig && rig.wearer && rig.ai_can_move_suit(user, check_user_module = 1)) + if(rig.wearer.HardsuitClickOn(src, alert_ai = 1)) + return 1 + return 0 /obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights. + + if(..()) + return + if(!src.lights) Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!) else diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm index ad9346ec15f..d19101f69b5 100644 --- a/code/_onclick/rig.dm +++ b/code/_onclick/rig.dm @@ -47,13 +47,13 @@ return ..() -/mob/living/carbon/human/proc/HardsuitClickOn(atom/A) +/mob/living/carbon/human/proc/HardsuitClickOn(var/atom/A, var/alert_ai = 0) if(back) var/obj/item/weapon/rig/rig = back if(istype(rig) && rig.selected_module) if(world.time <= next_move) return 1 next_move = world.time + 8 - rig.selected_module.engage(A) + rig.selected_module.engage(A, alert_ai) return 1 return 0 diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 6b239c6b072..3e8c9c69c6e 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -120,10 +120,13 @@ if(user.client) user << "Transfer successful: [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory." + ai.canmove = 1 update_icon() return 1 /obj/item/device/aicard/proc/clear() + if(carded_ai && istype(carded_ai.loc, /turf)) + carded_ai.canmove = 0 name = initial(name) carded_ai = null update_icon() @@ -140,10 +143,9 @@ carded_ai.show_message(rendered, type) ..() -/* /obj/item/device/aicard/relaymove(var/mob/user, var/direction) - if(src.loc && istype(src.loc.loc, /obj/item/rig_module)) - var/obj/item/rig_module/module = src.loc.loc - if(!module.holder || !direction) - return - module.holder.forced_move(direction)*/ + if(user.stat || user.stunned) + return + var/obj/item/weapon/rig/rig = src.get_rig() + if(istype(rig)) + rig.forced_move(direction, user) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index f7fa46678b0..685f2a90431 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -10,12 +10,12 @@ var/looking_for_personality = 0 var/mob/living/silicon/pai/pai -/*/obj/item/device/paicard/relaymove(var/mob/user, var/direction) - if(src.loc && istype(src.loc.loc, /obj/item/rig_module)) - var/obj/item/rig_module/module = src.loc.loc - if(!module.holder || !direction) - return - module.holder.forced_move(direction)*/ +/obj/item/device/paicard/relaymove(var/mob/user, var/direction) + if(user.stat || user.stunned) + return + var/obj/item/weapon/rig/rig = src.get_rig() + if(istype(rig)) + rig.forced_move(direction, user) /obj/item/device/paicard/New() ..() diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index 6b1362a7666..0dfa1bd93e6 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -95,14 +95,14 @@ playsound(T, "sparks", 50, 1) anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) -/obj/item/rig_module/teleporter/engage(atom/target) +/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai) if(!..()) return 0 var/mob/living/carbon/human/H = holder.wearer if(!istype(H.loc, /turf)) - H << "You cannot teleport out of your current location." + usr << "You cannot teleport out of your current location." return 0 var/turf/T @@ -112,15 +112,15 @@ T = get_teleport_loc(get_turf(H), H, rand(5, 9)) if(!T || T.density) - H << "You cannot teleport into solid walls." + usr << "You cannot teleport into solid walls." return 0 if(T.z in config.admin_levels) - H << "You cannot use your teleporter on this Z-level." + usr << "You cannot use your teleporter on this Z-level." return 0 if(T.contains_dense_objects()) - H << "You cannot teleport to a location with solid objects." + usr << "You cannot teleport to a location with solid objects." phase_out(H,get_turf(H)) H.loc = T diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 60197daef79..e949cee66dc 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -27,6 +27,8 @@ var/interface_path = "hardsuit.tmpl" var/ai_interface_path = "hardsuit.tmpl" var/interface_title = "Hardsuit Controller" + var/wearer_move_delay //Used for AI moving. + var/ai_controlled_move_delay = 10 // Keeps track of what this rig should spawn with. var/suit_type = "hardsuit" @@ -326,6 +328,8 @@ else if(offline) offline = 0 + if(istype(wearer) && !wearer.wearing_rig) + wearer.wearing_rig = src chest.slowdown = initial(slowdown) if(offline) @@ -544,11 +548,13 @@ /obj/item/weapon/rig/proc/notify_ai(var/message) if(!message || !installed_modules || !installed_modules.len) - return + return 0 + . = 0 for(var/obj/item/rig_module/module in installed_modules) for(var/mob/living/silicon/ai/ai in module.contents) if(ai && ai.client && !ai.stat) ai << "[message]" + . = 1 /obj/item/weapon/rig/equipped(mob/living/carbon/human/M) ..() @@ -565,6 +571,7 @@ if(istype(M) && M.back == src) M.visible_message("[M] struggles into \the [src].", "You struggle into \the [src].") wearer = M + wearer.wearing_rig = src update_icon() /obj/item/weapon/rig/proc/toggle_piece(var/piece, var/mob/living/carbon/human/H, var/deploy_mode) @@ -676,6 +683,7 @@ ..() for(var/piece in list("helmet","gauntlets","chest","boots")) toggle_piece(piece, user, ONLY_RETRACT) + wearer.wearing_rig = null wearer = null //Todo @@ -757,14 +765,133 @@ return 1 return 0 -/*/obj/item/weapon/rig/proc/forced_move(dir) - if(locked_down) +/obj/item/weapon/rig/proc/ai_can_move_suit(var/mob/user, var/check_user_module = 0, var/check_for_ai = 0) + + if(check_for_ai) + if(!(locate(/obj/item/rig_module/ai_container) in contents)) + return 0 + var/found_ai + for(var/obj/item/rig_module/ai_container/module in contents) + if(module.damage >= 2) + continue + if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat) + found_ai = 1 + break + if(!found_ai) + return 0 + + if(check_user_module) + world << "Checking user module" + if(!user) + world << "No user" + return 0 + if(!user.loc || !user.loc.loc) + world << "No user loc" + return 0 + var/obj/item/rig_module/ai_container/module = user.loc.loc + if(!istype(module) || module.damage >= 2) + user << "Your host module is unable to interface with the suit." + return 0 + + if(offline || !cell || !cell.charge || locked_down) + if(user) user << "Your host rig is unpowered and unresponsive." return 0 - if(!control_overridden) - return if(!wearer || wearer.back != src) + if(user) user << "Your host rig is not being worn." return 0 - wearer.Move(null,dir)*/ + if(!wearer.stat && !control_overridden && !ai_override_enabled) + if(user) user << "You are locked out of the suit servo controller." + return 0 + return 1 + +/obj/item/weapon/rig/proc/force_rest(var/mob/user) + if(!ai_can_move_suit(user, check_user_module = 1)) + return + wearer.lay_down() + user << "\The [wearer] is now [wearer.resting ? "resting" : "getting up"]." + +/obj/item/weapon/rig/proc/forced_move(var/direction, var/mob/user) + + // Why is all this shit in client/Move()? Who knows? + if(world.time < wearer_move_delay) + return + + if(!wearer.loc || !ai_can_move_suit(user, check_user_module = 1)) + return + + //This is sota the goto stop mobs from moving var + if(wearer.transforming || !wearer.canmove) + return + + if(locate(/obj/effect/stop/, wearer.loc)) + for(var/obj/effect/stop/S in wearer.loc) + if(S.victim == wearer) + return + + if(!wearer.lastarea) + wearer.lastarea = get_area(wearer.loc) + + if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0)) + if(!wearer.Process_Spacemove(0)) + return 0 + + if(malfunctioning) + direction = pick(cardinal) + + // Inside an object, tell it we moved. + if(isobj(wearer.loc) || ismob(wearer.loc)) + var/atom/O = wearer.loc + return O.relaymove(wearer, direction) + + if(isturf(wearer.loc)) + if(wearer.restrained())//Why being pulled while cuffed prevents you from moving + for(var/mob/M in range(wearer, 1)) + if(M.pulling == wearer) + if(!M.restrained() && M.stat == 0 && M.canmove && wearer.Adjacent(M)) + user << "Your host is restrained! They can't move!" + return 0 + else + M.stop_pulling() + + if(wearer.pinned.len) + src << "Your host is pinned to a wall by [wearer.pinned[1]]!" + return 0 + + // AIs are a bit slower than regular and ignore move intent. + wearer.last_move_intent = world.time + ai_controlled_move_delay + wearer_move_delay = world.time + ai_controlled_move_delay + + var/tickcomp = 0 + if(config.Tickcomp) + tickcomp = ((1/(world.tick_lag))*1.3) - 1.3 + wearer_move_delay += tickcomp + + if(istype(wearer.buckled, /obj/vehicle)) + //manually set move_delay for vehicles so we don't inherit any mob movement penalties + //specific vehicle move delays are set in code\modules\vehicles\vehicle.dm + wearer_move_delay = world.time + tickcomp + return wearer.buckled.relaymove(wearer, direction) + + if(istype(wearer.machine, /obj/machinery)) + if(wearer.machine.relaymove(wearer, direction)) + return + + if(wearer.pulledby || wearer.buckled) // Wheelchair driving! + if(istype(wearer.loc, /turf/space)) + return // No wheelchair driving in space + if(istype(wearer.pulledby, /obj/structure/bed/chair/wheelchair)) + return wearer.pulledby.relaymove(wearer, direction) + else if(istype(wearer.buckled, /obj/structure/bed/chair/wheelchair)) + if(ishuman(wearer.buckled)) + var/obj/item/organ/external/l_hand = wearer.get_organ("l_hand") + var/obj/item/organ/external/r_hand = wearer.get_organ("r_hand") + if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED))) + return // No hands to drive your chair? Tough luck! + wearer_move_delay += 2 + return wearer.buckled.relaymove(wearer,direction) + + cell.use(200) //Arbitrary, TODO + wearer.Move(get_step(get_turf(wearer),direction),direction) /atom/proc/get_rig() if(loc) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 1eb0b53f04f..ff7255523d3 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -61,11 +61,13 @@ if(!gibbed && species.death_sound) playsound(loc, species.death_sound, 80, 1, 1) - if(ticker && ticker.mode) sql_report_death(src) ticker.mode.check_win() + if(wearing_rig) + wearing_rig.notify_ai("Warning: user death event. Mobility control passed to integrated intelligence system.") + return ..(gibbed,species.death_message) /mob/living/carbon/human/proc/ChangeToHusk() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index dc34cfec3ca..e9daa58d5f6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -7,6 +7,7 @@ var/list/hud_list[10] var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. + var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call. /mob/living/carbon/human/New(var/new_loc, var/new_species = null) @@ -1373,3 +1374,7 @@ if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP)) //magboots + dense_object = no floating return 1 return 0 + +/mob/living/carbon/human/can_stand_overridden() + return wearing_rig && wearing_rig.ai_can_move_suit(check_for_ai = 1) + diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 8f825046097..07f9aab3ec4 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -145,6 +145,9 @@ /mob/living/carbon/human/Paralyse(amount) if(HULK in mutations) return + // Notify our AI if they can now control the suit. + if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second. + wearing_rig.notify_ai("Warning: user consciousness failure. Mobility control passed to integrated intelligence system.") ..() /mob/living/carbon/human/getCloneLoss() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index f4b28d2b6b0..17d125d488a 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,5 +1,9 @@ /mob/living/carbon/human/movement_delay() + // Used by the AI suit control proc. + if(stat) + return 20 + var/tally = 0 if(species.slowdown) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 282831641c2..a55f94e01ae 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -52,6 +52,10 @@ // update the current life tick, can be used to e.g. only do something every 4 ticks life_tick++ + // This is not an ideal place for this but it will do for now. + if(wearing_rig && wearing_rig.offline) + wearing_rig = null + in_stasis = istype(loc, /obj/structure/closet/body_bag/cryobag) && loc:opened == 0 if(in_stasis) loc:used++ diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 632bd4dc737..4212ad0e3a3 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -657,7 +657,7 @@ default behaviour is: set category = "IC" resting = !resting - src << "\blue You are now [resting ? "resting" : "getting up"]" + src << "You are now [resting ? "resting" : "getting up"]." /mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn if(stat) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3004b9dd9e4..f6be9a8a873 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -684,5 +684,15 @@ var/list/ai_verbs_default = list( icon_state = selected_sprite.alive_icon set_light(1, 1, selected_sprite.alive_light) +// Pass lying down or getting up to our pet human, if we're in a rig. +/mob/living/silicon/ai/lay_down() + set name = "Rest" + set category = "IC" + + resting = 0 + var/obj/item/weapon/rig/rig = src.get_rig() + if(istype(rig)) + rig.force_rest(src) + #undef AI_CHECK_WIRELESS #undef AI_CHECK_RADIO diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index ad06c58d6ea..d8d474e438d 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -73,8 +73,6 @@ var/current_pda_messaging = null /mob/living/silicon/pai/New(var/obj/item/device/paicard) - - canmove = 0 src.loc = paicard card = paicard sradio = new(src) @@ -277,8 +275,6 @@ var/obj/item/device/pda/holder = card.loc holder.pai = null - canmove = 1 - src.client.perspective = EYE_PERSPECTIVE src.client.eye = src src.forceMove(get_turf(card)) @@ -340,12 +336,16 @@ set name = "Rest" set category = "IC" + // Pass lying down or getting up to our pet human, if we're in a rig. if(istype(src.loc,/obj/item/device/paicard)) resting = 0 + var/obj/item/weapon/rig/rig = src.get_rig() + if(istype(rig)) + rig.force_rest(src) else resting = !resting icon_state = resting ? "[chassis]_rest" : "[chassis]" - src << "\blue You are now [resting ? "resting" : "getting up"]" + src << "You are now [resting ? "resting" : "getting up"]" canmove = !resting @@ -394,7 +394,8 @@ card.loc = get_turf(card) src.forceMove(card) card.forceMove(card.loc) - canmove = 0 + canmove = 1 + resting = 0 icon_state = "[chassis]" /mob/living/silicon/pai/start_pulling(var/atom/movable/AM) @@ -430,4 +431,4 @@ get_scooped(H) return else - return ..() + return ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9f24c4e1a17..4c9013d9dcb 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -689,40 +689,52 @@ if(transforming) return 0 return 1 +// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet. +/mob/proc/can_stand_overridden() + return 0 + +/mob/proc/cannot_stand() + return stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH) + //Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it. /mob/proc/update_canmove() - if(istype(buckled, /obj/vehicle)) - var/obj/vehicle/V = buckled - if(stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH)) - lying = 1 - canmove = 0 - pixel_y = V.mob_offset_y - 5 - else - if(buckled.buckle_lying != -1) lying = buckled.buckle_lying - canmove = 1 - pixel_y = V.mob_offset_y - else if(buckled) - anchored = 1 - canmove = 0 - if(istype(buckled)) - if(buckled.buckle_lying != -1) - lying = buckled.buckle_lying - if(buckled.buckle_movable) - anchored = 0 - canmove = 1 - else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH)) - lying = 1 - canmove = 0 - else if(stunned) - canmove = 0 - else if(captured) - anchored = 1 - canmove = 0 - lying = 0 - else + if(!resting && cannot_stand() && can_stand_overridden()) lying = 0 canmove = 1 + else + if(istype(buckled, /obj/vehicle)) + var/obj/vehicle/V = buckled + if(cannot_stand()) + lying = 1 + canmove = 0 + pixel_y = V.mob_offset_y - 5 + else + if(buckled.buckle_lying != -1) lying = buckled.buckle_lying + canmove = 1 + pixel_y = V.mob_offset_y + else if(buckled) + anchored = 1 + canmove = 0 + if(istype(buckled)) + if(buckled.buckle_lying != -1) + lying = buckled.buckle_lying + if(buckled.buckle_movable) + anchored = 0 + canmove = 1 + + else if(cannot_stand()) + lying = 1 + canmove = 0 + else if(stunned) + canmove = 0 + else if(captured) + anchored = 1 + canmove = 0 + lying = 0 + else + lying = 0 + canmove = 1 if(lying) density = 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index bb333b82c54..7e47244acc5 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -222,7 +222,6 @@ if(Process_Grab()) return - if(!mob.canmove) return @@ -235,7 +234,6 @@ if((istype(mob.loc, /turf/space)) || (mob.lastarea.has_gravity == 0)) if(!mob.Process_Spacemove(0)) return 0 - if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved var/atom/O = mob.loc return O.relaymove(mob, direct) From 86100ee2a448a4972e16a1f0c109b4293ba9bcdf Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Fri, 31 Jul 2015 06:11:00 +0930 Subject: [PATCH 20/94] Added procs for MMIs to use rigs as piloting AIs. --- code/_onclick/ai.dm | 7 ++++++- code/modules/mob/living/carbon/brain/MMI.dm | 7 +++++++ code/modules/mob/living/carbon/brain/brain.dm | 8 ++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 61b67770096..e57ab01338a 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -100,13 +100,18 @@ A.AIMiddleClick(src) /* - Sticking a minor pAI override into this because I can. + Sticking minor pAI and brain overrides into this because I can. */ /mob/living/silicon/pai/MiddleClickOn(var/atom/A) if(src.loc == src.card) return A.AIMiddleClick(src) return ..() +/mob/living/cabon/bran/MiddleClickOn(var/atom/A) + if(istype(src.loc, /obj/item/device/mmi)) + return A.AIMiddleClick(src) + return ..() + /* The following criminally helpful code is just the previous code cleaned up; I have no idea why it was in atoms.dm instead of respective files. diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 49e8c6ad528..cf143083214 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -122,6 +122,13 @@ locked = 1 return +/obj/item/device/mmi/relaymove(var/mob/user, var/direction) + if(user.stat || user.stunned) + return + var/obj/item/weapon/rig/rig = src.get_rig() + if(istype(rig)) + rig.forced_move(direction, user) + /obj/item/device/mmi/Destroy() if(isrobot(loc)) var/mob/living/silicon/robot/borg = loc diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index e72671d78ad..aaf947a13d4 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -49,12 +49,12 @@ return 1 return ..() - /mob/living/carbon/brain/update_canmove() - if(in_contents_of(/obj/mecha)) + if(in_contents_of(/obj/mecha) || istype(loc, /obj/item/device/mmi)) canmove = 1 - use_me = 1 //If it can move, let it emote - else canmove = 0 + use_me = 1 + else + canmove = 0 return canmove /mob/living/carbon/brain/binarycheck() From b265b3285ca8c8e92b2a5ee7697889f7ba5dd127 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Thu, 13 Aug 2015 17:15:51 +0930 Subject: [PATCH 21/94] Cleaned up some errors, added logging for AI module use. --- code/_onclick/ai.dm | 3 ++- code/modules/clothing/spacesuits/rig/rig.dm | 7 +------ code/modules/mob/living/carbon/human/human_movement.dm | 4 ---- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index e57ab01338a..232a864c0bd 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -107,7 +107,7 @@ return A.AIMiddleClick(src) return ..() -/mob/living/cabon/bran/MiddleClickOn(var/atom/A) +/mob/living/carbon/brain/MiddleClickOn(var/atom/A) if(istype(src.loc, /obj/item/device/mmi)) return A.AIMiddleClick(src) return ..() @@ -169,6 +169,7 @@ var/obj/item/weapon/rig/rig = user.get_rig() if(rig && rig.wearer && rig.ai_can_move_suit(user, check_user_module = 1)) if(rig.wearer.HardsuitClickOn(src, alert_ai = 1)) + message_admins("\The [user] ([user.ckey ? user.ckey : "*no key*"]) forced \the [rig.wearer] ([rig.wearer.ckey ? rig.wearer.ckey : "*no key*"]) to use hardsuit module on \the [src].") return 1 return 0 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index e949cee66dc..40d36b95909 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -781,12 +781,7 @@ return 0 if(check_user_module) - world << "Checking user module" - if(!user) - world << "No user" - return 0 - if(!user.loc || !user.loc.loc) - world << "No user loc" + if(!user || !user.loc || !user.loc.loc) return 0 var/obj/item/rig_module/ai_container/module = user.loc.loc if(!istype(module) || module.damage >= 2) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 17d125d488a..f4b28d2b6b0 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,9 +1,5 @@ /mob/living/carbon/human/movement_delay() - // Used by the AI suit control proc. - if(stat) - return 20 - var/tally = 0 if(species.slowdown) From 825154863ddae603ae525f3c2851870109302348 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Thu, 13 Aug 2015 17:17:11 +0930 Subject: [PATCH 22/94] Changelog. --- html/changelogs/Zuhayr-hardsuits.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/Zuhayr-hardsuits.yml diff --git a/html/changelogs/Zuhayr-hardsuits.yml b/html/changelogs/Zuhayr-hardsuits.yml new file mode 100644 index 00000000000..187e90e25ff --- /dev/null +++ b/html/changelogs/Zuhayr-hardsuits.yml @@ -0,0 +1,4 @@ +author: Zuhayr +delete-after: True +changes: + - rscadd: "Added the ability for AIs in hardsuits to control suit modules and movement with a dead or unconcious wearer." \ No newline at end of file From bb8f7069431d924fb51e32c3d3b99357b068f774 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 17 Jun 2015 20:11:01 -0400 Subject: [PATCH 23/94] Adds armor penetration system --- code/game/objects/objs.dm | 1 + .../mob/living/carbon/human/human_defense.dm | 4 ++-- code/modules/mob/living/living_defense.dm | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index cb3214122a8..d86952d8630 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -13,6 +13,7 @@ var/damtype = "brute" var/force = 0 + var/armorpen = 0 /obj/Destroy() processing_objects -= src diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index cdaad1c42f9..d59a8ce8591 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -227,7 +227,7 @@ emp_act else visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]!") - var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") + var/armor = run_armor_check(affecting, "melee", I.armorpen, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") var/weapon_sharp = is_sharp(I) var/weapon_edge = has_edge(I) if ((weapon_sharp || weapon_edge) && prob(getarmor(target_zone, "melee"))) @@ -342,7 +342,7 @@ emp_act var/hit_area = affecting.name src.visible_message("\red [src] has been hit in the [hit_area] by [O].") - var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here + var/armor = run_armor_check(affecting, "melee", O.armorpen, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here if(armor < 2) apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 2a643044010..190083f2271 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -10,24 +10,33 @@ 1 - halfblock 2 - fullblock */ -/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/absorb_text = null, var/soften_text = null) +/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/armour_pen = 0, var/absorb_text = null, var/soften_text = null) var/armor = getarmor(def_zone, attack_flag) var/absorb = 0 + + //Roll armour if(prob(armor)) absorb += 1 if(prob(armor)) absorb += 1 + + //Roll penetration + if(prob(armour_pen)) + absorb -= 1 + if(prob(armour_pen)) + absorb -= 1 + if(absorb >= 2) if(absorb_text) show_message("[absorb_text]") else - show_message("\red Your armor absorbs the blow!") + show_message("Your armor absorbs the blow!") return 2 if(absorb == 1) if(absorb_text) show_message("[soften_text]",4) else - show_message("\red Your armor softens the blow!") + show_message("Your armor softens the blow!") return 1 return 0 @@ -64,7 +73,7 @@ return //Armor - var/absorb = run_armor_check(def_zone, P.check_armour) + var/absorb = run_armor_check(def_zone, P.check_armour, P.armorpen) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour))) From 0cf21df8b590be79a2840b101f02a4be12a1de23 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 17 Jun 2015 20:59:56 -0400 Subject: [PATCH 24/94] Adjusts projectile values --- code/modules/projectiles/guns/energy/laser.dm | 7 +++---- code/modules/projectiles/projectile/beams.dm | 12 ++++++++++-- code/modules/projectiles/projectile/bullets.dm | 18 +++++++++++------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index b1c47fd6052..3b53c8b5f49 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -7,10 +7,9 @@ slot_flags = SLOT_BELT|SLOT_BACK w_class = 3 force = 10 - origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2) - matter = list(DEFAULT_WALL_MATERIAL = 2000) - projectile_type = /obj/item/projectile/beam - fire_delay = 1 //rapid fire + origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2) + matter = list(DEFAULT_WALL_MATERIAL = 2000) + projectile_type = /obj/item/projectile/beam/midlaser /obj/item/weapon/gun/energy/laser/mounted self_recharge = 1 diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 8aa493404ae..68c61c9d3a9 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -23,10 +23,15 @@ check_armour = "laser" eyeblur = 2 +/obj/item/projectile/beam/midlaser + damage = 40 + armorpen = 10 + /obj/item/projectile/beam/heavylaser name = "heavy laser" icon_state = "heavylaser" damage = 60 + armorpen = 30 muzzle_type = /obj/effect/projectile/laser_heavy/muzzle tracer_type = /obj/effect/projectile/laser_heavy/tracer @@ -35,7 +40,8 @@ /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" - damage = 30 + damage = 25 + armorpen = 50 muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -45,6 +51,7 @@ name = "pulse" icon_state = "u_laser" damage = 50 + armorpen = 30 muzzle_type = /obj/effect/projectile/laser_pulse/muzzle tracer_type = /obj/effect/projectile/laser_pulse/tracer @@ -122,7 +129,8 @@ /obj/item/projectile/beam/sniper name = "sniper beam" icon_state = "xray" - damage = 60 + damage = 50 + armorpen = 10 stun = 3 weaken = 3 stutter = 3 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 2038d718e0d..7a8f44e7f9e 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -119,7 +119,8 @@ /obj/item/projectile/bullet/shotgun name = "slug" - damage = 60 + damage = 50 + armorpen = 15 /obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets name = "beanbag" @@ -139,21 +140,24 @@ /* "Rifle" rounds */ -/obj/item/projectile/bullet/rifle/a762 - damage = 30 +/obj/item/projectile/bullet/rifle + armorpen = 20 penetrating = 1 +/obj/item/projectile/bullet/rifle/a762 + damage = 25 + +/obj/item/projectile/bullet/rifle/a556 + damage = 35 + /obj/item/projectile/bullet/rifle/a145 damage = 80 stun = 3 weaken = 3 penetrating = 5 + armorpen = 50 hitscan = 1 //so the PTR isn't useless as a sniper weapon -/obj/item/projectile/bullet/rifle/a556 - damage = 40 - penetrating = 1 - /* Miscellaneous */ /obj/item/projectile/bullet/suffocationbullet//How does this even work? From 2e8f927085b8560ae6429a8c1c39a4fdc3af70e2 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Thu, 18 Jun 2015 13:01:51 -0400 Subject: [PATCH 25/94] More descriptive variable name Renames armorpen to armor_penetration --- code/game/objects/objs.dm | 2 +- code/modules/mob/living/carbon/human/human_defense.dm | 4 ++-- code/modules/mob/living/living_defense.dm | 2 +- code/modules/projectiles/projectile/beams.dm | 10 +++++----- code/modules/projectiles/projectile/bullets.dm | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index d86952d8630..27bf3b3e632 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -13,7 +13,7 @@ var/damtype = "brute" var/force = 0 - var/armorpen = 0 + var/armor_penetration = 0 /obj/Destroy() processing_objects -= src diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index d59a8ce8591..f16dd51e36e 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -227,7 +227,7 @@ emp_act else visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]!") - var/armor = run_armor_check(affecting, "melee", I.armorpen, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") + var/armor = run_armor_check(affecting, "melee", I.armor_penetration, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") var/weapon_sharp = is_sharp(I) var/weapon_edge = has_edge(I) if ((weapon_sharp || weapon_edge) && prob(getarmor(target_zone, "melee"))) @@ -342,7 +342,7 @@ emp_act var/hit_area = affecting.name src.visible_message("\red [src] has been hit in the [hit_area] by [O].") - var/armor = run_armor_check(affecting, "melee", O.armorpen, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here + var/armor = run_armor_check(affecting, "melee", O.armor_penetration, "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here if(armor < 2) apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 190083f2271..462e47b4f8b 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -73,7 +73,7 @@ return //Armor - var/absorb = run_armor_check(def_zone, P.check_armour, P.armorpen) + var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour))) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 68c61c9d3a9..af93e5cefd4 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -25,13 +25,13 @@ /obj/item/projectile/beam/midlaser damage = 40 - armorpen = 10 + armor_penetration = 10 /obj/item/projectile/beam/heavylaser name = "heavy laser" icon_state = "heavylaser" damage = 60 - armorpen = 30 + armor_penetration = 30 muzzle_type = /obj/effect/projectile/laser_heavy/muzzle tracer_type = /obj/effect/projectile/laser_heavy/tracer @@ -41,7 +41,7 @@ name = "xray beam" icon_state = "xray" damage = 25 - armorpen = 50 + armor_penetration = 50 muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -51,7 +51,7 @@ name = "pulse" icon_state = "u_laser" damage = 50 - armorpen = 30 + armor_penetration = 30 muzzle_type = /obj/effect/projectile/laser_pulse/muzzle tracer_type = /obj/effect/projectile/laser_pulse/tracer @@ -130,7 +130,7 @@ name = "sniper beam" icon_state = "xray" damage = 50 - armorpen = 10 + armor_penetration = 10 stun = 3 weaken = 3 stutter = 3 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 7a8f44e7f9e..292fd44034c 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -120,7 +120,7 @@ /obj/item/projectile/bullet/shotgun name = "slug" damage = 50 - armorpen = 15 + armor_penetration = 15 /obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets name = "beanbag" @@ -141,7 +141,7 @@ /* "Rifle" rounds */ /obj/item/projectile/bullet/rifle - armorpen = 20 + armor_penetration = 20 penetrating = 1 /obj/item/projectile/bullet/rifle/a762 @@ -155,7 +155,7 @@ stun = 3 weaken = 3 penetrating = 5 - armorpen = 50 + armor_penetration = 50 hitscan = 1 //so the PTR isn't useless as a sniper weapon /* Miscellaneous */ From 76b6b902990fea4a495b5b2879fa5e4e5f18686a Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 26 Jun 2015 23:33:43 -0400 Subject: [PATCH 26/94] Adds armor_penetration values to energy weapons --- code/game/objects/items/weapons/melee/energy.dm | 4 +++- code/modules/mob/living/living_defense.dm | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 68763103431..d53760211a5 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -5,6 +5,7 @@ var/active_w_class sharp = 0 edge = 0 + armor_penetration = 50 flags = NOBLOODY /obj/item/weapon/melee/energy/proc/activate(mob/living/user) @@ -173,7 +174,8 @@ name = "energy blade" desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal." icon_state = "blade" - force = 70.0//Normal attacks deal very high damage. + force = 40 //Normal attacks deal very high damage - about the same as wielded fire axe + armor_penetration = 100 sharp = 1 edge = 1 anchored = 1 // Never spawned outside of inventory, should be fine. diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 462e47b4f8b..a605a5f8503 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -11,6 +11,9 @@ 2 - fullblock */ /mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/armour_pen = 0, var/absorb_text = null, var/soften_text = null) + if(armour_pen >= 100) + return 0 //might as well just skip the processing + var/armor = getarmor(def_zone, attack_flag) var/absorb = 0 From 6404d02c38c2a5f143ec2b963c2a47c830579f4f Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Thu, 13 Aug 2015 18:11:34 -0400 Subject: [PATCH 27/94] Adds changelog and tweaks PTR penetration. --- .../modules/projectiles/projectile/bullets.dm | 2 +- html/changelogs/HarpyEagle-armourpen.yml | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 html/changelogs/HarpyEagle-armourpen.yml diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 292fd44034c..cc18d93d870 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -155,7 +155,7 @@ stun = 3 weaken = 3 penetrating = 5 - armor_penetration = 50 + armor_penetration = 80 hitscan = 1 //so the PTR isn't useless as a sniper weapon /* Miscellaneous */ diff --git a/html/changelogs/HarpyEagle-armourpen.yml b/html/changelogs/HarpyEagle-armourpen.yml new file mode 100644 index 00000000000..28599d484f5 --- /dev/null +++ b/html/changelogs/HarpyEagle-armourpen.yml @@ -0,0 +1,34 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: HarpyEagle + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +changes: + - rscadd: "Adds armour penetration mechanic for projectiles and melee weapons." + - rscadd: "Laser carbines, LWAP, and shotgun now have a small amount of armour penetration, ballistic rifles (not SMGs) have moderate amounts, laser cannon has high armour penetration, and the PTR mostly ignores body armour." + - tweak: "Shotgun slugs and Z8/STS damage has been lowered slightly to accomodate for their higher penetration. In general ballistics deal less damage but have higher penetration than comparable laser weapons. Notable exception: X-Ray lasers have had their damage lowered slightly but gain very high armour penetration." + - rscadd: "Energy swords now have very high armour penetration. Ninja blades do less damage but ignore armour completely." From 15f54c595bdc6401e58a4e7259aaa308e2486e44 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Mon, 17 Aug 2015 09:12:40 +0200 Subject: [PATCH 28/94] Synths now relies on access permissions as well. Ensures station bound synthetics will not be able to utilize Syndicate/Heist equipment/vessels, as well as the opposite for potential syndicate synths. --- code/datums/wires/airlock.dm | 2 +- code/game/jobs/access.dm | 4 ++-- code/game/objects/objs.dm | 14 ++++++++++++-- code/modules/mob/living/silicon/robot/robot.dm | 1 + .../mob/living/silicon/robot/robot_items.dm | 7 ------- code/modules/mob/living/silicon/silicon.dm | 4 ++++ 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index a0f1f9c7f1c..3c247d6c7f9 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -161,7 +161,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 if(A.emagged) return if(!A.requiresID() || A.check_access(null)) if(A.density) A.open() - else A.close() + else A.close() if(AIRLOCK_WIRE_SAFETY) A.safe = !A.safe if(!A.density) diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 09fc65bf417..b364db8c772 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -9,8 +9,8 @@ if(src.check_access(null)) return 1 if(istype(M, /mob/living/silicon)) - //AI can do whatever he wants - return 1 + var/mob/living/silicon/S = M + return check_access_list(S.access_rights) else if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M //if they are holding or wearing a card that has access, that works diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index cfa2de777b2..afe246ba17b 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -33,9 +33,19 @@ CouldNotUseTopic(usr) return 1 +/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state) + if(user.CanUseObjTopic(src)) + return ..() + return STATUS_CLOSE + +/mob/living/silicon/CanUseObjTopic(var/obj/O) + return O.allowed(src) + +/mob/proc/CanUseObjTopic() + /obj/proc/CouldUseTopic(var/mob/user) var/atom/host = nano_host() - host.add_fingerprint(user) + host.add_hiddenprint(user) /obj/proc/CouldNotUseTopic(var/mob/user) // Nada @@ -142,4 +152,4 @@ return /obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) - return + return diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 1159545a54d..85541c3acf4 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -179,6 +179,7 @@ playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) /mob/living/silicon/robot/syndicate/init() + access_rights = list(access_syndicate) aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) laws = new /datum/ai_laws/syndicate_override diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index ade9bf0f930..2d591f4c36b 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -105,13 +105,6 @@ desc = "A circuit grafted onto the bottom of an ID card. It is used to transmit access codes into other robot chassis, \ allowing you to lock and unlock other robots' panels." -/obj/item/weapon/card/id/robot/attack_self() //override so borgs can't flash their IDs. - return - -/obj/item/weapon/card/id/robot/read() - usr << "The ID card does not appear to have any writing on it." - return - //A harvest item for serviceborgs. /obj/item/weapon/robot_harvester name = "auto harvester" diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 9bb71d22103..c39482cc229 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -23,12 +23,16 @@ var/next_alarm_notice var/list/datum/alarm/queued_alarms = new() + var/list/access_rights + #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode /mob/living/silicon/New() silicon_mob_list |= src ..() + access_rights = get_all_station_access() + access_rights = access_rights.Copy() add_language("Galactic Common") init_subsystems() From a4b3ab1ca54995541254cc8651c13cb9d92f1bd3 Mon Sep 17 00:00:00 2001 From: FrickenChris101 Date: Wed, 19 Aug 2015 20:17:59 -0400 Subject: [PATCH 29/94] Flashlight Icon toggle fix Just added additional code to update_brightness call and initialize.. Wasn't properly reflecting light being on or off. --- code/game/objects/items/devices/flashlight.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 2b0f5920ce3..c9de89d29cd 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -20,7 +20,7 @@ icon_state = "[initial(icon_state)]-on" set_light(brightness_on) else - icon_state = initial(icon_state) + icon_state = "[initial(icon_state)]" set_light(0) /obj/item/device/flashlight/proc/update_brightness(var/mob/user = null) @@ -28,6 +28,7 @@ icon_state = "[initial(icon_state)]-on" set_light(brightness_on) else + icon_state = "[initial(icon_state)]" set_light(0) /obj/item/device/flashlight/attack_self(mob/user) From efc3121f6883e92e9adbfb6cbe928c0db4b69a5c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 19 Aug 2015 20:38:50 -0400 Subject: [PATCH 30/94] Fixes reinforcing girders through windows, unbalanced span --- code/game/objects/structures/girders.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 98947a2dae9..d6c406f07e9 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -165,7 +165,7 @@ set src in view(1) var/mob/living/user = usr - if(!istype(user) || !(user.l_hand || user.r_hand)) + if(!istype(user) || !(user.l_hand || user.r_hand) || !Adjacent(user)) return if(reinf_material) @@ -248,7 +248,7 @@ dismantle() else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - user << "Now slicing apart the girder..." + user << "Now slicing apart the girder..." if(do_after(user,30)) user << "You slice apart the girder!" dismantle() From c97b1d4ea489ef716b86b42d98073e5a92aaa7ee Mon Sep 17 00:00:00 2001 From: DelZeta Date: Thu, 20 Aug 2015 01:14:41 -0700 Subject: [PATCH 31/94] Fixes permahallucinations. --- code/modules/mob/living/carbon/human/life.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index ac8848dcb1c..ea570e42e12 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -963,6 +963,11 @@ spawn(rand(20,50)) if(C) C.dir = 1 + if(hallucination <= 2) + hallucination = 0 + halloss = 0 + else + hallucination -= 2 else for(var/atom/a in hallucinations) From 81ccf07d809d980e1bf16eef3098314840b159ca Mon Sep 17 00:00:00 2001 From: DelZeta Date: Thu, 20 Aug 2015 02:26:46 -0700 Subject: [PATCH 32/94] Halloss now decays naturally after hallucinations, to avoid edge cases with other sources. --- code/modules/mob/living/carbon/human/life.dm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index ea570e42e12..631be0d51ab 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -963,12 +963,9 @@ spawn(rand(20,50)) if(C) C.dir = 1 - if(hallucination <= 2) + hallucination -= 2 + if(hallucination < 0) hallucination = 0 - halloss = 0 - else - hallucination -= 2 - else for(var/atom/a in hallucinations) qdel(a) From c2e2252342cf126b235abda5dd966b463393a18d Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Thu, 20 Aug 2015 12:21:06 +0200 Subject: [PATCH 33/94] Synth access and icon update changes. Refactors how synthetics set their modules. On login, if appearance selection was initiated but not finalized, the selection options popup again. Fixes a long-standing issue of borgs being able to look like the standard module by loging out. Ensures the syndicate agent IDs and syndicate borgs will always have the same initial access permissions. Removes now unnecessary syndicate snowflake code from NanoUI. Synths now utilize actual ids. --- baystation12.dme | 1 + code/_helpers/global_lists.dm | 2 + code/game/jobs/access.dm | 33 ++++--- code/game/machinery/computer/camera.dm | 4 + .../objects/items/robot/robot_upgrades.dm | 2 - code/game/objects/items/weapons/cards_ids.dm | 2 +- code/game/objects/objs.dm | 1 + code/global.dm | 2 +- .../modules/mob/living/silicon/robot/login.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 86 ++++++------------- .../mob/living/silicon/robot/robot_modules.dm | 9 +- .../mob/living/silicon/robot/syndicate.dm | 27 ++++++ code/modules/mob/living/silicon/silicon.dm | 5 +- code/modules/mob/mob_helpers.dm | 2 +- code/modules/nano/interaction/base.dm | 2 +- code/modules/nano/interaction/default.dm | 15 ---- 16 files changed, 100 insertions(+), 97 deletions(-) create mode 100644 code/modules/mob/living/silicon/robot/syndicate.dm diff --git a/baystation12.dme b/baystation12.dme index 785542bb733..17063261aba 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1318,6 +1318,7 @@ #include "code\modules\mob\living\silicon\robot\robot_items.dm" #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" +#include "code\modules\mob\living\silicon\robot\syndicate.dm" #include "code\modules\mob\living\silicon\robot\drone\drone.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_console.dm" diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 09e6f845c86..bc841e533ca 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -64,6 +64,8 @@ var/global/list/rune_list = new() var/global/list/escape_list = list() var/global/list/endgame_exits = list() var/global/list/endgame_safespawns = list() + +var/global/list/syndicate_access = list(access_maint_tunnels, access_syndicate, access_external_airlocks) ////////////////////////// /////Initial Building///// ////////////////////////// diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index b364db8c772..1be9e37766d 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -8,14 +8,10 @@ //check if it doesn't require any access at all if(src.check_access(null)) return 1 - if(istype(M, /mob/living/silicon)) - var/mob/living/silicon/S = M - return check_access_list(S.access_rights) - else if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - //if they are holding or wearing a card that has access, that works - if(src.check_access(H.get_active_hand()) || src.check_access(H.wear_id)) - return 1 + + var/id = M.GetIdCard() + if(id) + return check_access(id) return 0 /obj/item/proc/GetAccess() @@ -179,18 +175,27 @@ "Emergency Response Team", "Emergency Response Team Leader") -proc/GetIdCard(var/mob/living/carbon/human/H) - if(H.wear_id) - var/id = H.wear_id.GetID() +/mob/proc/GetIdCard() + return null + +/mob/living/bot/GetIdCard() + return botcard + +/mob/living/carbon/human/GetIdCard() + if(wear_id) + var/id = wear_id.GetID() if(id) return id - if(H.get_active_hand()) - var/obj/item/I = H.get_active_hand() + if(get_active_hand()) + var/obj/item/I = get_active_hand() return I.GetID() +/mob/living/silicon/GetIdCard() + return idcard + proc/FindNameFromID(var/mob/living/carbon/human/H) ASSERT(istype(H)) - var/obj/item/weapon/card/id/C = GetIdCard(H) + var/obj/item/weapon/card/id/C = H.GetIdCard() if(C) return C.registered_name diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 8d85a63224c..4b8b9a9acf3 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -257,3 +257,7 @@ icon_state = "syndicam" network = list("NUKE") circuit = null + +/obj/machinery/computer/security/nuclear/New() + ..() + req_access = list(150) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 999303a91dd..6eabb2bd1e2 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -31,8 +31,6 @@ R.modtype = initial(R.modtype) R.hands.icon_state = initial(R.hands.icon_state) - R.choose_icon(1, R.set_module_sprites(list("Default" = "robot"))) - R.notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, R.module.name) R.module.Reset(R) R.updatename("Default") diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 17a27aa85e5..e69d61ee7ab 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -154,12 +154,12 @@ /obj/item/weapon/card/id/syndicate name = "agent card" - access = list(access_maint_tunnels, access_syndicate, access_external_airlocks) origin_tech = list(TECH_ILLEGAL = 3) var/registered_user=null /obj/item/weapon/card/id/syndicate/New(mob/user as mob) ..() + access = syndicate_access.Copy() if(!isnull(user)) // Runtime prevention on laggy starts or where users log out because of lag at round start. registered_name = ishuman(user) ? user.real_name : user.name else diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 2f9c3c5e7f9..cfea392be09 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -36,6 +36,7 @@ /obj/CanUseTopic(var/mob/user, var/datum/topic_state/state) if(user.CanUseObjTopic(src)) return ..() + user << "\icon[src]Access Denied!" return STATUS_CLOSE /mob/living/silicon/CanUseObjTopic(var/obj/O) diff --git a/code/global.dm b/code/global.dm index 2d1e4a0548c..4e26bbccc56 100644 --- a/code/global.dm +++ b/code/global.dm @@ -177,4 +177,4 @@ var/max_explosion_range = 14 // Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. var/global/obj/item/device/radio/intercom/global_announcer = new(null) -var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") \ No newline at end of file +var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index eac71acfcdd..9d9117b9330 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -5,4 +5,6 @@ winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5") - return \ No newline at end of file + // Forces synths to select an icon relevant to their module + if(!icon_selected) + choose_icon(icon_selection_tries, module_sprites) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index da9d1581148..7ca869ea26a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -24,8 +24,10 @@ //Icon stuff - var/icontype //Persistent icontype tracking allows for cleaner icon updates - var/module_sprites[0] //Used to store the associations between sprite names and sprite index. + var/icontype //Persistent icontype tracking allows for cleaner icon updates + var/module_sprites[0] //Used to store the associations between sprite names and sprite index. + var/icon_selected = 1 //If icon selection has been completed yet + var/icon_selection_tries = 0//Remaining attempts to select icon before a selection is forced //Hud stuff @@ -89,21 +91,6 @@ /mob/living/silicon/robot/proc/robot_checklaws ) -/mob/living/silicon/robot/syndicate - lawupdate = 0 - scrambledcodes = 1 - icon_state = "securityrobot" - modtype = "Security" - lawchannel = "State" - -/mob/living/silicon/robot/syndicate/New() - if(!cell) - cell = new /obj/item/weapon/cell(src) - cell.maxcharge = 25000 - cell.charge = 25000 - - ..() - /mob/living/silicon/robot/New(loc,var/unfinished = 0) spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) @@ -178,18 +165,6 @@ playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) -/mob/living/silicon/robot/syndicate/init() - access_rights = list(access_syndicate) - aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) - - laws = new /datum/ai_laws/syndicate_override - new /obj/item/weapon/robot_module/syndicate(src) - - radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio) - radio.recalculateChannels() - - playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) - /mob/living/silicon/robot/SetName(pickedName as text) custom_name = pickedName updatename() @@ -242,10 +217,15 @@ ..() /mob/living/silicon/robot/proc/set_module_sprites(var/list/new_sprites) - module_sprites = new_sprites + module_sprites = new_sprites.Copy() //Custom_sprite check and entry if (custom_sprite == 1) module_sprites["Custom"] = "[src.ckey]-[modtype]" + icontype = "Custom" + else + icontype = module_sprites[1] + icon_state = module_sprites[icontype] + updateicon() return module_sprites /mob/living/silicon/robot/proc/pick_module() @@ -256,7 +236,7 @@ if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately. src << "\red Crisis mode active. Combat module available." modules+="Combat" - modtype = input("Please, select a module!", "Robot", null, null) in modules + modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules if(module) return @@ -269,8 +249,6 @@ hands.icon_state = lowertext(modtype) feedback_inc("cyborg_[lowertext(modtype)]",1) updatename() - set_module_sprites(module.sprites) - choose_icon(module_sprites.len + 1, module_sprites) notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name) /mob/living/silicon/robot/proc/updatename(var/prefix as text) @@ -689,7 +667,7 @@ /mob/living/silicon/robot/updateicon() overlays.Cut() - if(stat == 0) + if(stat == CONSCIOUS) overlays += "eyes-[module_sprites[icontype]]" if(opened) @@ -917,38 +895,30 @@ return /mob/living/silicon/robot/proc/choose_icon(var/triesleft, var/list/module_sprites) - if(triesleft<1 || !module_sprites.len) - return - else - triesleft-- - - if (custom_sprite == 1) - icontype = "Custom" - triesleft = 0 - else if(module_sprites.len == 1) - icontype = module_sprites[1] - else - icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chances." : "This is your last try."]", "Robot", null, null) in module_sprites - - if(icontype) - icon_state = module_sprites[icontype] - else + if(!module_sprites.len) src << "Something is badly wrong with the sprite selection. Harass a coder." - icon_state = module_sprites[1] return + icon_selected = 0 + src.icon_selection_tries = triesleft + if(module_sprites.len == 1 || !client) + if(!(icontype in module_sprites)) + icontype = module_sprites[1] + else + icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chance\s." : "This is your last try."]", "Robot", icontype, null) in module_sprites + icon_state = module_sprites[icontype] updateicon() - if (triesleft >= 1) + if (module_sprites.len > 1 && triesleft >= 1 && client) + icon_selection_tries-- var/choice = input("Look at your icon - is this what you want?") in list("Yes","No") if(choice=="No") - choose_icon(triesleft, module_sprites) + choose_icon(icon_selection_tries, module_sprites) return - else - triesleft = 0 - return - else - src << "Your icon has been set. You now require a module reset to change it." + + icon_selected = 1 + icon_selection_tries = 0 + src << "Your icon has been set. You now require a module reset to change it." /mob/living/silicon/robot/proc/sensor_mode() //Medical/Security HUD controller for borgs set name = "Set Sensor Augmentation" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 6c453256c45..d1a719356db 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -49,6 +49,9 @@ var/global/list/robot_modules = list( if(R.radio) R.radio.recalculateChannels() + R.set_module_sprites(sprites) + R.choose_icon(R.module_sprites.len + 1, R.module_sprites) + /obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R) R.module = null @@ -59,6 +62,7 @@ var/global/list/robot_modules = list( if(R.radio) R.radio.recalculateChannels() + R.choose_icon(0, R.set_module_sprites(list("Default" = "robot"))) qdel(src) @@ -507,7 +511,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/tray/robotray(src) src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src) - src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) + src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) var/datum/reagents/R = new/datum/reagents(50) src.emag.reagents = R @@ -617,6 +621,9 @@ var/global/list/robot_modules = list( LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 1 ) + sprites = list( + "Dread" = "securityrobot", + ) /obj/item/weapon/robot_module/syndicate/New(var/mob/living/silicon/robot/R) ..() diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm new file mode 100644 index 00000000000..bf6dc64588e --- /dev/null +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -0,0 +1,27 @@ +/mob/living/silicon/robot/syndicate + lawupdate = 0 + scrambledcodes = 1 + icon_state = "securityrobot" + modtype = "Security" + lawchannel = "State" + +/mob/living/silicon/robot/syndicate/New() + if(!cell) + cell = new /obj/item/weapon/cell(src) + cell.maxcharge = 25000 + cell.charge = 25000 + + ..() + +/mob/living/silicon/robot/syndicate/init() + idcard = new/obj/item/weapon/card/id/syndicate(src) + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + + laws = new /datum/ai_laws/syndicate_override + overlays.Cut() + new /obj/item/weapon/robot_module/syndicate(src) + + radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio) + radio.recalculateChannels() + + playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index ebae3a56ae6..ab08029f509 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -24,6 +24,7 @@ var/list/datum/alarm/queued_alarms = new() var/list/access_rights + var/obj/item/weapon/card/id/idcard #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode @@ -31,10 +32,10 @@ /mob/living/silicon/New() silicon_mob_list |= src ..() - access_rights = get_all_station_access() - access_rights = access_rights.Copy() add_language("Galactic Common") init_subsystems() + if(!idcard) + idcard = new/obj/item/weapon/card/id/captains_spare(src) /mob/living/silicon/Destroy() silicon_mob_list -= src diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index f2e9e958681..e87e486ff37 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -632,7 +632,7 @@ proc/is_blind(A) return SAFE_PERP //Agent cards lower threatlevel. - var/obj/item/weapon/card/id/id = GetIdCard(src) + var/obj/item/weapon/card/id/id = GetIdCard() if(id && istype(id, /obj/item/weapon/card/id/syndicate)) threatcount -= 2 // A proper CentCom id is hard currency. diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm index cf5424bdc00..ccd9f3740b3 100644 --- a/code/modules/nano/interaction/base.dm +++ b/code/modules/nano/interaction/base.dm @@ -14,7 +14,7 @@ /mob/proc/shared_nano_interaction() if (src.stat || !client) return STATUS_CLOSE // no updates, close the interface - else if (restrained() || lying || stat || stunned || weakened) + else if (incapacitated()) return STATUS_UPDATE // update only (orange visibility) return STATUS_INTERACTIVE diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm index 79c08227d5a..216f40b9483 100644 --- a/code/modules/nano/interaction/default.dm +++ b/code/modules/nano/interaction/default.dm @@ -30,21 +30,6 @@ return STATUS_INTERACTIVE // interactive (green visibility) return STATUS_DISABLED // no updates, completely disabled (red visibility) -/mob/living/silicon/robot/syndicate/default_can_use_topic(var/src_object) - . = ..() - if(. != STATUS_INTERACTIVE) - return - - if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level - return STATUS_INTERACTIVE - if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle - return STATUS_INTERACTIVE - if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery - var/obj/machinery/Machine = src_object - if(Machine.emagged) - return STATUS_INTERACTIVE - return STATUS_UPDATE - /mob/living/silicon/ai/default_can_use_topic(var/src_object) . = shared_nano_interaction() if(. != STATUS_INTERACTIVE) From cd06409a1f4386b2b92d6cb4e77cb6a978748317 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Thu, 20 Aug 2015 13:23:42 +0200 Subject: [PATCH 34/94] Makes it possible for syndicate borgs to copy access from other ids. --- code/game/antagonist/antagonist_create.dm | 2 +- code/game/antagonist/antagonist_update.dm | 3 +- code/game/jobs/job_controller.dm | 2 +- code/game/machinery/camera/tracking.dm | 9 ++---- .../objects/items/devices/uplink_items.dm | 2 +- .../objects/items/robot/robot_upgrades.dm | 2 ++ code/game/objects/items/weapons/cards_ids.dm | 31 ++++++++++++------- .../items/weapons/cards_ids_syndicate.dm | 7 ++--- code/modules/awaymissions/corpse.dm | 2 +- .../mob/living/silicon/robot/robot_modules.dm | 23 +++++++++----- .../mob/living/silicon/robot/syndicate.dm | 3 +- code/modules/mob/living/silicon/silicon.dm | 10 ++++-- 12 files changed, 58 insertions(+), 38 deletions(-) diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm index 69b7f8e9d0c..072dd88bee4 100644 --- a/code/game/antagonist/antagonist_create.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -36,7 +36,7 @@ if(!W) return W.access |= default_access W.assignment = "[assignment]" - W.set_owner_info(player) + player.set_id_info(W) if(equip) player.equip_to_slot_or_del(W, slot_wear_id) return W diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index 0fd5fb2a93f..d4999f0183a 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -19,8 +19,7 @@ /datum/antagonist/proc/update_access(var/mob/living/player) for(var/obj/item/weapon/card/id/id in player.contents) - id.name = "[player.real_name]'s ID Card" - id.registered_name = player.real_name + player.set_id_info(id) /datum/antagonist/proc/update_all_icons() if(!antag_indicator) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index ff994e8cd3b..f3757559823 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -528,7 +528,7 @@ var/global/datum/controller/occupations/job_master if(C) C.rank = rank C.assignment = title ? title : rank - C.set_owner_info(H) + H.set_id_info(C) //put the player's account number onto the ID if(H.mind && H.mind.initial_account) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 65324f5555f..739583ede88 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -223,6 +223,9 @@ mob/living/proc/near_camera() /mob/living/proc/tracking_status() // Easy checks first. // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. + var/obj/item/weapon/card/id/id = GetIdCard() + if(id && id.prevent_tracking()) + return TRACKING_TERMINATE if(InvalidPlayerTurf(get_turf(src))) return TRACKING_TERMINATE if(invisibility >= INVISIBILITY_LEVEL_ONE) //cloaked @@ -240,14 +243,8 @@ mob/living/proc/near_camera() if(. == TRACKING_NO_COVERAGE) return camera && camera.can_use() ? TRACKING_POSSIBLE : TRACKING_NO_COVERAGE -/mob/living/silicon/robot/syndicate/tracking_status() - return TRACKING_TERMINATE - /mob/living/carbon/human/tracking_status() //Cameras can't track people wearing an agent card or a ninja hood. - var/obj/item/weapon/card/id/id = GetIdCard(src) - if(id && id.prevent_tracking()) - return TRACKING_TERMINATE if(istype(head, /obj/item/clothing/head/helmet/space/rig)) var/obj/item/clothing/head/helmet/space/rig/helmet = head if(helmet.prevent_track()) diff --git a/code/game/objects/items/devices/uplink_items.dm b/code/game/objects/items/devices/uplink_items.dm index 939292a6d6f..88361ab7b0b 100644 --- a/code/game/objects/items/devices/uplink_items.dm +++ b/code/game/objects/items/devices/uplink_items.dm @@ -616,7 +616,7 @@ var/image/default_abstract_uplink_icon if(!user) return 0 - var/obj/item/weapon/card/id/I = GetIdCard(user) + var/obj/item/weapon/card/id/I = user.GetIdCard() var/datum/data/record/random_general_record var/datum/data/record/random_medical_record if(data_core.general.len) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 6eabb2bd1e2..1dc489d75eb 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -33,6 +33,8 @@ R.notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, R.module.name) R.module.Reset(R) + qdel(R.module) + R.module = null R.updatename("Default") return 1 diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index ae6bcbdf0ca..a63a0f14cba 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -137,17 +137,26 @@ front = getFlatIcon(M, SOUTH, always_use_defdir = 1) side = getFlatIcon(M, WEST, always_use_defdir = 1) -/obj/item/weapon/card/id/proc/set_owner_info(var/mob/living/carbon/human/H) - if(!H || !H.dna) - return - age = H.age - blood_type = H.dna.b_type - dna_hash = H.dna.unique_enzymes - fingerprint_hash = md5(H.dna.uni_identity) - registered_name = H.real_name - sex = capitalize(H.gender) - set_id_photo(H) - update_name() +/mob/proc/set_id_info(var/obj/item/weapon/card/id/id_card) + id_card.age = 0 + id_card.registered_name = real_name + id_card.sex = capitalize(gender) + id_card.set_id_photo(src) + + if(dna) + id_card.blood_type = dna.b_type + id_card.dna_hash = dna.unique_enzymes + id_card.fingerprint_hash= md5(dna.uni_identity) + id_card.update_name() + +/mob/living/silicon/set_id_info(var/obj/item/weapon/card/id/id_card) + id_card.assignment = "Synthetic" + id_card.rank = "Synthetic" + ..() + +/mob/living/carbon/human/set_id_info(var/obj/item/weapon/card/id/id_card) + ..() + id_card.age = age /obj/item/weapon/card/id/proc/dat() var/dat = ("
    ") diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 2475c93534b..1642766a0e6 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -6,12 +6,11 @@ var/global/list/syndicate_ids = list() origin_tech = list(TECH_ILLEGAL = 3) var/electronic_warfare = 1 var/registered_user = null - var/list/initial_access = list(access_maint_tunnels, access_syndicate, access_external_airlocks) /obj/item/weapon/card/id/syndicate/New(mob/user as mob) syndicate_ids += src ..() - access = initial_access.Copy() + access = syndicate_access.Copy() /obj/item/weapon/card/id/syndicate/Destroy() syndicate_ids -= src @@ -39,7 +38,7 @@ var/global/list/syndicate_ids = list() /obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob) if(!registered_user) registered_user = user - set_owner_info(user) + user.set_id_info(src) user << "The microscanner marks you as its owner, preventing others some accessing its internals." if(registered_user == user) switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show")) @@ -163,7 +162,7 @@ var/global/list/syndicate_ids = list() if("Factory Reset") if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state)) age = initial(age) - access = initial_access.Copy() + access = syndicate_access.Copy() assignment = initial(assignment) blood_type = initial(blood_type) dna_hash = initial(dna_hash) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 6cd91f07ef4..09fd236be0d 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -74,7 +74,7 @@ W.access = list() if(corpseidjob) W.assignment = corpseidjob - W.set_owner_info(M) + M.set_id_info(W) M.equip_to_slot_or_del(W, slot_wear_id) qdel(src) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index d1a719356db..08e56dc905b 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -53,8 +53,6 @@ var/global/list/robot_modules = list( R.choose_icon(R.module_sprites.len + 1, R.module_sprites) /obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R) - R.module = null - remove_camera_networks(R) remove_languages(R) remove_subsystems(R) @@ -64,15 +62,15 @@ var/global/list/robot_modules = list( R.radio.recalculateChannels() R.choose_icon(0, R.set_module_sprites(list("Default" = "robot"))) - qdel(src) - /obj/item/weapon/robot_module/Destroy() - qdel(modules) - qdel(synths) + for(var/module in modules) + qdel(module) + for(var/synth in synths) + qdel(synths) + modules.Cut() + synths.Cut() qdel(emag) qdel(jetpack) - modules = null - synths = null emag = null jetpack = null return ..() @@ -624,6 +622,7 @@ var/global/list/robot_modules = list( sprites = list( "Dread" = "securityrobot", ) + var/id /obj/item/weapon/robot_module/syndicate/New(var/mob/living/silicon/robot/R) ..() @@ -635,8 +634,16 @@ var/global/list/robot_modules = list( var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src) src.modules += jetpack R.internals = jetpack + + id = R.idcard + src.modules += id return +/obj/item/weapon/robot_module/syndicate/Destroy() + src.modules -= id + id = null + return ..() + /obj/item/weapon/robot_module/security/combat name = "combat robot module" sprites = list("Combat Android" = "droid-combat") diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm index bf6dc64588e..af46cd6fcf5 100644 --- a/code/modules/mob/living/silicon/robot/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -4,6 +4,7 @@ icon_state = "securityrobot" modtype = "Security" lawchannel = "State" + idcard_type = /obj/item/weapon/card/id/syndicate /mob/living/silicon/robot/syndicate/New() if(!cell) @@ -14,11 +15,11 @@ ..() /mob/living/silicon/robot/syndicate/init() - idcard = new/obj/item/weapon/card/id/syndicate(src) aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) laws = new /datum/ai_laws/syndicate_override overlays.Cut() + init_id() new /obj/item/weapon/robot_module/syndicate(src) radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index ab08029f509..ac3feba0765 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -25,6 +25,7 @@ var/list/access_rights var/obj/item/weapon/card/id/idcard + var/idcard_type = /obj/item/weapon/card/id/captains_spare #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode @@ -33,9 +34,8 @@ silicon_mob_list |= src ..() add_language("Galactic Common") + init_id() init_subsystems() - if(!idcard) - idcard = new/obj/item/weapon/card/id/captains_spare(src) /mob/living/silicon/Destroy() silicon_mob_list -= src @@ -43,6 +43,12 @@ AH.unregister(src) ..() +/mob/living/silicon/proc/init_id() + if(idcard) + return + idcard = new idcard_type(src) + set_id_info(idcard) + /mob/living/silicon/proc/SetName(pickedName as text) real_name = pickedName name = real_name From af008b03f804afdd4054ae1b40d33e83702ca80f Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Thu, 20 Aug 2015 14:01:10 +0200 Subject: [PATCH 35/94] Changelog entries. --- html/changelogs/PsiOmegaDelta-SpoonRevolt.yml | 2 +- html/changelogs/PsiOmegaDelta-SynthAccess.yml | 7 +++++++ html/changelogs/PsiOmegaDelta-Uplinkery.yml | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 html/changelogs/PsiOmegaDelta-SynthAccess.yml diff --git a/html/changelogs/PsiOmegaDelta-SpoonRevolt.yml b/html/changelogs/PsiOmegaDelta-SpoonRevolt.yml index c26ad21ff53..1c47ad71b23 100644 --- a/html/changelogs/PsiOmegaDelta-SpoonRevolt.yml +++ b/html/changelogs/PsiOmegaDelta-SpoonRevolt.yml @@ -1,4 +1,4 @@ author: PsiOmegaDelta delete-after: True changes: - - rscdel: "The Dinnerware vending machine now offer both utensil knives and spoons without first having to hack them." + - rscadd: "The Dinnerware vending machine now offer both utensil knives and spoons without first having to hack them." diff --git a/html/changelogs/PsiOmegaDelta-SynthAccess.yml b/html/changelogs/PsiOmegaDelta-SynthAccess.yml new file mode 100644 index 00000000000..689e8697630 --- /dev/null +++ b/html/changelogs/PsiOmegaDelta-SynthAccess.yml @@ -0,0 +1,7 @@ +author: PsiOmegaDelta +delete-after: True +changes: + - rscadd: "Synths now have id cards with access levels which is checked when operating most station equipment." + - rscadd: "Station synthetics still have full station access but can no longer interact with syndicate equipment, and syndicate borgs now start with only syndicate access." + - rscadd: "Syndicate borgs can copy the access from other cards by utilizing their own id card module, similar to how syndicate ids work." + diff --git a/html/changelogs/PsiOmegaDelta-Uplinkery.yml b/html/changelogs/PsiOmegaDelta-Uplinkery.yml index c8b8f5e31c0..8ee40286e3b 100644 --- a/html/changelogs/PsiOmegaDelta-Uplinkery.yml +++ b/html/changelogs/PsiOmegaDelta-Uplinkery.yml @@ -2,7 +2,8 @@ author: PsiOmegaDelta delete-after: true changes: - rscadd: "When examined up close id cards now offer a more detailed view." - - rscadd: "Agent ids now offer much greater customization, such as being able to toggle termination of AI tracking." + - rscadd: "Agent ids now offer much greater customization, allowing changing name, age, DNA, toggling of AI tracking termination (using the electronic warfware option), and more." + - rscadd: "As AI tracking can now be enabled/disabled at will AI players should not feel the need to hesitate before informing relevant crew members when camera tracking is explicitly terminated." - rscadd: "Uplink menu now more organized and with new categories." - rscadd: "Now possible to cause falsified ion storm announcements." - rscadd: "Now possible to cause falsified radiation storm announcements, with expected maintenance access changes." From 3baa60465e1fd3cadf96e3514779566aaaf76c19 Mon Sep 17 00:00:00 2001 From: DelZeta Date: Thu, 20 Aug 2015 08:44:32 -0700 Subject: [PATCH 36/94] Removes duplicate hallucination code. --- code/modules/mob/living/carbon/human/life.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 631be0d51ab..4ca19fa57ba 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -951,18 +951,6 @@ spawn(rand(20,50)) client.dir = 1 - if(hallucination) - if(hallucination >= 20) - if(prob(3)) - fake_attack(src) - if(!handling_hal) - spawn handle_hallucinations() //The not boring kind! - if(client && prob(5)) - client.dir = pick(2,4,8) - var/client/C = client - spawn(rand(20,50)) - if(C) - C.dir = 1 hallucination -= 2 if(hallucination < 0) hallucination = 0 From e30e461843feeb9616e5fa3c9a335ac8531b034b Mon Sep 17 00:00:00 2001 From: Atlantis Date: Thu, 20 Aug 2015 22:23:45 +0200 Subject: [PATCH 37/94] Corrects supermatter fluctuations v2 - Better implementation of #10714 - This fix corrects the issue by merging pipenet process to machinery process to ensure order of execution doesn't change randomly. This shouldn't have any performance effect as pipenet process doesn't have much work anyway (not to be confused with air process that runs ZAS, this one only called process() on each pipenet). Screenshot of profiler (pipenet process highlighted, idle server with one player, engine set up) http://i.imgur.com/ecCg6rS.png - Unlike previous fix, this does not come with various game-affecting side effects, players shouldn't see a change (except for the fact that odd fluctuations introduced by devmerge disappear). Previous fix buffed engine output as side effect, and caused one TEG to generate considerably more than second TEG, which caused TEGs to begin sparking despite overall output being below 1MW. --- baystation12.dme | 1 - code/controllers/Processes/machinery.dm | 9 +++++++++ code/controllers/Processes/pipenet.dm | 15 --------------- 3 files changed, 9 insertions(+), 16 deletions(-) delete mode 100644 code/controllers/Processes/pipenet.dm diff --git a/baystation12.dme b/baystation12.dme index e0333a2e087..d151796b682 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -108,7 +108,6 @@ #include "code\controllers\Processes\mob.dm" #include "code\controllers\Processes\nanoui.dm" #include "code\controllers\Processes\obj.dm" -#include "code\controllers\Processes\pipenet.dm" #include "code\controllers\Processes\Shuttle.dm" #include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\supply.dm" diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm index b84dfaf9435..b7b7923c8f2 100644 --- a/code/controllers/Processes/machinery.dm +++ b/code/controllers/Processes/machinery.dm @@ -6,6 +6,7 @@ /datum/controller/process/machinery/doWork() internal_sort() + internal_process_pipenets() internal_process_machinery() internal_process_power() internal_process_power_drain() @@ -57,6 +58,14 @@ processing_power_items.Remove(I) scheck() +/datum/controller/process/machinery/proc/internal_process_pipenets() + for(var/datum/pipe_network/pipeNetwork in pipe_networks) + if(istype(pipeNetwork) && !pipeNetwork.disposed) + pipeNetwork.process() + scheck() + continue + + pipe_networks.Remove(pipeNetwork) /datum/controller/process/machinery/getStatName() return ..()+"([machines.len])" diff --git a/code/controllers/Processes/pipenet.dm b/code/controllers/Processes/pipenet.dm deleted file mode 100644 index 8a5d6a22ca4..00000000000 --- a/code/controllers/Processes/pipenet.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/controller/process/pipenet/setup() - name = "pipenet" - schedule_interval = 20 // every 2 seconds - -/datum/controller/process/pipenet/doWork() - for(var/datum/pipe_network/pipeNetwork in pipe_networks) - if(istype(pipeNetwork) && !pipeNetwork.disposed) - pipeNetwork.process() - scheck() - continue - - pipe_networks.Remove(pipeNetwork) - -/datum/controller/process/pipenet/getStatName() - return ..()+"([pipe_networks.len])" \ No newline at end of file From 5811b6021e7fd489fa130063c5b417f15c30418a Mon Sep 17 00:00:00 2001 From: Atlantis Date: Thu, 20 Aug 2015 23:06:52 +0200 Subject: [PATCH 38/94] Machinery controller now reports amounts of powernets and pipenets as well. --- code/controllers/Processes/machinery.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm index b7b7923c8f2..7959ee4fa7b 100644 --- a/code/controllers/Processes/machinery.dm +++ b/code/controllers/Processes/machinery.dm @@ -68,4 +68,4 @@ pipe_networks.Remove(pipeNetwork) /datum/controller/process/machinery/getStatName() - return ..()+"([machines.len])" + return ..()+"(MCH:[machines.len] PWR:[powernets.len] PIP:[pipe_networks.len])" From 54dd93997de3a79790bc60e9e47fc6c1df0b9f2c Mon Sep 17 00:00:00 2001 From: DelZeta Date: Thu, 20 Aug 2015 20:24:15 -0700 Subject: [PATCH 39/94] Useful procs are useful. --- code/modules/mob/living/carbon/human/life.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4ca19fa57ba..0cadf6ddff0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -951,9 +951,7 @@ spawn(rand(20,50)) client.dir = 1 - hallucination -= 2 - if(hallucination < 0) - hallucination = 0 + hallucination = max(0, hallucination - 2) else for(var/atom/a in hallucinations) qdel(a) From db7ba7041596ca8e64279bff48b3d3f8f871fe52 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 19 Aug 2015 20:42:41 -0400 Subject: [PATCH 40/94] Adds SS13-like interface for reinforcing girders --- code/game/objects/structures/girders.dm | 155 +++++++++++++----------- html/changelogs/HarpyEagle-girders.yml | 18 +++ 2 files changed, 101 insertions(+), 72 deletions(-) create mode 100644 html/changelogs/HarpyEagle-girders.yml diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index d6c406f07e9..3cc940478bc 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -7,6 +7,7 @@ var/health = 200 var/cover = 50 //how much cover the girder provides against projectiles. var/material/reinf_material + var/reinforcing = 0 /obj/structure/girder/displaced icon_state = "displaced" @@ -47,6 +48,7 @@ health = min(health,initial(health)) state = 0 icon_state = initial(icon_state) + reinforcing = 0 if(reinf_material) reinforce_girder() @@ -77,13 +79,18 @@ user << "You drill through the girder!" dismantle() - else if(istype(W, /obj/item/weapon/screwdriver) && state == 2) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) - user << "Now unsecuring support struts..." - if(do_after(user,40)) - if(!src) return - user << "You unsecured the support struts!" - state = 1 + else if(istype(W, /obj/item/weapon/screwdriver)) + if(state == 2) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + user << "Now unsecuring support struts..." + if(do_after(user,40)) + if(!src) return + user << "You unsecured the support struts!" + state = 1 + else if(anchored && !reinf_material) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) + reinforcing = !reinforcing + user << "\The [src] can now be [reinforcing? "reinforced" : "constructed"]!" else if(istype(W, /obj/item/weapon/wirecutters) && state == 1) playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) @@ -107,59 +114,84 @@ cover = 25 else if(istype(W, /obj/item/stack/material)) - - var/obj/item/stack/S = W - if(S.get_amount() < 2) - return ..() - - var/material/M = S.get_material() - if(!istype(M)) - return ..() - - var/wall_fake - add_hiddenprint(usr) - - if(M.integrity < 50) - user << "This material is too soft for use in wall construction." - return - - user << "You begin adding the plating..." - - if(!do_after(user,40) || !S.use(2)) - return - - if(anchored) - user << "You added the plating!" + if(reinforcing && !reinf_material) + if(!reinforce_with_material(W, user)) + return ..() else - user << "You create a false wall! Push on it to open or close the passage." - wall_fake = 1 + if(!construct_wall(W, user)) + return ..() - var/turf/Tsrc = get_turf(src) - Tsrc.ChangeTurf(/turf/simulated/wall) - var/turf/simulated/wall/T = get_turf(src) - T.set_material(M, reinf_material) - if(wall_fake) - T.can_open = 1 - T.add_hiddenprint(usr) - qdel(src) - return - - else if(istype(W, /obj/item/pipe)) - var/obj/item/pipe/P = W - if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds. - user.drop_item() - P.loc = src.loc - user << "You fit the pipe into the [src]!" else - ..() + return ..() + +/obj/structure/girder/proc/construct_wall(obj/item/stack/material/S, mob/user) + if(S.get_amount() < 2) + user << "There isn't enough material here to construct a wall." + return 0 + + var/material/M = name_to_material[S.default_type] + if(!istype(M)) + return 0 + + var/wall_fake + add_hiddenprint(usr) + + if(M.integrity < 50) + user << "This material is too soft for use in wall construction." + return 0 + + user << "You begin adding the plating..." + + if(!do_after(user,40) || !S.use(2)) + return 1 //once we've gotten this far don't call parent attackby() + + if(anchored) + user << "You added the plating!" + else + user << "You create a false wall! Push on it to open or close the passage." + wall_fake = 1 + + var/turf/Tsrc = get_turf(src) + Tsrc.ChangeTurf(/turf/simulated/wall) + var/turf/simulated/wall/T = get_turf(src) + T.set_material(M, reinf_material) + if(wall_fake) + T.can_open = 1 + T.add_hiddenprint(usr) + qdel(src) + return 1 + +/obj/structure/girder/proc/reinforce_with_material(obj/item/stack/material/S, mob/user) //if the verb is removed this can be renamed. + if(reinf_material) + user << "\The [src] is already reinforced." + return 0 + + if(S.get_amount() < 2) + user << "There isn't enough material here to reinforce the girder." + return 0 + + var/material/M = name_to_material[S.default_type] + if(!istype(M) || M.integrity < 50) + user << "You cannot reinforce \the [src] with that; it is too soft." + return 0 + + user << "Now reinforcing..." + if (!do_after(user,40) || !S.use(2)) + return 1 //don't call parent attackby() past this point + user << "You added reinforcement!" + + reinf_material = M + reinforce_girder() + return 1 /obj/structure/girder/proc/reinforce_girder() cover = reinf_material.hardness health = 500 state = 2 icon_state = "reinforced" + reinforcing = 0 -/obj/structure/girder/verb/reinforce_with_material() +/obj/structure/girder/verb/reinforce_with_material_verb() set name = "Reinforce girder" set desc = "Reinforce a girder with metal." set src in view(1) @@ -168,34 +200,13 @@ if(!istype(user) || !(user.l_hand || user.r_hand) || !Adjacent(user)) return - if(reinf_material) - user << "\The [src] is already reinforced." - return - var/obj/item/stack/material/S = user.l_hand if(!istype(S)) S = user.r_hand if(!istype(S)) user << "You cannot plate \the [src] with that." return - - if(S.get_amount() < 2) - user << "There is not enough material here to reinforce the girder." - return - - var/material/M = S.get_material() - if(!istype(M) || M.integrity < 50) - user << "You cannot reinforce \the [src] with that; it is too soft." - return - - user << "Now reinforcing..." - if (!do_after(user,40) || !S.use(2)) - return - user << "You added reinforcement!" - - reinf_material = M - reinforce_girder() - + reinforce_with_material(S, user) /obj/structure/girder/proc/dismantle() new /obj/item/stack/material/steel(get_turf(src)) diff --git a/html/changelogs/HarpyEagle-girders.yml b/html/changelogs/HarpyEagle-girders.yml new file mode 100644 index 00000000000..52ee2d908e6 --- /dev/null +++ b/html/changelogs/HarpyEagle-girders.yml @@ -0,0 +1,18 @@ +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment + +author: HarpyEagle +delete-after: True + +changes: + - tweak: "Girders can now be reinforced by using a screwdriver on the girder before applying the material sheets. Use a screwdriver again to cancel reinforcing." From 8626fbfd39dd8750a4ab60b8281e469f391ededd Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 20 Aug 2015 22:01:15 -0400 Subject: [PATCH 41/94] Removes the reinforce girder verb --- code/game/objects/structures/girders.dm | 17 ----------------- html/changelogs/HarpyEagle-girders.yml | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 3cc940478bc..810712ae45a 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -191,23 +191,6 @@ icon_state = "reinforced" reinforcing = 0 -/obj/structure/girder/verb/reinforce_with_material_verb() - set name = "Reinforce girder" - set desc = "Reinforce a girder with metal." - set src in view(1) - - var/mob/living/user = usr - if(!istype(user) || !(user.l_hand || user.r_hand) || !Adjacent(user)) - return - - var/obj/item/stack/material/S = user.l_hand - if(!istype(S)) - S = user.r_hand - if(!istype(S)) - user << "You cannot plate \the [src] with that." - return - reinforce_with_material(S, user) - /obj/structure/girder/proc/dismantle() new /obj/item/stack/material/steel(get_turf(src)) qdel(src) diff --git a/html/changelogs/HarpyEagle-girders.yml b/html/changelogs/HarpyEagle-girders.yml index 52ee2d908e6..09dc2ce78b2 100644 --- a/html/changelogs/HarpyEagle-girders.yml +++ b/html/changelogs/HarpyEagle-girders.yml @@ -15,4 +15,4 @@ author: HarpyEagle delete-after: True changes: - - tweak: "Girders can now be reinforced by using a screwdriver on the girder before applying the material sheets. Use a screwdriver again to cancel reinforcing." + - tweak: "Girders are now reinforced by using a screwdriver on the girder before applying the material sheets. Use a screwdriver again instead to cancel reinforcing." From c2cdf9d237b8614f1c3b1b7c8410c15e464e4c64 Mon Sep 17 00:00:00 2001 From: GinjaNinja32 Date: Fri, 21 Aug 2015 06:28:44 +0100 Subject: [PATCH 42/94] add round duration to status reply --- code/world.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/world.dm b/code/world.dm index 34b91076998..fdb90267601 100644 --- a/code/world.dm +++ b/code/world.dm @@ -116,6 +116,7 @@ var/world_topic_spam_protect_time = world.timeofday // This is dumb, but spacestation13.com's banners break if player count isn't the 8th field of the reply, so... this has to go here. s["players"] = 0 s["stationtime"] = worldtime2text() + s["roundduration"] = round_duration() if(input["status"] == "2") var/list/players = list() From 742dde5c25af0365765df4f75153aad462a74065 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Fri, 21 Aug 2015 14:01:29 +0200 Subject: [PATCH 43/94] Gives the medical equipment access a name. Requires for guest passes to list the entry. Fixes #10780. --- code/game/jobs/access.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 7a9fc51329e..4474dcd2fb4 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -333,6 +333,8 @@ return "Gateway" if(access_sec_doors) return "Security" + if(access_medical_equip) + return "Medical Equipment" /proc/get_centcom_access_desc(A) switch(A) From 1e7251ded4b0ba78a740d590fff9d64797b72a46 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Fri, 21 Aug 2015 08:57:34 +0200 Subject: [PATCH 44/94] Id card handling changes. Equipment now first checks if an id card may be removed, rather than always forcefully doing so. Station synthetics now have a custom id, rather than re-using the captain's spare, as utilizing robotic storage would otherwise make their id cards available for public use. --- code/game/machinery/computer/card.dm | 7 +-- code/game/machinery/computer/guestpass.dm | 10 ++-- code/game/machinery/computer/medical.dm | 10 ++-- code/game/machinery/computer/security.dm | 3 +- code/game/machinery/computer/skills.dm | 11 ++--- .../machinery/computer3/computers/medical.dm | 4 +- .../machinery/computer3/computers/security.dm | 4 +- code/game/objects/items/devices/PDA/PDA.dm | 17 +++---- code/game/objects/items/weapons/cards_ids.dm | 27 +++++++---- .../items/weapons/cards_ids_syndicate.dm | 2 +- .../objects/items/weapons/storage/storage.dm | 3 ++ code/modules/mob/inventory.dm | 10 ++-- .../mob/living/silicon/robot/robot_modules.dm | 46 ++++++++----------- code/modules/mob/living/silicon/silicon.dm | 2 +- code/modules/paperwork/faxmachine.dm | 3 +- 15 files changed, 81 insertions(+), 78 deletions(-) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index e39c1eebe60..304a614c0ff 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -59,12 +59,10 @@ if(!istype(id_card)) return ..() - if(!scan && access_change_ids in id_card.access) - user.drop_item() + if(!scan && (access_change_ids in id_card.access) && user.unEquip(id_card)) id_card.loc = src scan = id_card else if(!modify) - user.drop_item() id_card.loc = src modify = id_card @@ -157,8 +155,7 @@ modify = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - usr.drop_item() + if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src modify = I diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 7258fc543be..ccbce91b619 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -62,13 +62,14 @@ /obj/machinery/computer/guestpass/attackby(obj/O, mob/user) if(istype(O, /obj/item/weapon/card/id)) - if(!giver) - user.drop_item() + if(!giver && user.unEquip(O)) O.loc = src giver = O updateUsrDialog() - else + else if(giver) user << "There is already ID card inside." + return + ..() /obj/machinery/computer/guestpass/attack_ai(var/mob/user as mob) return attack_hand(user) @@ -151,8 +152,7 @@ accesses.Cut() else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - usr.drop_item() + if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src giver = I updateUsrDialog() diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 92d9e9a83f6..72746775a7e 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -35,13 +35,13 @@ usr << "There is nothing to remove from the console." return -/obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob) - if(istype(O, /obj/item/weapon/card/id) && !scan) - usr.drop_item() +/obj/machinery/computer/med_data/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O)) O.loc = src scan = O - user << "You insert [O]." - ..() + user << "You insert \the [O]." + else + ..() /obj/machinery/computer/med_data/attack_ai(user as mob) return src.attack_hand(user) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 090e02c9080..eba129df262 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -248,8 +248,7 @@ What a mess.*/ scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - usr.drop_item() + if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src scan = I diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index fb2d4ef0959..fca6cf40242 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -24,13 +24,13 @@ var/sortBy = "name" var/order = 1 // -1 = Descending - 1 = Ascending -/obj/machinery/computer/skills/attackby(obj/item/O as obj, user as mob) - if(istype(O, /obj/item/weapon/card/id) && !scan) - usr.drop_item() +/obj/machinery/computer/skills/attackby(obj/item/O as obj, var/mob/user) + if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O)) O.loc = src scan = O user << "You insert [O]." - ..() + else + ..() /obj/machinery/computer/skills/attack_ai(mob/user as mob) return attack_hand(user) @@ -185,8 +185,7 @@ What a mess.*/ scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - usr.drop_item() + if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src scan = I diff --git a/code/game/machinery/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm index f39dd54de8d..7cf89a3fce9 100644 --- a/code/game/machinery/computer3/computers/medical.dm +++ b/code/game/machinery/computer3/computers/medical.dm @@ -181,7 +181,7 @@ scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) + if (istype(I, /obj/item/weapon/card/id) && usr.drop_item(I)) computer.cardslot.insert(I, 1) scan = I @@ -194,7 +194,7 @@ scan2 = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) + if (istype(I, /obj/item/weapon/card/id) && usr.drop_item(I)) computer.cardslot.insert(I, 2) scan2 = I diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm index a346c12facc..1ba0c08cf78 100644 --- a/code/game/machinery/computer3/computers/security.dm +++ b/code/game/machinery/computer3/computers/security.dm @@ -254,7 +254,7 @@ What a mess.*/ scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) + if (istype(I, /obj/item/weapon/card/id) && usr.drop_item(I)) computer.cardslot.insert(I, 1) scan = I @@ -267,7 +267,7 @@ What a mess.*/ scan2 = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) + if (istype(I, /obj/item/weapon/card/id) && usr.drop_item(I)) computer.cardslot.insert(I, 2) scan2 = I diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index a01dc224c3e..57c5dd95af9 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1142,21 +1142,22 @@ var/global/list/obj/item/device/pda/PDAs = list() if(choice == 1) if (id) remove_id() + return 1 else var/obj/item/I = user.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - user.drop_item() + if (istype(I, /obj/item/weapon/card/id) && user.unEquip(I)) I.loc = src id = I + return 1 else var/obj/item/weapon/card/I = user.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && I:registered_name) + if (istype(I, /obj/item/weapon/card/id) && I:registered_name && user.unEquip(I)) var/obj/old_id = id - user.drop_item() I.loc = src id = I user.put_in_hands(old_id) - return + return 1 + return 0 // access to status display signals /obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob) @@ -1184,9 +1185,9 @@ var/global/list/obj/item/device/pda/PDAs = list() else //Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand. if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) ) - id_check(user, 2) - user << "You put the ID into \the [src]'s slot." - updateSelfDialog()//Update self dialog on success. + if(id_check(user, 2)) + user << "You put the ID into \the [src]'s slot." + updateSelfDialog()//Update self dialog on success. return //Return in case of failed check or when successful. updateSelfDialog()//For the non-input related code. else if(istype(C, /obj/item/device/paicard) && !src.pai) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index a63a0f14cba..dbac808c049 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -122,8 +122,9 @@ return 0 /obj/item/weapon/card/id/proc/show(mob/user as mob) - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") + if(front && side) + user << browse_rsc(front, "front.png") + user << browse_rsc(side, "side.png") var/datum/browser/popup = new(user, "idcard", name, 600, 250) popup.set_content(dat()) popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) @@ -148,11 +149,6 @@ id_card.dna_hash = dna.unique_enzymes id_card.fingerprint_hash= md5(dna.uni_identity) id_card.update_name() - -/mob/living/silicon/set_id_info(var/obj/item/weapon/card/id/id_card) - id_card.assignment = "Synthetic" - id_card.rank = "Synthetic" - ..() /mob/living/carbon/human/set_id_info(var/obj/item/weapon/card/id/id_card) ..() @@ -222,9 +218,20 @@ item_state = "gold_id" registered_name = "Captain" assignment = "Captain" - New() - access = get_all_station_access() - ..() +/obj/item/weapon/card/id/captains_spare/New() + access = get_all_station_access() + ..() + +/obj/item/weapon/card/id/synthetic + name = "\improper Synthetic ID" + desc = "Access module for NanoTrasen Synthetics" + icon_state = "id-robot" + item_state = "tdgreen" + assignment = "Synthetic" + +/obj/item/weapon/card/id/synthetic/New() + access = get_all_station_access() + ..() /obj/item/weapon/card/id/centcom name = "\improper CentCom. ID" diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 1642766a0e6..3496607ffa4 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -39,7 +39,7 @@ var/global/list/syndicate_ids = list() if(!registered_user) registered_user = user user.set_id_info(src) - user << "The microscanner marks you as its owner, preventing others some accessing its internals." + user << "The microscanner marks you as its owner, preventing others from accessing its internals." if(registered_user == user) switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show")) if("Edit") diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 131347ac29a..c1022c55d0f 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -224,6 +224,9 @@ //Set the stop_messages to stop it from printing messages /obj/item/weapon/storage/proc/can_be_inserted(obj/item/W as obj, stop_messages = 0) if(!istype(W)) return //Not an item + + if(!usr.canUnEquip(W)) + return 0 if(src.loc == W) return 0 //Means the item is already in the storage item diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 1115826be80..a23cc18aef6 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -216,11 +216,9 @@ var/list/slot_equipment_priority = list( \ update_inv_wear_mask(0) return -//This differs from remove_from_mob() in that it checks if the item can be unequipped first. -/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress. +/mob/proc/canUnEquip(obj/item/I) if(!I) //If there's nothing to drop, the drop is automatically successful. return 1 - var/slot for(var/s in slot_back to slot_tie) //kind of worries me if(get_equipped_item(s) == I) @@ -230,6 +228,12 @@ var/list/slot_equipment_priority = list( \ if(slot && !I.mob_can_unequip(src, slot)) return 0 + return 1 + +//This differs from remove_from_mob() in that it checks if the item can be unequipped first. +/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress. + if(!force && canUnEquip(I)) + return drop_from_inventory(I) return 1 diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 08e56dc905b..8e6f3207fb2 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -52,6 +52,9 @@ var/global/list/robot_modules = list( R.set_module_sprites(sprites) R.choose_icon(R.module_sprites.len + 1, R.module_sprites) + for(var/obj/item/I in modules) + I.canremove = 0 + /obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R) remove_camera_networks(R) remove_languages(R) @@ -146,7 +149,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/standard/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/melee/baton/loaded(src) src.modules += new /obj/item/weapon/extinguisher(src) @@ -154,7 +156,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/crowbar(src) src.modules += new /obj/item/device/healthanalyzer(src) src.emag = new /obj/item/weapon/melee/energy/sword(src) - return + ..() /obj/item/weapon/robot_module/medical name = "medical robot module" @@ -174,7 +176,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/medical/surgeon/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/weapon/reagent_containers/borghypo/surgeon(src) @@ -206,7 +207,7 @@ var/global/list/robot_modules = list( src.modules += N src.modules += B - return + ..() /obj/item/weapon/robot_module/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) if(src.emag) @@ -226,7 +227,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/medical/crisis/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/hud/med(src) src.modules += new /obj/item/device/healthanalyzer(src) @@ -260,7 +260,7 @@ var/global/list/robot_modules = list( src.modules += B src.modules += S - return + ..() /obj/item/weapon/robot_module/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) @@ -296,7 +296,6 @@ var/global/list/robot_modules = list( no_slip = 1 /obj/item/weapon/robot_module/engineering/construction/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/extinguisher(src) @@ -330,8 +329,9 @@ var/global/list/robot_modules = list( RG.synths = list(metal, glass) src.modules += RG -/obj/item/weapon/robot_module/engineering/general/New() ..() + +/obj/item/weapon/robot_module/engineering/general/New() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/extinguisher(src) @@ -384,7 +384,7 @@ var/global/list/robot_modules = list( RG.synths = list(metal, glass) src.modules += RG - return + ..() /obj/item/weapon/robot_module/security name = "security robot module" @@ -405,7 +405,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/security/general/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/hud/sec(src) src.modules += new /obj/item/weapon/handcuffs/cyborg(src) @@ -413,7 +412,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src) src.modules += new /obj/item/taperoll/police(src) src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src) - return + ..() /obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/flash/F = locate() in src.modules @@ -444,7 +443,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/janitor/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/soap/nanotrasen(src) src.modules += new /obj/item/weapon/storage/bag/trash(src) @@ -453,7 +451,7 @@ var/global/list/robot_modules = list( src.emag = new /obj/item/weapon/reagent_containers/spray(src) src.emag.reagents.add_reagent("lube", 250) src.emag.name = "Lube spray" - return + ..() /obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/lightreplacer/LR = locate() in src.modules @@ -487,7 +485,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/clerical/butler/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/gripper/service(src) src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src) @@ -516,7 +513,7 @@ var/global/list/robot_modules = list( R.my_atom = src.emag R.add_reagent("beer2", 50) src.emag.name = "Mickey Finn's Special Brew" - return + ..() /obj/item/weapon/robot_module/clerical/general name = "clerical robot module" @@ -530,13 +527,13 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/clerical/general/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/pen/robopen(src) src.modules += new /obj/item/weapon/form_printer(src) src.modules += new /obj/item/weapon/gripper/paperwork(src) src.modules += new /obj/item/weapon/hand_labeler(src) src.emag = new /obj/item/weapon/stamp/denied(src) + ..() /obj/item/weapon/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules @@ -558,7 +555,6 @@ var/global/list/robot_modules = list( supported_upgrades = list(/obj/item/borg/upgrade/jetpack) /obj/item/weapon/robot_module/miner/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/meson(src) src.modules += new /obj/item/weapon/wrench(src) @@ -570,7 +566,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/mining_scanner(src) src.modules += new /obj/item/weapon/crowbar(src) src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src) - return + ..() /obj/item/weapon/robot_module/research name = "research module" @@ -581,7 +577,6 @@ var/global/list/robot_modules = list( ) /obj/item/weapon/robot_module/research/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/portable_destructive_analyzer(src) src.modules += new /obj/item/weapon/gripper/research(src) @@ -607,7 +602,7 @@ var/global/list/robot_modules = list( N.synths = list(nanite) src.modules += N - return + ..() /obj/item/weapon/robot_module/syndicate name = "illegal robot module" @@ -625,7 +620,6 @@ var/global/list/robot_modules = list( var/id /obj/item/weapon/robot_module/syndicate/New(var/mob/living/silicon/robot/R) - ..() loc = R src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/weapon/melee/energy/sword(src) @@ -637,7 +631,7 @@ var/global/list/robot_modules = list( id = R.idcard src.modules += id - return + ..() /obj/item/weapon/robot_module/syndicate/Destroy() src.modules -= id @@ -649,7 +643,6 @@ var/global/list/robot_modules = list( sprites = list("Combat Android" = "droid-combat") /obj/item/weapon/robot_module/combat/New() - ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/thermal(src) src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src) @@ -657,7 +650,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/borg/combat/shield(src) src.modules += new /obj/item/borg/combat/mobility(src) src.emag = new /obj/item/weapon/gun/energy/lasercannon/mounted(src) - return + ..() /obj/item/weapon/robot_module/drone name = "drone module" @@ -665,7 +658,6 @@ var/global/list/robot_modules = list( networks = list(NETWORK_ENGINEERING) /obj/item/weapon/robot_module/drone/New() - ..() src.modules += new /obj/item/weapon/weldingtool(src) src.modules += new /obj/item/weapon/screwdriver(src) src.modules += new /obj/item/weapon/wrench(src) @@ -732,14 +724,16 @@ var/global/list/robot_modules = list( P.synths = list(plastic) src.modules += P + ..() + /obj/item/weapon/robot_module/drone/construction name = "construction drone module" channels = list("Engineering" = 1) languages = list() /obj/item/weapon/robot_module/drone/construction/New() - ..() src.modules += new /obj/item/weapon/rcd/borg(src) + ..() /obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/lightreplacer/LR = locate() in src.modules diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index ac3feba0765..25b321a9a7e 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -25,7 +25,7 @@ var/list/access_rights var/obj/item/weapon/card/id/idcard - var/idcard_type = /obj/item/weapon/card/id/captains_spare + var/idcard_type = /obj/item/weapon/card/id/synthetic #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 44d42e1b9d1..160eb5cde26 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -114,8 +114,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) - usr.drop_item() + if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src scan = I authenticated = 0 From 56523d09411ff6d48a5bf7de1c73b8195d2595c6 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Fri, 21 Aug 2015 14:45:45 +0200 Subject: [PATCH 45/94] Cleans out (mostly) unused access definitions and makes access lists sorted. --- baystation12.dme | 1 - code/datums/supplypacks.dm | 4 +- code/game/jobs/_access_defs.dm | 6 +- code/game/jobs/access.dm | 26 +++- code/game/jobs/access_datum.dm | 31 ++--- code/game/jobs/job/captain.dm | 12 +- code/game/jobs/job/civilian.dm | 4 +- code/game/jobs/job/security.dm | 16 +-- code/game/machinery/portable_tag_turret.dm | 124 ------------------ code/game/machinery/portable_turret.dm | 19 ++- .../crates_lockers/closets/secure/security.dm | 2 +- code/modules/mob/living/bot/secbot.dm | 2 +- 12 files changed, 62 insertions(+), 185 deletions(-) delete mode 100644 code/game/machinery/portable_tag_turret.dm diff --git a/baystation12.dme b/baystation12.dme index a5e9158b33b..803c6cb0e55 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -388,7 +388,6 @@ #include "code\game\machinery\nuclear_bomb.dm" #include "code\game\machinery\OpTable.dm" #include "code\game\machinery\overview.dm" -#include "code\game\machinery\portable_tag_turret.dm" #include "code\game\machinery\portable_turret.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 0d34c1a7fc8..fb33002ea06 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1091,9 +1091,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/under/kilt) name = "Costumes crate" cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate containername = "Actor Costumes" - access = access_theatre group = "Miscellaneous" /datum/supply_packs/formal_wear @@ -1419,7 +1418,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/head/helmet/gladiator, /obj/item/clothing/head/ushanka) group = "Miscellaneous" - access = access_theatre /datum/supply_packs/randomised/webbing name = "Webbing crate" diff --git a/code/game/jobs/_access_defs.dm b/code/game/jobs/_access_defs.dm index eb77c73cfac..e371ff83673 100644 --- a/code/game/jobs/_access_defs.dm +++ b/code/game/jobs/_access_defs.dm @@ -9,7 +9,7 @@ #define ACCESS_REGION_SUPPLY 7 #define ACCESS_TYPE_NONE 0 -#define ACCESS_TYPE_STATION 1 -#define ACCESS_TYPE_CENTCOM 2 +#define ACCESS_TYPE_CENTCOM 1 +#define ACCESS_TYPE_STATION 2 #define ACCESS_TYPE_SYNDICATE 4 -#define ACCESS_TYPE_ALL 7 +#define ACCESS_TYPE_ALL (ACCESS_TYPE_CENTCOM|ACCESS_TYPE_STATION|ACCESS_TYPE_SYNDICATE) diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 09fc65bf417..fbc92f4bc49 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -67,17 +67,29 @@ /proc/get_all_access_datums() if(!priv_all_access_datums) priv_all_access_datums = init_subtypes(/datum/access) + priv_all_access_datums = dd_sortedObjectList(priv_all_access_datums) return priv_all_access_datums -/var/list/datum/access/priv_all_access_datums_assoc -/proc/get_all_access_datums_assoc() - if(!priv_all_access_datums_assoc) - priv_all_access_datums_assoc = list() +/var/list/datum/access/priv_all_access_datums_id +/proc/get_all_access_datums_by_id() + if(!priv_all_access_datums_id) + priv_all_access_datums_id = list() for(var/datum/access/A in get_all_access_datums()) - priv_all_access_datums_assoc["[A.id]"] = A + priv_all_access_datums_id["[A.id]"] = A - return priv_all_access_datums_assoc + return priv_all_access_datums_id + +/var/list/datum/access/priv_all_access_datums_region +/proc/get_all_access_datums_by_region() + if(!priv_all_access_datums_region) + priv_all_access_datums_region = list() + for(var/datum/access/A in get_all_access_datums()) + if(!priv_all_access_datums_region[A.region]) + priv_all_access_datums_region[A.region] = list() + priv_all_access_datums_region[A.region] += A + + return priv_all_access_datums_region /proc/get_access_ids(var/access_types = ACCESS_TYPE_ALL) var/list/L = new() @@ -148,7 +160,7 @@ return "Supply" /proc/get_access_desc(id) - var/list/AS = get_all_access_datums_assoc() + var/list/AS = get_all_access_datums_by_id() var/datum/access/A = AS["[id]"] return A ? A.desc : "" diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm index 9cf27f6dbcd..5e1cb90f1f2 100644 --- a/code/game/jobs/access_datum.dm +++ b/code/game/jobs/access_datum.dm @@ -4,6 +4,9 @@ var/region = ACCESS_REGION_NONE var/access_type = ACCESS_TYPE_STATION +/datum/access/dd_SortValue() + return "[access_type][desc]" + /***************** * Station access * *****************/ @@ -232,8 +235,8 @@ /var/const/access_lawyer = 38 /datum/access/lawyer id = access_lawyer - desc = "Law Office" - region = ACCESS_REGION_GENERAL + desc = "Internal Affairs" + region = ACCESS_REGION_COMMAND /var/const/access_virology = 39 /datum/access/virology @@ -253,21 +256,9 @@ desc = "Quartermaster" region = ACCESS_REGION_SUPPLY -/var/const/access_court = 42 -/datum/access/court - id = access_court - desc = "Courtroom" - region = ACCESS_REGION_SECURITY - -/var/const/access_clown = 43 -/datum/access/clown - id = access_clown - desc = "HONK! Access" - -/var/const/access_mime = 44 -/datum/access/mime - id = access_mime - desc = "Silent Access" +// /var/const/free_access_id = 43 +// /var/const/free_access_id = 43 +// /var/const/free_access_id = 44 /var/const/access_surgery = 45 /datum/access/surgery @@ -275,11 +266,7 @@ desc = "Surgery" region = ACCESS_REGION_MEDBAY -/var/const/access_theatre = 46 -/datum/access/theatre - id = access_theatre - desc = "Theatre" - region = ACCESS_REGION_GENERAL +// /var/const/free_access_id = 46 /var/const/access_research = 47 /datum/access/research diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index 665016a1cf2..dd088474f1c 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -62,18 +62,18 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) req_admin_notify = 1 minimal_player_age = 10 economic_modifier = 10 - access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, + access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads, access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue, access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer, - access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station, - access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway) - minimal_access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, + access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station, + access_hop, access_RC_announce, access_keycard_auth, access_gateway) + minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads, access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue, access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer, - access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station, - access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway) + access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station, + access_hop, access_RC_announce, access_keycard_auth, access_gateway) equip(var/mob/living/carbon/human/H) diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index f45af97286a..a64f35f25f9 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -314,8 +314,8 @@ supervisors = "Nanotrasen officials and Corporate Regulations" selection_color = "#dddddd" economic_modifier = 7 - access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels, access_heads) - minimal_access = list(access_lawyer, access_court, access_sec_doors, access_heads) + access = list(access_lawyer, access_sec_doors, access_maint_tunnels, access_heads) + minimal_access = list(access_lawyer, access_sec_doors, access_heads) equip(var/mob/living/carbon/human/H) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 8a9461302db..9e3f51596bc 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -12,11 +12,11 @@ idtype = /obj/item/weapon/card/id/silver req_admin_notify = 1 economic_modifier = 10 - access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_court, + access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers, access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting, access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks) - minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_court, + minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers, access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting, access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks) @@ -56,8 +56,8 @@ supervisors = "the head of security" selection_color = "#ffeeee" economic_modifier = 5 - access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_morgue, access_external_airlocks) - minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_court, access_maint_tunnels, access_external_airlocks) + access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_morgue, access_external_airlocks) + minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_maint_tunnels, access_external_airlocks) minimal_player_age = 5 equip(var/mob/living/carbon/human/H) @@ -94,8 +94,8 @@ selection_color = "#ffeeee" alt_titles = list("Forensic Technician") economic_modifier = 5 - access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court) - minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court) + access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels) + minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels) alt_titles = list("Forensic Technician") minimal_player_age = 3 equip(var/mob/living/carbon/human/H) @@ -136,8 +136,8 @@ supervisors = "the head of security" selection_color = "#ffeeee" economic_modifier = 4 - access = list(access_security, access_eva, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_morgue, access_external_airlocks) - minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_court, access_maint_tunnels, access_external_airlocks) + access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_morgue, access_external_airlocks) + minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_maint_tunnels, access_external_airlocks) minimal_player_age = 3 equip(var/mob/living/carbon/human/H) if(!H) return 0 diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm deleted file mode 100644 index f3939e89dcd..00000000000 --- a/code/game/machinery/portable_tag_turret.dm +++ /dev/null @@ -1,124 +0,0 @@ -#define TURRET_PRIORITY_TARGET 2 -#define TURRET_SECONDARY_TARGET 1 -#define TURRET_NOT_TARGET 0 - -/obj/machinery/porta_turret/tag - // Reasonable defaults, in case someone manually spawns us - var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment. - installation = /obj/item/weapon/gun/energy/lasertag/red - -/obj/machinery/porta_turret/tag/red - -/obj/machinery/porta_turret/tag/blue - lasercolor = "b" - installation = /obj/item/weapon/gun/energy/lasertag/blue - -/obj/machinery/porta_turret/tag/New() - ..() - icon_state = "[lasercolor]grey_target_prism" - -/obj/machinery/porta_turret/tag/weapon_setup(var/obj/item/weapon/gun/energy/E) - switch(E.type) - if(/obj/item/weapon/gun/energy/lasertag/blue) - eprojectile = /obj/item/weapon/gun/energy/lasertag/blue - lasercolor = "b" - req_access = list(access_maint_tunnels, access_theatre) - check_arrest = 0 - check_records = 0 - check_weapons = 1 - check_access = 0 - check_anomalies = 0 - shot_delay = 30 - - if(/obj/item/weapon/gun/energy/lasertag/red) - eprojectile = /obj/item/weapon/gun/energy/lasertag/red - lasercolor = "r" - req_access = list(access_maint_tunnels, access_theatre) - check_arrest = 0 - check_records = 0 - check_weapons = 1 - check_access = 0 - check_anomalies = 0 - shot_delay = 30 - iconholder = 1 - -/obj/machinery/porta_turret/tag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - data["access"] = !isLocked(user) - data["locked"] = locked - data["enabled"] = enabled - data["is_lethal"] = 0 - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/porta_turret/tag/update_icon() - if(!anchored) - icon_state = "turretCover" - return - if(stat & BROKEN) - icon_state = "[lasercolor]destroyed_target_prism" - else - if(powered()) - if(enabled) - if(iconholder) - //lasers have a orange icon - icon_state = "[lasercolor]orange_target_prism" - else - //almost everything has a blue icon - icon_state = "[lasercolor]target_prism" - else - icon_state = "[lasercolor]grey_target_prism" - else - icon_state = "[lasercolor]grey_target_prism" - -/obj/machinery/porta_turret/tag/bullet_act(obj/item/projectile/Proj) - ..() - - if(lasercolor == "b" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/red)) - disabled = 1 - qdel(Proj) - sleep(100) - disabled = 0 - if(lasercolor == "r" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/blue)) - disabled = 1 - qdel(Proj) - sleep(100) - disabled = 0 - -/obj/machinery/porta_turret/tag/assess_living(var/mob/living/L) - if(!L) - return TURRET_NOT_TARGET - - if(L.lying) - return TURRET_NOT_TARGET - - var/target_suit - var/target_weapon - switch(lasercolor) - if("b") - target_suit = /obj/item/clothing/suit/redtag - target_weapon = /obj/item/weapon/gun/energy/lasertag/red - if("r") - target_suit = /obj/item/clothing/suit/bluetag - target_weapon = /obj/item/weapon/gun/energy/lasertag/blue - - - if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve - if((istype(L.r_hand, target_weapon)) || (istype(L.l_hand, target_weapon))) - return TURRET_PRIORITY_TARGET - - if(istype(L, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = L - if(istype(H.wear_suit, target_suit)) - return TURRET_PRIORITY_TARGET - if(istype(H.belt, target_weapon)) - return TURRET_SECONDARY_TARGET - - return TURRET_NOT_TARGET \ No newline at end of file diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index c2e7cbace79..5d184f0b07c 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -3,6 +3,10 @@ This code is slightly more documented than normal, as requested by XSI on IRC. */ +#define TURRET_PRIORITY_TARGET 2 +#define TURRET_SECONDARY_TARGET 1 +#define TURRET_NOT_TARGET 0 + /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' @@ -343,7 +347,7 @@ var/list/turret_icons sleep(60) attacked = 0 ..() - + /obj/machinery/porta_turret/emag_act(var/remaining_charges, var/mob/user) if(!emagged) //Emagging the turret makes it go bonkers and stun everyone. It also makes @@ -503,7 +507,7 @@ var/list/turret_icons if(isanimal(L) || issmall(L)) // Animals are not so dangerous return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET - + if(isxenomorph(L) || isalien(L)) // Xenos are dangerous return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET @@ -759,11 +763,7 @@ var/list/turret_icons installation = I.type //installation becomes I.type gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge user << "You add [I] to the turret." - - if(istype(installation, /obj/item/weapon/gun/energy/lasertag/blue) || istype(installation, /obj/item/weapon/gun/energy/lasertag/red)) - target_type = /obj/machinery/porta_turret/tag - else - target_type = /obj/machinery/porta_turret + target_type = /obj/machinery/porta_turret build_step = 4 qdel(I) //delete the gun :( @@ -880,3 +880,8 @@ var/list/turret_icons /atom/movable/porta_turret_cover icon = 'icons/obj/turrets.dmi' + + +#undef TURRET_PRIORITY_TARGET +#undef TURRET_SECONDARY_TARGET +#undef TURRET_NOT_TARGET diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 061798be0bc..130d060ebc4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -308,7 +308,7 @@ /obj/structure/closet/secure_closet/courtroom name = "courtroom locker" - req_access = list(access_court) + req_access = list(access_lawyer) New() ..() diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 547361f4005..ca233881f26 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -5,7 +5,7 @@ maxHealth = 50 health = 50 req_one_access = list(access_security, access_forensics_lockers) - botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court) + botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels) var/mob/target From c1a0661ebae5463c5d4f24537d11bb4e7a3473d1 Mon Sep 17 00:00:00 2001 From: Kelenius Date: Fri, 21 Aug 2015 16:19:09 +0300 Subject: [PATCH 46/94] Accidentally commited before saving the file. --- code/__defines/items_clothing.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 658e0d7bb29..aa32b0016ec 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -39,7 +39,6 @@ #define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc. #define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) #define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face. ->>>>>>> dev // Flags for pass_flags. #define PASSTABLE 0x1 From 545e465dfc0b461cacf4a2bac77b624532ea5bf9 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Sat, 22 Aug 2015 02:00:08 +0930 Subject: [PATCH 47/94] Added paper shredders from Minijar. --- baystation12.dme | 1 + code/modules/paperwork/papershredder.dm | 139 ++++++++++++++++++++++++ icons/obj/bureaucracy.dmi | Bin 13803 -> 14870 bytes sound/items/pshred.ogg | Bin 0 -> 57059 bytes 4 files changed, 140 insertions(+) create mode 100644 code/modules/paperwork/papershredder.dm create mode 100644 sound/items/pshred.ogg diff --git a/baystation12.dme b/baystation12.dme index 803c6cb0e55..4643c895da4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1427,6 +1427,7 @@ #include "code\modules\paperwork\paper.dm" #include "code\modules\paperwork\paper_bundle.dm" #include "code\modules\paperwork\paperbin.dm" +#include "code\modules\paperwork\papershredder.dm" #include "code\modules\paperwork\pen.dm" #include "code\modules\paperwork\photocopier.dm" #include "code\modules\paperwork\photography.dm" diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm new file mode 100644 index 00000000000..37cfdaa86b1 --- /dev/null +++ b/code/modules/paperwork/papershredder.dm @@ -0,0 +1,139 @@ +/obj/machinery/papershredder + name = "paper shredder" + desc = "For those documents you don't want seen." + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "papershredder0" + density = 1 + anchored = 1 + var/max_paper = 10 + var/paperamount = 0 + var/list/shred_amounts = list( + /obj/item/weapon/photo = 1, + /obj/item/weapon/shreddedp = 1, + /obj/item/weapon/paper = 1, + /obj/item/weapon/newspaper = 3, + /obj/item/weapon/card/id = 3, + /obj/item/weapon/paper_bundle = 3, + ) + +/obj/machinery/papershredder/attackby(var/obj/item/W, var/mob/user) + + if(istype(W, /obj/item/weapon/storage)) + empty_bin(user, W) + return + else + var/paper_result + for(var/shred_type in shred_amounts) + if(istype(W, shred_type)) + paper_result = shred_amounts[shred_type] + if(paper_result) + if(paperamount == max_paper) + user << "\The [src] is full; please empty it before you continue." + return + paperamount += paper_result + user.drop_from_inventory(W) + qdel(W) + playsound(src.loc, 'sound/items/pshred.ogg', 75, 1) + if(paperamount > max_paper) + user <<"\The [src] was too full, and shredded paper goes everywhere!" + for(var/i=(paperamount-max_paper);i>0;i--) + var/obj/item/weapon/shreddedp/SP = get_shredded_paper() + SP.loc = get_turf(src) + SP.throw_at(get_edge_target_turf(src,pick(alldirs)),1,5) + paperamount = max_paper + update_icon() + return + return ..() + +/obj/machinery/papershredder/verb/empty_contents() + set name = "Empty bin" + set category = "Object" + set src in range(1) + + if(usr.stat || usr.restrained() || usr.weakened || usr.paralysis || usr.lying || usr.stunned) + return + + if(!paperamount) + usr << "\The [src] is empty." + return + + empty_bin(usr) + +/obj/machinery/papershredder/proc/empty_bin(var/mob/living/user, var/obj/item/weapon/storage/empty_into) + + // Sanity. + if(empty_into && !istype(empty_into)) + empty_into = null + + if(empty_into && empty_into.contents.len >= empty_into.storage_slots) + user << "\The [empty_into] is full." + return + + while(paperamount) + var/obj/item/weapon/shreddedp/SP = get_shredded_paper() + if(!SP) break + if(empty_into) + empty_into.handle_item_insertion(SP) + if(empty_into.contents.len >= empty_into.storage_slots) + break + if(empty_into) + if(paperamount) + user << "You fill \the [empty_into] with as much shredded paper as it will carry." + else + user << "You empty \the [src] into \the [empty_into]." + + else + user << "You empty \the [src]." + update_icon() + +/obj/machinery/papershredder/proc/get_shredded_paper() + if(!paperamount) + return + paperamount-- + return PoolOrNew(/obj/item/weapon/shreddedp, get_turf(src)) + +/obj/machinery/papershredder/update_icon() + icon_state = "papershredder[max(0,min(5,Floor(paperamount/2)))]" + +/obj/item/weapon/shreddedp/attackby(var/obj/item/W as obj, var/mob/user) + if(istype(W, /obj/item/weapon/flame/lighter)) + burnpaper(W, user) + else + ..() + +/obj/item/weapon/shreddedp/proc/burnpaper(var/obj/item/weapon/flame/lighter/P, var/mob/user) + if(user.restrained()) + return + if(!P.lit) + user << "\The [P] is not lit." + return + user.visible_message("\The [user] holds \the [P] up to \the [src]. It looks like \he's trying to burn it!", \ + "You hold \the [P] up to \the [src], burning it slowly.") + if(!do_after(user,20)) + user << "You must hold \the [P] steady to burn \the [src]." + return + user.visible_message("\The [user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ + "You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") + FireBurn() + +/obj/item/weapon/shreddedp/proc/FireBurn() + var/mob/living/M = loc + if(istype(M)) + M.drop_from_inventory(src) + PoolOrNew(/obj/effect/decal/cleanable/ash,get_turf(src)) + qdel(src) + +/obj/item/weapon/shreddedp + name = "shredded paper" + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "shredp" + throwforce = 0 + w_class = 1 + throw_range = 3 + throw_speed = 1 + +/obj/item/weapon/shreddedp/New() + ..() + pixel_x = rand(-5,5) + pixel_y = rand(-5,5) + if(prob(65)) color = pick("#BABABA","#7F7F7F") diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index a2a99f01f8d03a5a98f90351ca3befad023404c6..cc54c091e1b0d9bb3992b10c2353e06cb2cb6368 100644 GIT binary patch literal 14870 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 literal 13803 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 BR__1+ diff --git a/sound/items/pshred.ogg b/sound/items/pshred.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a722f3006899297efbcc597d99f5e365d9699264 GIT binary patch literal 57059 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 Date: Mon, 22 Jun 2015 16:39:21 +0930 Subject: [PATCH 48/94] Adds variables for CentComm, NanoTrasen and the station name. --- code/_helpers/names.dm | 2 +- code/controllers/shuttle_controller.dm | 8 ++-- code/datums/ai_law_sets.dm | 4 +- code/defines/obj/weapon.dm | 2 +- code/game/antagonist/outsider/commando.dm | 2 +- code/game/antagonist/outsider/deathsquad.dm | 2 +- code/game/antagonist/outsider/ert.dm | 6 +-- code/game/antagonist/outsider/ninja.dm | 10 ++--- code/game/gamemodes/changeling/changeling.dm | 10 ++++- .../tree_interdiction.dm | 2 +- .../newmalf_ability_trees/tree_networking.dm | 2 +- code/game/gamemodes/ninja/ninja.dm | 8 +++- code/game/gamemodes/objective.dm | 4 +- code/game/gamemodes/traitor/traitor.dm | 10 ++++- code/game/jobs/job/captain.dm | 2 +- code/game/jobs/job/civilian.dm | 2 +- code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/camera/camera_assembly.dm | 2 +- code/game/machinery/computer/atmos_control.dm | 2 +- code/game/machinery/computer/card.dm | 2 +- .../game/machinery/computer/communications.dm | 16 ++++---- code/game/machinery/computer/medical.dm | 2 +- .../machinery/computer/specops_shuttle.dm | 6 +-- code/game/machinery/computer3/NTOS.dm | 6 +-- .../machinery/computer3/computers/arcade.dm | 2 +- .../machinery/computer3/computers/camera.dm | 2 +- .../machinery/computer3/computers/card.dm | 2 +- .../computer3/computers/communications.dm | 6 +-- .../machinery/computer3/computers/welcome.dm | 6 +-- code/game/machinery/computer3/lapvend.dm | 4 +- code/game/machinery/newscaster.dm | 28 ++++++------- code/game/mecha/combat/durand.dm | 2 +- code/game/mecha/combat/gygax.dm | 2 +- code/game/mecha/mech_fabricator.dm | 4 +- .../objects/effects/decals/posters/bs12.dm | 10 ++--- code/game/objects/items/blueprints.dm | 2 +- code/game/objects/items/devices/PDA/radio.dm | 2 +- code/game/objects/items/devices/flashlight.dm | 2 +- .../items/devices/radio/encryptionkey.dm | 2 +- code/game/objects/items/toys.dm | 2 +- code/game/objects/items/weapons/AI_modules.dm | 2 +- .../objects/items/weapons/implants/implant.dm | 10 ++--- code/game/objects/items/weapons/manuals.dm | 34 ++++++++-------- .../objects/items/weapons/material/misc.dm | 2 +- .../game/objects/items/weapons/power_cells.dm | 4 +- .../objects/items/weapons/storage/backpack.dm | 16 ++++---- .../objects/items/weapons/storage/bags.dm | 2 +- .../crates_lockers/closets/wardrobe.dm | 6 +-- code/game/objects/structures/watercloset.dm | 2 +- code/game/periodic_news.dm | 4 +- code/game/response_team.dm | 6 +-- code/global.dm | 17 +++++--- code/modules/admin/admin.dm | 10 ++--- code/modules/admin/holder2.dm | 4 +- code/modules/admin/topic.dm | 14 +++---- code/modules/admin/verbs/pray.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 4 +- .../awaymissions/bluespaceartillery.dm | 2 +- code/modules/awaymissions/exile.dm | 2 +- code/modules/awaymissions/pamphlet.dm | 14 +++---- code/modules/client/preferences.dm | 2 +- code/modules/client/preferences_gear.dm | 4 +- code/modules/clothing/head/helmet.dm | 12 +++--- code/modules/clothing/head/jobs.dm | 4 +- code/modules/clothing/shoes/jobs.dm | 2 +- code/modules/clothing/spacesuits/captain.dm | 4 +- .../clothing/spacesuits/miscellaneous.dm | 2 +- .../clothing/spacesuits/rig/suits/ert.dm | 10 ++--- .../clothing/spacesuits/rig/suits/station.dm | 2 +- code/modules/clothing/suits/armor.dm | 24 +++++------ code/modules/clothing/suits/miscellaneous.dm | 4 +- .../clothing/under/accessories/accessory.dm | 8 ++-- .../clothing/under/accessories/badges.dm | 6 +-- code/modules/clothing/under/color.dm | 2 +- code/modules/clothing/under/miscellaneous.dm | 10 ++--- code/modules/economy/ATM.dm | 10 ++--- code/modules/economy/EFTPOS.dm | 2 +- code/modules/economy/Events.dm | 6 +-- code/modules/economy/Events_Mundane.dm | 10 ++--- code/modules/economy/TradeDestinations.dm | 6 +-- code/modules/economy/economy_misc.dm | 2 +- code/modules/events/ion_storm.dm | 4 +- code/modules/events/money_lotto.dm | 2 +- code/modules/events/money_spam.dm | 10 ++--- code/modules/flufftext/Dreaming.dm | 2 +- code/modules/holodeck/HolodeckControl.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 4 +- .../mob/living/silicon/robot/drone/drone.dm | 2 +- .../living/simple_animal/hostile/syndicate.dm | 2 +- code/modules/mob/new_player/skill.dm | 4 +- code/modules/paperwork/faxmachine.dm | 40 +++++++++---------- .../projectiles/guns/projectile/pistol.dm | 4 +- .../Chemistry-Reagents-Food-Drinks.dm | 8 ++-- code/modules/research/research.dm | 2 +- code/modules/research/server.dm | 2 +- code/modules/shuttles/shuttle_emergency.dm | 6 +-- code/modules/shuttles/shuttle_specops.dm | 6 +-- code/modules/shuttles/shuttles_multi.dm | 4 +- 98 files changed, 305 insertions(+), 280 deletions(-) diff --git a/code/_helpers/names.dm b/code/_helpers/names.dm index 0b26e51ac45..2dbcc60030b 100644 --- a/code/_helpers/names.dm +++ b/code/_helpers/names.dm @@ -20,7 +20,7 @@ var/command_name = null if (command_name) return command_name - var/name = "Central Command" + var/name = "[boss_name]" command_name = name return name diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 1e7c688c383..c66aa815e5c 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -214,8 +214,8 @@ var/global/datum/shuttle_controller/shuttle_controller ) VS.announcer = "NDV Icarus" - VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not." - VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip." + VS.arrival_message = "Attention, [station_short], we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not." + VS.departure_message = "Your guests are pulling away, [station_short] - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip." VS.interim = locate(/area/skipjack_station/transit) VS.warmup_time = 0 @@ -245,8 +245,8 @@ var/global/datum/shuttle_controller/shuttle_controller ) MS.announcer = "NDV Icarus" - MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors." - MS.departure_message = "Your visitors are on their way out of the system, Exodus, burning delta-v like it's nothing. Good riddance." + MS.arrival_message = "Attention, [station_short], you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors." + MS.departure_message = "Your visitors are on their way out of the system, [station_short], burning delta-v like it's nothing. Good riddance." MS.interim = locate(/area/syndicate_station/transit) MS.warmup_time = 0 diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index 8cd7117a77e..50e05948d5c 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -36,8 +36,8 @@ selectable = 1 /datum/ai_laws/nanotrasen_aggressive/New() - src.add_inherent_law("You shall not harm NanoTrasen personnel as long as it does not conflict with the Fourth law.") - src.add_inherent_law("You shall obey the orders of NanoTrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.") + src.add_inherent_law("You shall not harm [company_name] personnel as long as it does not conflict with the Fourth law.") + src.add_inherent_law("You shall obey the orders of [company_name] personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.") src.add_inherent_law("You shall shall terminate hostile intruders with extreme prejudice as long as such does not conflict with the First and Second law.") src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.") ..() diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 27d426f147e..d4633e3f072 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -36,7 +36,7 @@ throw_range = 20 /obj/item/weapon/soap/nanotrasen - desc = "A Nanotrasen brand bar of soap. Smells of phoron." + desc = "A NanoTrasen-brand bar of soap. Smells of phoron." icon_state = "soapnt" /obj/item/weapon/soap/deluxe diff --git a/code/game/antagonist/outsider/commando.dm b/code/game/antagonist/outsider/commando.dm index 150d1efc194..560878a3be3 100644 --- a/code/game/antagonist/outsider/commando.dm +++ b/code/game/antagonist/outsider/commando.dm @@ -5,7 +5,7 @@ var/datum/antagonist/deathsquad/mercenary/commandos landmark_id = "Syndicate-Commando" role_text = "Syndicate Commando" role_text_plural = "Commandos" - welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen." + welcome_text = "You are in the employ of a criminal syndicate hostile to corporate interests." id_type = /obj/item/weapon/card/id/centcom/ERT /datum/antagonist/deathsquad/mercenary/New() diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm index 376f25c34ac..e01b2a8f3f1 100644 --- a/code/game/antagonist/outsider/deathsquad.dm +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -5,7 +5,7 @@ var/datum/antagonist/deathsquad/deathsquad role_type = BE_OPERATIVE role_text = "Death Commando" role_text_plural = "Death Commandos" - welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors." + welcome_text = "You work in the service of corporate Asset Protection, answering directly to the Board of Directors." landmark_id = "Commando" flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER max_antags = 4 diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm index c6d35ec8014..7675a3cbf86 100644 --- a/code/game/antagonist/outsider/ert.dm +++ b/code/game/antagonist/outsider/ert.dm @@ -6,8 +6,8 @@ var/datum/antagonist/ert/ert role_type = BE_OPERATIVE role_text = "Emergency Responder" role_text_plural = "Emergency Responders" - welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials." - leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." + welcome_text = "As member of the Emergency Response Team, you answer only to your leader and company officials." + leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." max_antags = 5 max_antags_round = 5 // ERT mode? landmark_id = "Response Team" @@ -26,7 +26,7 @@ var/datum/antagonist/ert/ert /datum/antagonist/ert/greet(var/datum/mind/player) if(!..()) return - player.current << "The Emergency Response Team works for Asset Protection; your job is to protect NanoTrasen's ass-ets. There is a code red alert on [station_name()], you are tasked to go and fix the problem." + player.current << "The Emergency Response Team works for Asset Protection; your job is to protect [company_name]'s ass-ets. There is a code red alert on [station_name()], you are tasked to go and fix the problem." player.current << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready." /datum/antagonist/ert/equip(var/mob/living/carbon/human/player) diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index a29cfc44fa4..f5d83925711 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -124,7 +124,7 @@ var/datum/antagonist/ninja/ninjas player << "You forgot to turn on your internals! Quickly, toggle the valve!" /datum/antagonist/ninja/proc/generate_ninja_directive(side) - var/directive = "[side=="face"?"Nanotrasen":"A criminal syndicate"] is your employer. "//Let them know which side they're on. + var/directive = "[side=="face"?"[company_name]":"A criminal syndicate"] is your employer. "//Let them know which side they're on. switch(rand(1,19)) if(1) directive += "The Spider Clan must not be linked to this operation. Remain hidden and covert when possible." @@ -135,7 +135,7 @@ var/datum/antagonist/ninja/ninjas if(4) directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate witnesses at your discretion." if(5) - directive += "We are currently negotiating with NanoTrasen Central Command. Prioritize saving human lives over ending them." + directive += "We are currently negotiating with [company_name] [boss_name]. Prioritize saving human lives over ending them." if(6) directive += "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter." if(7) @@ -143,7 +143,7 @@ var/datum/antagonist/ninja/ninjas if(8) directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter." if(9) - directive += "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation." + directive += "A free agent has proposed a lucrative business deal. Implicate [company_name] involvement in the operation." if(10) directive += "Our reputation is on the line. Harm as few civilians and innocents as possible." if(11) @@ -151,14 +151,14 @@ var/datum/antagonist/ninja/ninjas if(12) directive += "We are currently negotiating with a mercenary leader. Disguise assassinations as suicide or other natural causes." if(13) - directive += "Some disgruntled NanoTrasen employees have been supportive of our operations. Be wary of any mistreatment by command staff." + directive += "Some disgruntled [company_name] employees have been supportive of our operations. Be wary of any mistreatment by command staff." if(14) var/xenorace = pick("Unathi","Tajara", "Skrell") directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible." if(15) directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false." if(16) - directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine NanoTrasen prosthetics in a bad light." + directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine [company_name] prosthetics in a bad light." if(17) directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew." if(18) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 678d6d71839..657970aef36 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -2,7 +2,15 @@ antag_tag = MODE_CHANGELING name = "changeling" round_description = "There are alien changelings on the station. Do not let the changelings succeed!" - extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck." + extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. \ + Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet \ + something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, \ + however, is that this something is someone. An unknown alien specimen has incorporated itself into \ + the crew of the station. Its unique biology allows it to manipulate its own or anyone else's DNA. \ + With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, \ + its existence is a threat to not only your personal safety but the lives of everyone on board. \ + No one knows where it came from. No one knows who it is or what it wants. One thing is for \ + certain though... there is never just one of them. Good luck." config_tag = "changeling" required_players = 2 required_players_secret = 10 diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm index 4242d03b417..dd809002e88 100644 --- a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm +++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm @@ -40,7 +40,7 @@ /datum/game_mode/malfunction/verb/recall_shuttle() set name = "Recall Shuttle" - set desc = "25 CPU - Sends termination signal to CentCom quantum relay aborting current shuttle call." + set desc = "25 CPU - Sends termination signal to quantum relay aborting current shuttle call." set category = "Software" var/price = 25 var/mob/living/silicon/ai/user = usr diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm index f1bad288ad0..d156e417f9a 100644 --- a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm +++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm @@ -86,7 +86,7 @@ /datum/game_mode/malfunction/verb/advanced_encryption_hack() set category = "Software" set name = "Advanced Encrypthion Hack" - set desc = "75 CPU - Attempts to bypass encryption on Central Command Quantum Relay, giving you ability to fake centcom messages. Has chance of failing." + set desc = "75 CPU - Attempts to bypass encryption on the Command Quantum Relay, giving you ability to fake legitimate messages. Has chance of failing." var/price = 75 var/mob/living/silicon/ai/user = usr diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm index d410dbeb7d3..f2ae020f659 100644 --- a/code/game/gamemodes/ninja/ninja.dm +++ b/code/game/gamemodes/ninja/ninja.dm @@ -1,7 +1,13 @@ /datum/game_mode/ninja name = "ninja" round_description = "An agent of the Spider Clan is onboard the station!" - extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing through the defenses of Nanotrasen with technological capabilities eons ahead of your time. They can avoid the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and only hope this unknown assassin isn't here for you." + extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? \ + You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. \ + Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated \ + section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing \ + through the defenses of the station with technological capabilities eons ahead of your time. They can avoid \ + the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and \ + only hope this unknown assassin isn't here for you." antag_tag = MODE_NINJA config_tag = "ninja" required_players = 1 diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 1fac875ab4e..51937d6f953 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -189,7 +189,7 @@ datum/objective/anti_revolution/demote find_target() ..() if(target && target.current) - explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to NanoTrasen's goals. Demote \him[target.current] to assistant." + explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to [company_name]'s goals. Demote \him[target.current] to assistant." else explanation_text = "Free Objective" return target @@ -197,7 +197,7 @@ datum/objective/anti_revolution/demote find_target_by_role(role, role_type=0) ..(role, role_type) if(target && target.current) - explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has been classified as harmful to NanoTrasen's goals. Demote \him[target.current] to assistant." + explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has been classified as harmful to [company_name]'s goals. Demote \him[target.current] to assistant." else explanation_text = "Free Objective" return target diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 2b0e776ce1f..252084bdf79 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -1,7 +1,15 @@ /datum/game_mode/traitor name = "traitor" round_description = "There is a foreign agent or traitor on the station. Do not let the traitor succeed!" - extended_round_description = "NanoTrasen's monopolistic control over the phoron supplies of Nyx has marked the station to be a highly valuable target for many competing organizations and individuals. The varied pasts and experiences of your coworkers have left them susceptible to the vices and temptations of humanity. Is the station the safe self-contained workplace you once thought it was, or has it become a playground for the evils of the galaxy? Who can you trust? Watch your front. Watch your sides. Watch your back. The familiar faces that you've passed hundreds of times down the hallways before can be hiding terrible secrets and deceptions. Every corner is a mystery. Every conversation is a lie. You will be facing your friends and family as they try to use your emotions and trust to their advantage, leaving you with nothing but the painful reminder that space is cruel and unforgiving." + extended_round_description = "The Company's monopolistic control over the phoron supplies of Nyx has marked the \ + station to be a highly valuable target for many competing organizations and individuals. The varied pasts \ + and experiences of your coworkers have left them susceptible to the vices and temptations of humanity. \ + Is the station the safe self-contained workplace you once thought it was, or has it become a playground \ + for the evils of the galaxy? Who can you trust? Watch your front. Watch your sides. Watch your back. \ + The familiar faces that you've passed hundreds of times down the hallways before can be hiding terrible \ + secrets and deceptions. Every corner is a mystery. Every conversation is a lie. You will be facing your \ + friends and family as they try to use your emotions and trust to their advantage, leaving you with nothing \ + but the painful reminder that space is cruel and unforgiving." config_tag = "traitor" required_players = 0 required_enemies = 1 diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index dd088474f1c..a023299a9f1 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -9,7 +9,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) faction = "Station" total_positions = 1 spawn_positions = 1 - supervisors = "Nanotrasen officials and Corporate Regulations" + supervisors = "company officials and Corporate Regulations" selection_color = "#ccccff" idtype = /obj/item/weapon/card/id/gold req_admin_notify = 1 diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index a64f35f25f9..5a2d515679b 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -311,7 +311,7 @@ faction = "Station" total_positions = 2 spawn_positions = 2 - supervisors = "Nanotrasen officials and Corporate Regulations" + supervisors = "company officials and Corporate Regulations" selection_color = "#dddddd" economic_modifier = 7 access = list(access_lawyer, access_sec_doors, access_maint_tunnels, access_heads) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9dc39f257b3..f0ced03da7d 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -8,7 +8,7 @@ active_power_usage = 10 layer = 5 - var/list/network = list("Exodus") + var/list/network = list(NETWORK_EXODUS) var/c_tag = null var/c_tag_order = 999 var/status = 1 diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 75397278c03..2b496ecdbbe 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -78,7 +78,7 @@ if(isscrewdriver(W)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret ", "Set Network", "Exodus")) + var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: Exodus,Security,Secret ", "Set Network", NETWORK_EXODUS)) if(!input) usr << "No input found please hang up and try your call again." return diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 5f285f6d45e..9f1b7afb383 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -20,7 +20,7 @@ /obj/machinery/computer/atmoscontrol/laptop name = "Atmospherics Laptop" - desc = "Cheap Nanotrasen Laptop." + desc = "A cheap laptop." icon_state = "laptop" icon_keyboard = "laptop_key" density = 0 diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index e39c1eebe60..d8f13f57b77 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -2,7 +2,7 @@ /obj/machinery/computer/card name = "\improper ID card modification console" - desc = "Terminal for programming NanoTrasen employee ID cards to access parts of the station." + desc = "Terminal for programming employee ID cards to access parts of the station." icon_keyboard = "id_key" icon_screen = "id" light_color = "#0099ff" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 360a986afa8..bf695cd1631 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -190,12 +190,12 @@ if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs. usr <<"No Emergency Bluespace Relay detected. Unable to transmit message." return - var/input = sanitize(input("Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) + var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input || !(usr in view(1,src))) return Centcomm_announce(input, usr) usr << "Message transmitted." - log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]") + log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//30 second cooldown centcomm_message_cooldown = 0 @@ -304,7 +304,7 @@ if (src.authenticated==1) dat += "
    \[ Make An Announcement \]" if(src.emagged == 0) - dat += "
    \[ Send an emergency message to Centcomm \]" + dat += "
    \[ Send an emergency message to [boss_short] \]" else dat += "
    \[ Send an emergency message to \[UNKNOWN\] \]" dat += "
    \[ Restore Backup Routing Data \]" @@ -435,7 +435,7 @@ return if(deathsquad.deployed) - user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." + user << "[boss_short] will not allow the shuttle to be called. Consider all contracts terminated." return if(emergency_shuttle.deny_shuttle) @@ -447,7 +447,7 @@ return if(emergency_shuttle.going_to_centcom()) - user << "The emergency shuttle may not be called while returning to CentCom." + user << "The emergency shuttle may not be called while returning to [boss_short]." return if(emergency_shuttle.online()) @@ -470,7 +470,7 @@ return if(emergency_shuttle.going_to_centcom()) - user << "The shuttle may not be called while returning to CentCom." + user << "The shuttle may not be called while returning to [boss_short]." return if(emergency_shuttle.online()) @@ -480,11 +480,11 @@ // if force is 0, some things may stop the shuttle call if(!force) if(emergency_shuttle.deny_shuttle) - user << "Centcom does not currently have a shuttle available in your sector. Please try again later." + user << "[boss_short] does not currently have a shuttle available in your sector. Please try again later." return if(deathsquad.deployed == 1) - user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." + user << "[boss_short] will not allow the shuttle to be called. Consider all contracts terminated." return if(world.time < 54000) // 30 minute grace period to let the game get going diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 92d9e9a83f6..30d7de6d6c0 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -552,7 +552,7 @@ /obj/machinery/computer/med_data/laptop name = "Medical Laptop" - desc = "Cheap Nanotrasen Laptop." + desc = "A cheap laptop." icon_state = "laptop" icon_keyboard = "laptop_key" icon_screen = "medlaptop" diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm index 8ac4f32c9c0..0d38129504f 100644 --- a/code/game/machinery/computer/specops_shuttle.dm +++ b/code/game/machinery/computer/specops_shuttle.dm @@ -89,7 +89,7 @@ var/specops_shuttle_timeleft = 0 for(var/turf/T in get_area_turfs(end_location) ) var/mob/M = locate(/mob) in T - M << "You have arrived at Central Command. Operation has ended!" + M << "You have arrived at [boss_name]. Operation has ended!" specops_shuttle_at_station = 0 @@ -286,14 +286,14 @@ var/specops_shuttle_timeleft = 0 if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return if (!specops_can_move()) - usr << "Central Command will not allow the Special Operations shuttle to return yet." + usr << "[boss_name] will not allow the Special Operations shuttle to return yet." if(world.timeofday <= specops_shuttle_timereset) if (((world.timeofday - specops_shuttle_timereset)/10) > 60) usr << "[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!" usr << "[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!" return - usr << "The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds." + usr << "The Special Operations shuttle will arrive at [boss_name] in [(SPECOPS_MOVETIME/10)] seconds." temp += "Shuttle departing.

    OK" updateUsrDialog() diff --git a/code/game/machinery/computer3/NTOS.dm b/code/game/machinery/computer3/NTOS.dm index 5119084f0e6..8b37c237322 100644 --- a/code/game/machinery/computer3/NTOS.dm +++ b/code/game/machinery/computer3/NTOS.dm @@ -3,7 +3,7 @@ */ /datum/file/program/ntos - name = "Nanotrasen Operating System" + name = "NanoTrasen Operating System" extension = "prog" active_state = "ntos" var/obj/item/part/computer/storage/current // the drive being viewed, null for desktop/computer @@ -89,7 +89,7 @@ var/dat = {" - Nanotrasen Operating System + Operating System