mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-16 05:02:18 +00:00
Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into 9/6/2015_baymerge
Conflicts: .travis.yml code/game/gamemodes/cult/cult.dm code/game/gamemodes/heist/heist.dm code/game/gamemodes/ninja/ninja.dm code/game/gamemodes/nuclear/nuclear.dm code/game/gamemodes/traitor/traitor.dm code/game/gamemodes/wizard/wizard.dm code/game/jobs/job/civilian.dm code/game/jobs/job/medical.dm code/game/jobs/job/security.dm code/game/objects/structures/lattice.dm code/global.dm code/modules/projectiles/ammunition/boxes.dm code/modules/reagents/Chemistry-Recipes.dm config/example/config.txt polaris.dme
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
/obj/item/weapon/tank/jetpack/verb/moveup()
|
||||
set name = "Move Upwards"
|
||||
set category = "Object"
|
||||
if(allow_thrust(0.01, usr))
|
||||
var/turf/controllerlocation = locate(1, 1, usr.z)
|
||||
var/legal = 0
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
legal = controller.up
|
||||
if (controller.up)
|
||||
var/turf/T = locate(usr.x, usr.y, controller.up_target)
|
||||
if(T && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
usr << "<span class='warning'>You bump into \the [A].</span>"
|
||||
break
|
||||
if(!blocked)
|
||||
usr.Move(T)
|
||||
usr << "You move upwards."
|
||||
else
|
||||
usr << "<span class='warning'>There is something in your way.</span>"
|
||||
if (legal == 0)
|
||||
usr << "There is nothing of interest in this direction."
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/tank/jetpack/verb/movedown()
|
||||
set name = "Move Downwards"
|
||||
set category = "Object"
|
||||
if(allow_thrust(0.01, usr))
|
||||
var/turf/controllerlocation = locate(1, 1, usr.z)
|
||||
var/legal = 0
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
legal = controller.down
|
||||
if (controller.down == 1)
|
||||
var/turf/T = locate(usr.x, usr.y, controller.down_target)
|
||||
var/turf/S = locate(usr.x, usr.y, usr.z)
|
||||
if(T && (istype(S, /turf/space) || istype(S, /turf/simulated/floor/open)))
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
usr << "<span class='warning'>You bump into \the [A].</span>"
|
||||
break
|
||||
if(!blocked)
|
||||
usr.Move(T)
|
||||
usr << "You move downwards."
|
||||
else
|
||||
usr << "<span class='warning'>You cant move through the floor.</span>"
|
||||
if (legal == 0)
|
||||
usr << "There is nothing of interest in this direction."
|
||||
return 1
|
||||
@@ -1,274 +0,0 @@
|
||||
///////////////////////////////////////
|
||||
//Contents: Ladders, Hatches, Stairs.//
|
||||
///////////////////////////////////////
|
||||
|
||||
/obj/multiz
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
density = 0
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
|
||||
CanPass(obj/mover, turf/source, height, airflow)
|
||||
return airflow || !density
|
||||
|
||||
/obj/multiz/ladder
|
||||
icon_state = "ladderdown"
|
||||
name = "ladder"
|
||||
desc = "A ladder. You climb up and down it."
|
||||
|
||||
var/d_state = 1
|
||||
var/obj/multiz/target
|
||||
|
||||
New()
|
||||
. = ..()
|
||||
|
||||
proc/connect()
|
||||
if(icon_state == "ladderdown") // the upper will connect to the lower
|
||||
d_state = 1
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
for(var/obj/multiz/ladder/L in below)
|
||||
if(L.icon_state == "ladderup")
|
||||
target = L
|
||||
L.target = src
|
||||
d_state = 0
|
||||
break
|
||||
return
|
||||
|
||||
/* ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
if(icon_state == "ladderup" && prob(10))
|
||||
qdel(src)
|
||||
if(2.0)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
if(3.0)
|
||||
qdel(src)
|
||||
return*/
|
||||
|
||||
Destroy()
|
||||
spawn(1)
|
||||
if(target && icon_state == "ladderdown")
|
||||
qdel(target)
|
||||
return ..()
|
||||
|
||||
attackby(obj/item/C as obj, mob/user as mob)
|
||||
(..)
|
||||
|
||||
// construction commented out for balance concerns
|
||||
/* if (!target && istype(C, /obj/item/stack/rods))
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
var/found = 0
|
||||
var/obj/item/stack/rods/S = C
|
||||
if(S.amount < 2)
|
||||
user << "You dont have enough rods to finish the ladder."
|
||||
return
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
found = 1
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
var/blocked = 0
|
||||
for(var/atom/A in below.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
break
|
||||
if(!blocked && !istype(below, /turf/simulated/wall))
|
||||
var/obj/multiz/ladder/X = new /obj/multiz/ladder(below)
|
||||
S.amount = S.amount - 2
|
||||
if(S.amount == 0) qdel(S)
|
||||
X.icon_state = "ladderup"
|
||||
connect()
|
||||
user << "You finish the ladder."
|
||||
else
|
||||
user << "The area below is blocked."
|
||||
if(!found)
|
||||
user << "You cant build a ladder down there."
|
||||
return
|
||||
|
||||
else if (icon_state == "ladderdown" && d_state == 0 && istype(C, /obj/item/weapon/wrench))
|
||||
user << "<span class='notice'>You start loosening the anchoring bolts which secure the ladder to the frame.</span>"
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
|
||||
|
||||
sleep(30)
|
||||
if(!user || !C) return
|
||||
|
||||
src.d_state = 1
|
||||
if(target)
|
||||
var/obj/item/stack/rods/R = PoolOrNew(/obj/item/stack/rods, target.loc)
|
||||
R.amount = 2
|
||||
qdel(Target)
|
||||
|
||||
user << "<span class='notice'>You remove the bolts anchoring the ladder.</span>"
|
||||
return
|
||||
|
||||
else if (icon_state == "ladderdown" && d_state == 1 && istype(C, /obj/item/weapon/weldingtool) )
|
||||
var/obj/item/weapon/weldingtool/WT = C
|
||||
if( WT.remove_fuel(0,user) )
|
||||
|
||||
user << "<span class='notice'>You begin to remove the ladder.</span>"
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
|
||||
sleep(60)
|
||||
if(!user || !WT || !WT.isOn()) return
|
||||
|
||||
var/obj/item/stack/material/steel/S = new /obj/item/stack/material/steel( src )
|
||||
S.amount = 2
|
||||
user << "<span class='notice'>You remove the ladder and close the hole.</span>"
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
return
|
||||
|
||||
else
|
||||
src.attack_hand(user)
|
||||
return*/
|
||||
src.attack_hand(user)
|
||||
return
|
||||
|
||||
attack_hand(var/mob/M)
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
M << "The ladder is incomplete and can't be climbed."
|
||||
else
|
||||
var/turf/T = target.loc
|
||||
var/blocked = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(A.density)
|
||||
blocked = 1
|
||||
break
|
||||
if(blocked || istype(T, /turf/simulated/wall))
|
||||
M << "Something is blocking the ladder."
|
||||
else
|
||||
M.visible_message("<span class='notice'>\The [M] climbs [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!</span>", "You climb [src.icon_state == "ladderup" ? "up" : "down"] \the [src]!", "You hear some grunting, and clanging of a metal ladder being used.")
|
||||
M.Move(target.loc)
|
||||
|
||||
/* hatch
|
||||
icon_state = "hatchdown"
|
||||
name = "hatch"
|
||||
desc = "A hatch. You climb down it, and it will automatically seal against pressure loss behind you."
|
||||
top_icon_state = "hatchdown"
|
||||
var/top_icon_state_open = "hatchdown-open"
|
||||
var/top_icon_state_close = "hatchdown-close"
|
||||
|
||||
bottom_icon_state = "ladderup"
|
||||
|
||||
var/image/green_overlay
|
||||
var/image/red_overlay
|
||||
|
||||
var/active = 0
|
||||
|
||||
New()
|
||||
. = ..()
|
||||
red_overlay = image(icon, "red-ladderlight")
|
||||
green_overlay = image(icon, "green-ladderlight")
|
||||
|
||||
attack_hand(var/mob/M)
|
||||
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
qdel(src)
|
||||
|
||||
if(active)
|
||||
M << "That [src] is being used."
|
||||
return // It is a tiny airlock, only one at a time.
|
||||
|
||||
active = 1
|
||||
var/obj/multiz/ladder/hatch/top_hatch = target
|
||||
var/obj/multiz/ladder/hatch/bottom_hatch = src
|
||||
if(icon_state == top_icon_state)
|
||||
top_hatch = src
|
||||
bottom_hatch = target
|
||||
|
||||
flick(top_icon_state_open, top_hatch)
|
||||
bottom_hatch.overlays += green_overlay
|
||||
|
||||
spawn(7)
|
||||
if(!target || !istype(target.loc, /turf))
|
||||
qdel(src)
|
||||
if(M.z == z && get_dist(src,M) <= 1)
|
||||
var/list/adjacent_to_me = global_adjacent_z_levels["[z]"]
|
||||
M.visible_message("<span class='notice'>\The [M] scurries [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!</span>", "You scramble [target.z == adjacent_to_me["up"] ? "up" : "down"] \the [src]!", "You hear some grunting, and a hatch sealing.")
|
||||
M.Move(target.loc)
|
||||
flick(top_icon_state_close,top_hatch)
|
||||
bottom_hatch.overlays -= green_overlay
|
||||
bottom_hatch.overlays += red_overlay
|
||||
|
||||
spawn(7)
|
||||
top_hatch.icon_state = top_icon_state
|
||||
bottom_hatch.overlays -= red_overlay
|
||||
active = 0*/
|
||||
|
||||
/obj/multiz/stairs
|
||||
name = "Stairs"
|
||||
desc = "Stairs. You walk up and down them."
|
||||
icon_state = "rampbottom"
|
||||
var/obj/multiz/stairs/connected
|
||||
var/turf/target
|
||||
var/turf/target2
|
||||
var/suggest_dir // try this dir first when finding stairs; this is the direction to walk *down* the stairs
|
||||
|
||||
New()
|
||||
..()
|
||||
var/turf/cl= locate(1, 1, src.z)
|
||||
for(var/obj/effect/landmark/zcontroller/c in cl)
|
||||
if(c.up)
|
||||
var/turf/O = locate(src.x, src.y, c.up_target)
|
||||
if(istype(O, /turf/space))
|
||||
O.ChangeTurf(/turf/simulated/floor/open)
|
||||
|
||||
spawn(1)
|
||||
var/turf/T
|
||||
if(suggest_dir)
|
||||
T = get_step(src.loc,suggest_dir)
|
||||
find_stair_connection(T, suggest_dir, 1)
|
||||
if(!target)
|
||||
for(var/dir in cardinal)
|
||||
T = get_step(src.loc,dir)
|
||||
find_stair_connection(T, dir)
|
||||
if(target)
|
||||
break
|
||||
|
||||
Bumped(var/atom/movable/M)
|
||||
if(connected && target && istype(src, /obj/multiz/stairs) && locate(/obj/multiz/stairs) in M.loc)
|
||||
var/obj/multiz/stairs/Con = locate(/obj/multiz/stairs) in M.loc
|
||||
if(Con == src.connected) //make sure the atom enters from the approriate lower stairs tile
|
||||
M.Move(target)
|
||||
return
|
||||
|
||||
proc/find_stair_connection(var/turf/T, var/dir, var/suggested=0)
|
||||
for(var/obj/multiz/stairs/S in T)
|
||||
if(S && S.icon_state == "rampbottom" && !S.connected)
|
||||
if(!S.suggest_dir || S.suggest_dir == dir) // it doesn't have a suggested direction, or it's the same direction as we're trying, so we connect to it
|
||||
initialise_stair_connection(src, S, dir)
|
||||
else if(!suggested) // we're trying directions, so it could be a reverse stair (i.e. we're the bottom stair rather than the top)
|
||||
var/inv_dir = 0
|
||||
switch(dir)
|
||||
if(1)
|
||||
inv_dir = 2
|
||||
if(2)
|
||||
inv_dir = 1
|
||||
if(4)
|
||||
inv_dir = 8
|
||||
if(8)
|
||||
inv_dir = 4
|
||||
if(S.suggest_dir == inv_dir)
|
||||
initialise_stair_connection(S, src, inv_dir)
|
||||
|
||||
proc/initialise_stair_connection(var/obj/multiz/stairs/top, var/obj/multiz/stairs/bottom, var/dir)
|
||||
top.set_dir(dir)
|
||||
bottom.set_dir(dir)
|
||||
top.connected = bottom
|
||||
bottom.connected = top
|
||||
top.icon_state = "ramptop"
|
||||
top.density = 1
|
||||
var/turf/controllerlocation = locate(1, 1, top.z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up)
|
||||
var/turf/above = locate(top.x, top.y, controller.up_target)
|
||||
if(istype(above,/turf/space) || istype(above,/turf/simulated/floor/open))
|
||||
top.target = above
|
||||
var/turf/above2 = locate(bottom.x, bottom.y, controller.up_target)
|
||||
if(istype(above2, /turf/space) || istype(above,/turf/simulated/floor/open))
|
||||
top.target2 = above2
|
||||
return
|
||||
@@ -1,11 +0,0 @@
|
||||
/obj/multiz/stairs/north_up
|
||||
suggest_dir = SOUTH
|
||||
|
||||
/obj/multiz/stairs/south_up
|
||||
suggest_dir = NORTH
|
||||
|
||||
/obj/multiz/stairs/east_up
|
||||
suggest_dir = WEST
|
||||
|
||||
/obj/multiz/stairs/west_up
|
||||
suggest_dir = EAST
|
||||
@@ -1,128 +0,0 @@
|
||||
/turf/simulated/floor/open
|
||||
name = "open space"
|
||||
density = 0
|
||||
icon_state = "black"
|
||||
pathweight = 100000 //Seriously, don't try and path over this one numbnuts
|
||||
var/icon/darkoverlays = null
|
||||
var/turf/floorbelow
|
||||
var/list/overlay_references
|
||||
|
||||
New()
|
||||
..()
|
||||
getbelow()
|
||||
return
|
||||
|
||||
Enter(var/atom/movable/AM)
|
||||
if (..()) //TODO make this check if gravity is active (future use) - Sukasa
|
||||
spawn(1)
|
||||
// only fall down in defined areas (read: areas with artificial gravitiy)
|
||||
if(!floorbelow) //make sure that there is actually something below
|
||||
if(!getbelow())
|
||||
return
|
||||
if(AM)
|
||||
var/area/areacheck = get_area(src)
|
||||
var/blocked = 0
|
||||
var/soft = 0
|
||||
for(var/atom/A in floorbelow.contents)
|
||||
if(A.density)
|
||||
if(istype(A, /obj/structure/window))
|
||||
var/obj/structure/window/W = A
|
||||
blocked = W.is_fulltile()
|
||||
if(blocked)
|
||||
break
|
||||
else
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/machinery/atmospherics/pipe/zpipe/up) && istype(AM,/obj/item/pipe))
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/structure/disposalpipe/up) && istype(AM,/obj/item/pipe))
|
||||
blocked = 1
|
||||
break
|
||||
if(istype(A, /obj/multiz/stairs))
|
||||
soft = 1
|
||||
//dont break here, since we still need to be sure that it isnt blocked
|
||||
|
||||
if (soft || (!blocked && !(areacheck.name == "Space")))
|
||||
AM.Move(floorbelow)
|
||||
if (!soft && istype(AM, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
var/damage = 5
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "head")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "chest")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_leg")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_leg")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "l_arm")
|
||||
H.apply_damage(min(rand(-damage,damage),0), BRUTE, "r_arm")
|
||||
H:weakened = max(H:weakened,2)
|
||||
H:updatehealth()
|
||||
return ..()
|
||||
|
||||
/turf/proc/hasbelow()
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/simulated/floor/open/proc/getbelow()
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
// check if there is something to draw below
|
||||
if(!controller.down)
|
||||
src.ChangeTurf(get_base_turf(src.z))
|
||||
return 0
|
||||
else
|
||||
floorbelow = locate(src.x, src.y, controller.down_target)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
// override to make sure nothing is hidden
|
||||
/turf/simulated/floor/open/levelupdate()
|
||||
for(var/obj/O in src)
|
||||
O.hide(0)
|
||||
|
||||
//overwrite the attackby of space to transform it to openspace if necessary
|
||||
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
|
||||
if (istype(C, /obj/item/stack/cable_coil) && src.hasbelow())
|
||||
var/turf/simulated/floor/open/W = src.ChangeTurf(/turf/simulated/floor/open)
|
||||
W.attackby(C, user)
|
||||
return
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/open/ex_act(severity)
|
||||
// cant destroy empty space with an ordinary bomb
|
||||
return
|
||||
|
||||
/turf/simulated/floor/open/attackby(obj/item/C as obj, mob/user as mob)
|
||||
(..)
|
||||
if (istype(C, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/cable = C
|
||||
cable.turf_place(src, user)
|
||||
return
|
||||
|
||||
if (istype(C, /obj/item/stack/rods))
|
||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||
if(L)
|
||||
return
|
||||
var/obj/item/stack/rods/R = C
|
||||
if (R.use(1))
|
||||
user << "<span class='notice'>Constructing support lattice...</span>"
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
ReplaceWithLattice()
|
||||
return
|
||||
|
||||
if (istype(C, /obj/item/stack/tile/floor))
|
||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||
if(L)
|
||||
var/obj/item/stack/tile/floor/S = C
|
||||
if (S.get_amount() < 1)
|
||||
return
|
||||
qdel(L)
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
S.use(1)
|
||||
ChangeTurf(/turf/simulated/floor/airless)
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>The plating is going to need some support.</span>"
|
||||
return
|
||||
@@ -1,189 +0,0 @@
|
||||
/obj/effect/landmark/zcontroller
|
||||
name = "Z-Level Controller"
|
||||
var/initialized = 0 // when set to 1, turfs will report to the controller
|
||||
var/up = 0 // 1 allows up movement
|
||||
var/up_target = 0 // the Z-level that is above the current one
|
||||
var/down = 0 // 1 allows down movement
|
||||
var/down_target = 0 // the Z-level that is below the current one
|
||||
|
||||
var/list/slow = list()
|
||||
var/list/normal = list()
|
||||
var/list/fast = list()
|
||||
|
||||
var/slow_time
|
||||
var/normal_time
|
||||
var/fast_time
|
||||
|
||||
/obj/effect/landmark/zcontroller/New()
|
||||
..()
|
||||
for (var/turf/T in world)
|
||||
if (T.z == z)
|
||||
fast += T
|
||||
slow_time = world.time + 3000
|
||||
normal_time = world.time + 600
|
||||
fast_time = world.time + 10
|
||||
|
||||
processing_objects.Add(src)
|
||||
|
||||
initialized = 1
|
||||
return 1
|
||||
|
||||
/obj/effect/landmark/zcontroller/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/zcontroller/process()
|
||||
if (world.time > fast_time)
|
||||
calc(fast)
|
||||
fast_time = world.time + 10
|
||||
|
||||
if (world.time > normal_time)
|
||||
calc(normal)
|
||||
normal_time = world.time + 600
|
||||
|
||||
/* if (world.time > slow_time)
|
||||
calc(slow)
|
||||
slow_time = world.time + 3000 */
|
||||
return
|
||||
|
||||
/obj/effect/landmark/zcontroller/proc/add(var/list/L, var/I, var/transfer)
|
||||
while (L.len)
|
||||
var/turf/T = pick(L)
|
||||
|
||||
L -= T
|
||||
slow -= T
|
||||
normal -= T
|
||||
fast -= T
|
||||
|
||||
if(!T || !istype(T, /turf))
|
||||
continue
|
||||
|
||||
switch (I)
|
||||
if(1) slow += T
|
||||
if(2) normal += T
|
||||
if(3) fast += T
|
||||
|
||||
if(transfer > 0)
|
||||
if(up)
|
||||
var/turf/controller_up = locate(1, 1, up_target)
|
||||
for(var/obj/effect/landmark/zcontroller/c_up in controller_up)
|
||||
var/list/temp = list()
|
||||
temp += locate(T.x, T.y, up_target)
|
||||
c_up.add(temp, I, transfer-1)
|
||||
|
||||
if(down)
|
||||
var/turf/controller_down = locate(1, 1, down_target)
|
||||
for(var/obj/effect/landmark/zcontroller/c_down in controller_down)
|
||||
var/list/temp = list()
|
||||
temp += locate(T.x, T.y, down_target)
|
||||
c_down.add(temp, I, transfer-1)
|
||||
return
|
||||
|
||||
/turf
|
||||
var/list/z_overlays = list()
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
|
||||
var/turf/controller = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/c in controller)
|
||||
if(c.initialized)
|
||||
var/list/turf = list()
|
||||
turf += src
|
||||
c.add(turf,3,1)
|
||||
|
||||
atom/movable/Move() //Hackish
|
||||
. = ..()
|
||||
|
||||
var/turf/controllerlocation = locate(1, 1, src.z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up || controller.down)
|
||||
var/list/temp = list()
|
||||
temp += locate(src.x, src.y, src.z)
|
||||
controller.add(temp,3,1)
|
||||
|
||||
/obj/effect/landmark/zcontroller/proc/calc(var/list/L)
|
||||
var/list/slowholder = list()
|
||||
var/list/normalholder = list()
|
||||
var/list/fastholder = list()
|
||||
var/new_list
|
||||
|
||||
while(L.len)
|
||||
var/turf/T = pick(L)
|
||||
new_list = 0
|
||||
|
||||
if(!T || !istype(T, /turf))
|
||||
L -= T
|
||||
continue
|
||||
|
||||
T.overlays -= T.z_overlays
|
||||
T.z_overlays -= T.z_overlays
|
||||
|
||||
if(down && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
|
||||
var/turf/below = locate(T.x, T.y, down_target)
|
||||
if(below)
|
||||
if(!(istype(below, /turf/space) || istype(below, /turf/simulated/floor/open)))
|
||||
var/image/t_img = list()
|
||||
new_list = 1
|
||||
|
||||
var/image/temp = image(below, dir=below.dir, layer = TURF_LAYER + 0.04)
|
||||
|
||||
temp.color = rgb(127,127,127)
|
||||
temp.overlays += below.overlays
|
||||
t_img += temp
|
||||
T.overlays += t_img
|
||||
T.z_overlays += t_img
|
||||
|
||||
// get objects
|
||||
var/image/o_img = list()
|
||||
for(var/obj/o in below)
|
||||
// ingore objects that have any form of invisibility
|
||||
if(o.invisibility) continue
|
||||
new_list = 2
|
||||
var/image/temp2 = image(o, dir=o.dir, layer = TURF_LAYER+0.05*o.layer)
|
||||
temp2.color = rgb(127,127,127)
|
||||
temp2.overlays += o.overlays
|
||||
o_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += o_img
|
||||
T.z_overlays += o_img
|
||||
|
||||
// get mobs
|
||||
var/image/m_img = list()
|
||||
for(var/mob/m in below)
|
||||
// ingore mobs that have any form of invisibility
|
||||
if(m.invisibility) continue
|
||||
// only add this tile to fastprocessing if there is a living mob, not a dead one
|
||||
if(istype(m, /mob/living)) new_list = 3
|
||||
var/image/temp2 = image(m, dir=m.dir, layer = TURF_LAYER+0.05*m.layer)
|
||||
temp2.color = rgb(127,127,127)
|
||||
temp2.overlays += m.overlays
|
||||
m_img += temp2
|
||||
// you need to add a list to .overlays or it will not display any because space
|
||||
T.overlays += m_img
|
||||
T.z_overlays += m_img
|
||||
|
||||
T.overlays -= below.z_overlays
|
||||
T.z_overlays -= below.z_overlays
|
||||
|
||||
L -= T
|
||||
|
||||
if(new_list == 1)
|
||||
slowholder += T
|
||||
if(new_list == 2)
|
||||
normalholder += T
|
||||
if(new_list == 3)
|
||||
fastholder += T
|
||||
for(var/d in cardinal)
|
||||
var/turf/mT = get_step(T,d)
|
||||
if(!(mT in fastholder))
|
||||
fastholder += mT
|
||||
for(var/f in cardinal)
|
||||
var/turf/nT = get_step(mT,f)
|
||||
if(!(nT in fastholder))
|
||||
fastholder += nT
|
||||
|
||||
add(slowholder,1, 0)
|
||||
add(normalholder, 2, 0)
|
||||
add(fastholder, 3, 0)
|
||||
return
|
||||
@@ -1,37 +0,0 @@
|
||||
/obj/effect/landmark/zcontroller/level_1_bottom
|
||||
up = 1
|
||||
up_target = 2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_2_mid
|
||||
up = 1
|
||||
up_target = 3
|
||||
down = 1
|
||||
down_target = 1
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_3_mid
|
||||
up = 1
|
||||
up_target = 4
|
||||
down = 1
|
||||
down_target = 2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_4_mid
|
||||
up = 1
|
||||
up_target = 5
|
||||
down = 1
|
||||
down_target = 3
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_2_top
|
||||
down = 1
|
||||
down_target = 1
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_3_top
|
||||
down = 1
|
||||
down_target = 2
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_4_top
|
||||
down = 1
|
||||
down_target = 3
|
||||
|
||||
/obj/effect/landmark/zcontroller/level_5_top
|
||||
down = 1
|
||||
down_target = 4
|
||||
@@ -64,9 +64,9 @@ turf/c_airblock(turf/other)
|
||||
#ifdef ZLEVELS
|
||||
if(other.z != src.z)
|
||||
if(other.z < src.z)
|
||||
if(!istype(src, /turf/simulated/floor/open)) return BLOCKED
|
||||
if(!istype(src, /turf/simulated/open)) return BLOCKED
|
||||
else
|
||||
if(!istype(other, /turf/simulated/floor/open)) return BLOCKED
|
||||
if(!istype(other, /turf/simulated/open)) return BLOCKED
|
||||
#endif
|
||||
|
||||
var/result = 0
|
||||
|
||||
@@ -281,8 +281,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
var/direct = !(block & ZONE_BLOCKED)
|
||||
var/space = !istype(B)
|
||||
|
||||
if(direct && !space)
|
||||
if(min(A.zone.contents.len, B.zone.contents.len) <= ZONE_MIN_SIZE || equivalent_pressure(A.zone,B.zone) || current_cycle == 0)
|
||||
if(!space)
|
||||
if(min(A.zone.contents.len, B.zone.contents.len) < ZONE_MIN_SIZE || (direct && (equivalent_pressure(A.zone,B.zone) || current_cycle == 0)))
|
||||
merge(A.zone,B.zone)
|
||||
return
|
||||
|
||||
|
||||
@@ -86,3 +86,10 @@
|
||||
//Flags for zone sleeping
|
||||
#define ZONE_ACTIVE 1
|
||||
#define ZONE_SLEEPING 0
|
||||
|
||||
// Defines how much of certain gas do the Atmospherics tanks start with. Values are in kpa per tile (assuming 20C)
|
||||
#define ATMOSTANK_NITROGEN 90000 // A lot of N2 is needed to produce air mix, that's why we keep 90MPa of it
|
||||
#define ATMOSTANK_OXYGEN 40000 // O2 is also important for airmix, but not as much as N2 as it's only 21% of it.
|
||||
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
|
||||
#define ATMOSTANK_PHORON 25000
|
||||
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
|
||||
@@ -24,6 +24,7 @@
|
||||
#define BE_PLANT 0x1000
|
||||
#define BE_MUTINEER 0x2000
|
||||
#define BE_PAI 0x4000
|
||||
#define BE_LOYALIST 0x8000
|
||||
|
||||
var/list/be_special_flags = list(
|
||||
"Traitor" = BE_TRAITOR,
|
||||
@@ -32,6 +33,7 @@ var/list/be_special_flags = list(
|
||||
"Wizard" = BE_WIZARD,
|
||||
"Malf AI" = BE_MALF,
|
||||
"Revolutionary" = BE_REV,
|
||||
"Loyalist" = BE_LOYALIST,
|
||||
"Xenomorph" = BE_ALIEN,
|
||||
"Positronic Brain" = BE_AI,
|
||||
"Cultist" = BE_CULTIST,
|
||||
@@ -77,6 +79,7 @@ var/list/be_special_flags = list(
|
||||
#define MODE_MONKEY "monkey"
|
||||
#define MODE_RENEGADE "renegade"
|
||||
#define MODE_REVOLUTIONARY "revolutionary"
|
||||
#define MODE_LOYALIST "loyalist"
|
||||
#define MODE_MALFUNCTION "malf"
|
||||
#define MODE_TRAITOR "traitor"
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret")
|
||||
#define NETWORK_MINE "MINE"
|
||||
#define NETWORK_RESEARCH "Research"
|
||||
#define NETWORK_RESEARCH_OUTPOST "Research Outpost"
|
||||
#define NETWORK_PRISON "Prison"
|
||||
#define NETWORK_ROBOTS "Robots"
|
||||
#define NETWORK_PRISON "Prison"
|
||||
#define NETWORK_SECURITY "Security"
|
||||
#define NETWORK_TELECOM "Tcomsat"
|
||||
#define NETWORK_THUNDER "thunder"
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
|
||||
#define IMPRINTER 0x1 //For circuits. Uses glass/chemicals.
|
||||
#define PROTOLATHE 0x2 //New stuff. Uses glass/metal/chemicals
|
||||
#define MECHFAB 0x4 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
|
||||
#define MECHFAB 0x4 //Mechfab
|
||||
#define CHASSIS 0x8 //For protolathe, but differently
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define HAS_LIPS 0x4 // Lips are drawn onto the mob icon. (lipstick)
|
||||
#define HAS_UNDERWEAR 0x8 // Underwear is drawn onto the mob icon.
|
||||
#define HAS_EYE_COLOR 0x10 // Eye colour selectable in chargen. (RGB)
|
||||
#define HAS_HAIR_COLOR 0x20 // Hair colour selectable in chargen. (RGB)
|
||||
|
||||
// Languages.
|
||||
#define LANGUAGE_SOL_COMMON "Sol Common"
|
||||
|
||||
@@ -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/////
|
||||
//////////////////////////
|
||||
@@ -118,9 +120,7 @@ var/global/list/endgame_safespawns = list()
|
||||
for (var/language_name in all_languages)
|
||||
var/datum/language/L = all_languages[language_name]
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
language_keys[":[lowertext(L.key)]"] = L
|
||||
language_keys[".[lowertext(L.key)]"] = L
|
||||
language_keys["#[lowertext(L.key)]"] = L
|
||||
language_keys[lowertext(L.key)] = L
|
||||
|
||||
var/rkey = 0
|
||||
paths = typesof(/datum/species)-/datum/species
|
||||
|
||||
@@ -314,3 +314,19 @@ proc/TextPreview(var/string,var/len=40)
|
||||
if(C && (C.prefs.toggles & CHAT_NOICONS))
|
||||
return tagdesc
|
||||
return "<IMG src='\ref[text_tag_icons.icon]' class='text_tag' iconstate='[tagname]'" + (tagdesc ? " alt='[tagdesc]'" : "") + ">"
|
||||
|
||||
/proc/contains_az09(var/input)
|
||||
for(var/i=1, i<=length(input), i++)
|
||||
var/ascii_char = text2ascii(input,i)
|
||||
switch(ascii_char)
|
||||
// A .. Z
|
||||
if(65 to 90) //Uppercase Letters
|
||||
return 1
|
||||
// a .. z
|
||||
if(97 to 122) //Lowercase Letters
|
||||
return 1
|
||||
|
||||
// 0 .. 9
|
||||
if(48 to 57) //Numbers
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -36,9 +36,12 @@ proc/round_duration()
|
||||
|
||||
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
|
||||
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
|
||||
var/mins = (mills % 36000) / 600
|
||||
var/hours = mills / 36000
|
||||
var/mins = round((mills % 36000) / 600)
|
||||
var/hours = round(mills / 36000)
|
||||
|
||||
last_round_duration = "[round(hours)]h [round(mins)]m"
|
||||
mins = mins < 10 ? add_zero(mins, 1) : mins
|
||||
hours = hours < 10 ? add_zero(hours, 1) : hours
|
||||
|
||||
last_round_duration = "[hours]:[mins]"
|
||||
next_duration_update = world.time + 1 MINUTES
|
||||
return last_round_duration
|
||||
|
||||
@@ -243,10 +243,10 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return 1
|
||||
|
||||
//Ensure the frequency is within bounds of what it should be sending/recieving at
|
||||
/proc/sanitize_frequency(var/f)
|
||||
/proc/sanitize_frequency(var/f, var/low = PUBLIC_LOW_FREQ, var/high = PUBLIC_HIGH_FREQ)
|
||||
f = round(f)
|
||||
f = max(1441, f) // 144.1
|
||||
f = min(1489, f) // 148.9
|
||||
f = max(low, f)
|
||||
f = min(high, f)
|
||||
if ((f % 2) == 0) //Ensure the last digit is an odd number
|
||||
f += 1
|
||||
return f
|
||||
@@ -569,7 +569,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
var/turf/current = get_turf(source)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
var/steps = 0
|
||||
|
||||
|
||||
if(!current || !target_turf)
|
||||
return 0
|
||||
|
||||
@@ -1053,12 +1053,10 @@ proc/get_mob_with_client_list()
|
||||
|
||||
//gets the turf the atom is located in (or itself, if it is a turf).
|
||||
//returns null if the atom is not in a turf.
|
||||
/proc/get_turf(atom/location)
|
||||
while(location)
|
||||
if(isturf(location))
|
||||
return location
|
||||
location = location.loc
|
||||
return null
|
||||
/proc/get_turf(atom/A)
|
||||
if(!istype(A)) return
|
||||
for(A, A && !isturf(A), A=A.loc);
|
||||
return A
|
||||
|
||||
/proc/get(atom/loc, type)
|
||||
while(loc)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
build_click(src, client.buildmode, params, A)
|
||||
return
|
||||
|
||||
if(control_disabled || stat)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -51,7 +51,7 @@
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(!canClick())
|
||||
if(control_disabled || !canClick())
|
||||
return
|
||||
|
||||
if(aiCamera.in_camera_mode)
|
||||
@@ -89,13 +89,24 @@
|
||||
*/
|
||||
|
||||
/mob/living/silicon/ai/ShiftClickOn(var/atom/A)
|
||||
A.AIShiftClick(src)
|
||||
if(!control_disabled && A.AIShiftClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
|
||||
A.AICtrlClick(src)
|
||||
if(!control_disabled && A.AICtrlClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/AltClickOn(var/atom/A)
|
||||
A.AIAltClick(src)
|
||||
if(!control_disabled && A.AIAltClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/MiddleClickOn(var/atom/A)
|
||||
A.AIMiddleClick(src)
|
||||
if(!control_disabled && A.AIMiddleClick(src))
|
||||
return
|
||||
..()
|
||||
|
||||
/*
|
||||
The following criminally helpful code is just the previous code cleaned up;
|
||||
@@ -105,11 +116,6 @@
|
||||
/atom/proc/AICtrlShiftClick()
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AICtrlShiftClick()
|
||||
if(emagged)
|
||||
return
|
||||
return
|
||||
|
||||
/atom/proc/AIShiftClick()
|
||||
return
|
||||
|
||||
@@ -118,7 +124,7 @@
|
||||
Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "0"), 1)
|
||||
return
|
||||
return 1
|
||||
|
||||
/atom/proc/AICtrlClick()
|
||||
return
|
||||
@@ -128,15 +134,18 @@
|
||||
Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!)
|
||||
else
|
||||
Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "1"), 1)
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
|
||||
Topic(src, list("src"= "\ref[src]", "breaker"="1"), 1) // 1 meaning no window (consistency!)
|
||||
return 1
|
||||
|
||||
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
|
||||
Topic(src, list("src"= "\ref[src]", "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!)
|
||||
return 1
|
||||
|
||||
/atom/proc/AIAltClick(var/atom/A)
|
||||
AltClick(A)
|
||||
return AltClick(A)
|
||||
|
||||
/obj/machinery/door/airlock/AIAltClick() // Electrifies doors.
|
||||
if(!electrified_until)
|
||||
@@ -145,20 +154,25 @@
|
||||
else
|
||||
// disable/6 is not in Topic; disable/5 disables both temporary and permanent shock
|
||||
Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "0"), 1)
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
|
||||
Topic(src, list("src"= "\ref[src]", "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!)
|
||||
return 1
|
||||
|
||||
/atom/proc/AIMiddleClick()
|
||||
return
|
||||
/atom/proc/AIMiddleClick(var/mob/living/silicon/user)
|
||||
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
|
||||
Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "0"), 1)
|
||||
return
|
||||
return 1
|
||||
|
||||
//
|
||||
// Override AdjacentQuick for AltClicking
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
// faster access to objects already on you
|
||||
if(A.loc != src)
|
||||
setMoveCooldown(10) //getting something out of a backpack
|
||||
|
||||
|
||||
if(W)
|
||||
var/resolved = W.resolve_attackby(A, src)
|
||||
if(!resolved && A && W)
|
||||
@@ -128,7 +128,7 @@
|
||||
if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1))
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
setMoveCooldown(5)
|
||||
|
||||
|
||||
if(W)
|
||||
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
||||
var/resolved = W.resolve_attackby(A,src)
|
||||
@@ -224,10 +224,8 @@
|
||||
Only used for swapping hands
|
||||
*/
|
||||
/mob/proc/MiddleClickOn(var/atom/A)
|
||||
return
|
||||
|
||||
/mob/living/carbon/MiddleClickOn(var/atom/A)
|
||||
swap_hand()
|
||||
return
|
||||
|
||||
// In case of use break glass
|
||||
/*
|
||||
@@ -278,7 +276,7 @@
|
||||
else
|
||||
user.listed_turf = T
|
||||
user.client.statpanel = T.name
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/proc/TurfAdjacent(var/turf/T)
|
||||
return T.AdjacentQuick(src)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// Otherwise jump
|
||||
else
|
||||
following = null
|
||||
loc = get_turf(A)
|
||||
forceMove(get_turf(A))
|
||||
|
||||
/mob/dead/observer/ClickOn(var/atom/A, var/params)
|
||||
if(client.buildmode)
|
||||
|
||||
@@ -29,34 +29,53 @@
|
||||
src << "Somehow you bugged the system. Setting your hardsuit mode to middle-click."
|
||||
hardsuit_click_mode = MIDDLE_CLICK
|
||||
|
||||
/mob/living/carbon/human/MiddleClickOn(atom/A)
|
||||
/mob/living/MiddleClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == MIDDLE_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/AltClickOn(atom/A)
|
||||
/mob/living/AltClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == ALT_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/CtrlClickOn(atom/A)
|
||||
/mob/living/CtrlClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == CTRL_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/HardsuitClickOn(atom/A)
|
||||
if(!canClick())
|
||||
return
|
||||
if(back)
|
||||
var/obj/item/weapon/rig/rig = back
|
||||
if(istype(rig) && rig.selected_module)
|
||||
rig.selected_module.engage(A)
|
||||
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
return 1
|
||||
/mob/living/proc/can_use_rig()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/can_use_rig()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/brain/can_use_rig()
|
||||
return istype(loc, /obj/item/device/mmi)
|
||||
|
||||
/mob/living/silicon/ai/can_use_rig()
|
||||
return carded
|
||||
|
||||
/mob/living/silicon/pai/can_use_rig()
|
||||
return loc == card
|
||||
|
||||
/mob/living/proc/HardsuitClickOn(var/atom/A, var/alert_ai = 0)
|
||||
if(!can_use_rig() || !canClick())
|
||||
return 0
|
||||
var/obj/item/weapon/rig/rig = get_rig()
|
||||
if(istype(rig) && !rig.offline && rig.selected_module)
|
||||
if(src != rig.wearer)
|
||||
if(rig.ai_can_move_suit(src, check_user_module = 1))
|
||||
message_admins("[key_name_admin(src, include_name = 1)] is trying to force \the [key_name_admin(rig.wearer, include_name = 1)] to use a hardsuit module.")
|
||||
else
|
||||
return 0
|
||||
rig.selected_module.engage(A, alert_ai)
|
||||
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
#undef MIDDLE_CLICK
|
||||
|
||||
@@ -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])"
|
||||
return ..()+"(MCH:[machines.len] PWR:[powernets.len] PIP:[pipe_networks.len])"
|
||||
|
||||
@@ -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])"
|
||||
@@ -97,11 +97,16 @@ On the map:
|
||||
1455 for AI access
|
||||
*/
|
||||
|
||||
var/const/BOT_FREQ = 1447
|
||||
var/const/RADIO_LOW_FREQ = 1200
|
||||
var/const/PUBLIC_LOW_FREQ = 1441
|
||||
var/const/PUBLIC_HIGH_FREQ = 1489
|
||||
var/const/RADIO_HIGH_FREQ = 1600
|
||||
|
||||
var/const/BOT_FREQ = 1447
|
||||
var/const/COMM_FREQ = 1353
|
||||
var/const/ERT_FREQ = 1345
|
||||
var/const/AI_FREQ = 1343
|
||||
var/const/DTH_FREQ = 1341
|
||||
var/const/ERT_FREQ = 1345
|
||||
var/const/AI_FREQ = 1343
|
||||
var/const/DTH_FREQ = 1341
|
||||
var/const/SYND_FREQ = 1213
|
||||
|
||||
// department channels
|
||||
@@ -113,6 +118,10 @@ var/const/SCI_FREQ = 1351
|
||||
var/const/SRV_FREQ = 1349
|
||||
var/const/SUP_FREQ = 1347
|
||||
|
||||
// internal department channels
|
||||
var/const/MED_I_FREQ = 1485
|
||||
var/const/SEC_I_FREQ = 1475
|
||||
|
||||
var/list/radiochannels = list(
|
||||
"Common" = PUB_FREQ,
|
||||
"Science" = SCI_FREQ,
|
||||
@@ -125,7 +134,9 @@ var/list/radiochannels = list(
|
||||
"Mercenary" = SYND_FREQ,
|
||||
"Supply" = SUP_FREQ,
|
||||
"Service" = SRV_FREQ,
|
||||
"AI Private" = AI_FREQ
|
||||
"AI Private" = AI_FREQ,
|
||||
"Medical(I)" = MED_I_FREQ,
|
||||
"Security(I)" = SEC_I_FREQ
|
||||
)
|
||||
|
||||
// central command channels, i.e deathsquid & response teams
|
||||
@@ -134,8 +145,8 @@ var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ)
|
||||
// Antag channels, i.e. Syndicate
|
||||
var/list/ANTAG_FREQS = list(SYND_FREQ)
|
||||
|
||||
//depenging helpers
|
||||
var/list/DEPT_FREQS = list(SCI_FREQ, MED_FREQ, ENG_FREQ, SEC_FREQ, SUP_FREQ, SRV_FREQ, ERT_FREQ, SYND_FREQ, DTH_FREQ)
|
||||
//Department channels, arranged lexically
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
|
||||
|
||||
#define TRANSMISSION_WIRE 0
|
||||
#define TRANSMISSION_RADIO 1
|
||||
@@ -145,29 +156,28 @@ var/list/DEPT_FREQS = list(SCI_FREQ, MED_FREQ, ENG_FREQ, SEC_FREQ, SUP_FREQ, SRV
|
||||
if (frequency in ANTAG_FREQS)
|
||||
return "syndradio"
|
||||
// centcomm channels (deathsquid and ert)
|
||||
else if(frequency in CENT_FREQS)
|
||||
if(frequency in CENT_FREQS)
|
||||
return "centradio"
|
||||
// command channel
|
||||
else if(frequency == COMM_FREQ)
|
||||
if(frequency == COMM_FREQ)
|
||||
return "comradio"
|
||||
// AI private channel
|
||||
else if(frequency == AI_FREQ)
|
||||
if(frequency == AI_FREQ)
|
||||
return "airadio"
|
||||
// department radio formatting (poorly optimized, ugh)
|
||||
else if(frequency == SEC_FREQ)
|
||||
if(frequency == SEC_FREQ)
|
||||
return "secradio"
|
||||
else if (frequency == ENG_FREQ)
|
||||
if (frequency == ENG_FREQ)
|
||||
return "engradio"
|
||||
else if(frequency == SCI_FREQ)
|
||||
if(frequency == SCI_FREQ)
|
||||
return "sciradio"
|
||||
else if(frequency == MED_FREQ)
|
||||
if(frequency == MED_FREQ)
|
||||
return "medradio"
|
||||
else if(frequency == SUP_FREQ) // cargo
|
||||
if(frequency == SUP_FREQ) // cargo
|
||||
return "supradio"
|
||||
else if(frequency == SRV_FREQ) // service
|
||||
if(frequency == SRV_FREQ) // service
|
||||
return "srvradio"
|
||||
// If all else fails and it's a dept_freq, color me purple!
|
||||
else if(frequency in DEPT_FREQS)
|
||||
if(frequency in DEPT_FREQS)
|
||||
return "deptradio"
|
||||
|
||||
return "radio"
|
||||
|
||||
@@ -74,9 +74,6 @@ var/list/gamemode_cache = list()
|
||||
var/automute_on = 0 //enables automuting/spam prevention
|
||||
var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
|
||||
|
||||
var/rp_rev = 0 // Changes between conversion methods in rev.
|
||||
var/announce_revheads = 0 // Determines if revheads are announced in revolution mode.
|
||||
|
||||
var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds...
|
||||
var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active.
|
||||
|
||||
@@ -216,6 +213,8 @@ var/list/gamemode_cache = list()
|
||||
|
||||
var/aggressive_changelog = 0
|
||||
|
||||
var/list/language_prefixes = list(",","#","-")//Default language prefixes
|
||||
|
||||
/datum/configuration/New()
|
||||
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
|
||||
for (var/T in L)
|
||||
@@ -648,12 +647,6 @@ var/list/gamemode_cache = list()
|
||||
if("disable_welder_vision")
|
||||
config.welder_vision = 0
|
||||
|
||||
if("rp_rev")
|
||||
config.rp_rev = 1
|
||||
|
||||
if("announce_revheads")
|
||||
config.announce_revheads = 1
|
||||
|
||||
if("allow_extra_antags")
|
||||
config.allow_extra_antags = 1
|
||||
|
||||
@@ -696,6 +689,11 @@ var/list/gamemode_cache = list()
|
||||
if("aggressive_changelog")
|
||||
config.aggressive_changelog = 1
|
||||
|
||||
if("default_language_prefixes")
|
||||
var/list/values = text2list(value, " ")
|
||||
if(values.len > 0)
|
||||
language_prefixes = values
|
||||
|
||||
else
|
||||
log_misc("Unknown setting in configuration: '[name]'")
|
||||
|
||||
@@ -853,21 +851,15 @@ var/list/gamemode_cache = list()
|
||||
for (var/game_mode in gamemode_cache)
|
||||
var/datum/game_mode/M = gamemode_cache[game_mode]
|
||||
if (M.config_tag && M.config_tag == mode_name)
|
||||
M.create_antagonists()
|
||||
return M
|
||||
return gamemode_cache["extended"]
|
||||
|
||||
/datum/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
for (var/game_mode in gamemode_cache)
|
||||
var/list/runnable_modes = list()
|
||||
for(var/game_mode in gamemode_cache)
|
||||
var/datum/game_mode/M = gamemode_cache[game_mode]
|
||||
if (!(M.config_tag in modes))
|
||||
continue
|
||||
if (probabilities[M.config_tag]<=0)
|
||||
continue
|
||||
if (M.can_start())
|
||||
runnable_modes[M] = probabilities[M.config_tag]
|
||||
//world << "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]"
|
||||
if(M && M.can_start() && !isnull(config.probabilities[M.config_tag]) && config.probabilities[M.config_tag] > 0)
|
||||
runnable_modes |= M
|
||||
return runnable_modes
|
||||
|
||||
/datum/configuration/proc/post_load()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/list/eng = new()
|
||||
var/list/med = new()
|
||||
var/list/sci = new()
|
||||
var/list/car = new()
|
||||
var/list/civ = new()
|
||||
var/list/bot = new()
|
||||
var/list/misc = new()
|
||||
@@ -67,6 +68,9 @@
|
||||
if(real_rank in science_positions)
|
||||
sci[name] = rank
|
||||
department = 1
|
||||
if(real_rank in cargo_positions)
|
||||
car[name] = rank
|
||||
department = 1
|
||||
if(real_rank in civilian_positions)
|
||||
civ[name] = rank
|
||||
department = 1
|
||||
@@ -100,6 +104,11 @@
|
||||
for(name in sci)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(car.len > 0)
|
||||
dat += "<tr><th colspan=3>Cargo</th></tr>"
|
||||
for(name in car)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[car[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(civ.len > 0)
|
||||
dat += "<tr><th colspan=3>Civilian</th></tr>"
|
||||
for(name in civ)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -72,6 +72,7 @@ var/global/ManifestJSON
|
||||
var/eng[0]
|
||||
var/med[0]
|
||||
var/sci[0]
|
||||
var/car[0]
|
||||
var/civ[0]
|
||||
var/bot[0]
|
||||
var/misc[0]
|
||||
@@ -113,6 +114,12 @@ var/global/ManifestJSON
|
||||
department = 1
|
||||
if(depthead && sci.len != 1)
|
||||
sci.Swap(1,sci.len)
|
||||
|
||||
if(real_rank in cargo_positions)
|
||||
car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive)
|
||||
department = 1
|
||||
if(depthead && car.len != 1)
|
||||
car.Swap(1,car.len)
|
||||
|
||||
if(real_rank in civilian_positions)
|
||||
civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
|
||||
@@ -134,6 +141,7 @@ var/global/ManifestJSON
|
||||
"eng" = eng,\
|
||||
"med" = med,\
|
||||
"sci" = sci,\
|
||||
"car" = car,\
|
||||
"civ" = civ,\
|
||||
"bot" = bot,\
|
||||
"misc" = misc\
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
w_class = 3.0
|
||||
origin_tech = list(TECH_MATERIAL = 1)
|
||||
var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
|
||||
sprite_sheets = list("Resomi" = 'icons/mob/species/resomi/handcuffs.dmi')
|
||||
|
||||
/obj/item/weapon/caution
|
||||
desc = "Caution! Wet Floor!"
|
||||
|
||||
@@ -7,7 +7,14 @@ var/datum/antagonist/xenos/borer/borers
|
||||
mob_path = /mob/living/simple_animal/borer
|
||||
bantype = "Borer"
|
||||
welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x."
|
||||
var/list/hosts = list()
|
||||
antag_indicator = "brainworm"
|
||||
|
||||
faction_role_text = "Borer Thrall"
|
||||
faction_descriptor = "Unity"
|
||||
faction_welcome = "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head."
|
||||
|
||||
initial_spawn_req = 3
|
||||
initial_spawn_target = 5
|
||||
|
||||
/datum/antagonist/xenos/borer/New()
|
||||
..(1)
|
||||
@@ -23,32 +30,24 @@ var/datum/antagonist/xenos/borer/borers
|
||||
player.objectives += new /datum/objective/borer_reproduce()
|
||||
player.objectives += new /datum/objective/escape()
|
||||
|
||||
/datum/antagonist/xenos/borer/proc/place_in_host(var/mob/living/simple_animal/borer/borer, var/mob/living/carbon/human/host)
|
||||
borer.host = host
|
||||
borer.host_brain.name = host.name
|
||||
borer.host_brain.real_name = host.real_name
|
||||
var/obj/item/organ/external/head = host.get_organ("head")
|
||||
if(head) head.implants += borer
|
||||
|
||||
/datum/antagonist/xenos/borer/proc/get_hosts()
|
||||
var/list/possible_hosts = list()
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
var/obj/item/organ/external/head/head = H.get_organ("head")
|
||||
if(head.status & ORGAN_ROBOT)
|
||||
continue
|
||||
if(H.stat != DEAD && !H.has_brain_worms())
|
||||
possible_hosts |= H
|
||||
return possible_hosts
|
||||
|
||||
/datum/antagonist/xenos/borer/place_all_mobs()
|
||||
var/list/possible_hosts = get_hosts()
|
||||
for(var/datum/mind/player in current_antagonists)
|
||||
if(!possible_hosts.len)
|
||||
return
|
||||
var/mob/host = pick(possible_hosts)
|
||||
possible_hosts -= host
|
||||
place_in_host(player, host)
|
||||
|
||||
/datum/antagonist/xenos/borer/place_mob(var/mob/living/mob)
|
||||
var/list/possible_hosts = get_hosts()
|
||||
if(possible_hosts.len) place_in_host(mob, pick(possible_hosts))
|
||||
var/mob/living/simple_animal/borer/borer = mob
|
||||
if(istype(borer))
|
||||
var/mob/living/carbon/human/host
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.stat != DEAD && !H.has_brain_worms())
|
||||
var/obj/item/organ/external/head = H.get_organ("head")
|
||||
if(head && !(head.status & ORGAN_ROBOT))
|
||||
host = H
|
||||
break
|
||||
if(istype(host))
|
||||
var/obj/item/organ/external/head = host.get_organ("head")
|
||||
borer.host = host
|
||||
head.implants += borer
|
||||
borer.loc = head
|
||||
if(!borer.host_brain)
|
||||
borer.host_brain = new(borer)
|
||||
borer.host_brain.name = host.name
|
||||
borer.host_brain.real_name = host.real_name
|
||||
return
|
||||
..() // Place them at a vent if they can't get a host.
|
||||
|
||||
@@ -10,27 +10,21 @@ var/datum/antagonist/xenos/xenomorphs
|
||||
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
|
||||
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
|
||||
|
||||
max_antags = 5
|
||||
max_antags_round = 8
|
||||
hard_cap = 5
|
||||
hard_cap_round = 8
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
|
||||
spawn_announcement_title = "Lifesign Alert"
|
||||
spawn_announcement_sound = 'sound/AI/aliens.ogg'
|
||||
spawn_announcement_delay = 400
|
||||
spawn_announcement_delay = 5000
|
||||
|
||||
/datum/antagonist/xenos/New(var/no_reference)
|
||||
..()
|
||||
if(!no_reference)
|
||||
xenomorphs = src
|
||||
|
||||
/datum/antagonist/xenos/Topic(href, href_list)
|
||||
if (..())
|
||||
return
|
||||
if(href_list["move_to_spawn"]) place_mob(locate(href_list["move_to_spawn"]))
|
||||
|
||||
/datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player)
|
||||
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[move to vent\]</a>"
|
||||
|
||||
/datum/antagonist/xenos/attempt_random_spawn()
|
||||
if(config.aliens_allowed) ..()
|
||||
|
||||
@@ -48,12 +42,5 @@ var/datum/antagonist/xenos/xenomorphs
|
||||
player.objectives += new /datum/objective/survive()
|
||||
player.objectives += new /datum/objective/escape()
|
||||
|
||||
/datum/antagonist/xenos/place_all_mobs()
|
||||
var/list/vents = get_vents()
|
||||
for(var/datum/mind/player in current_antagonists)
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/temp_vent = pick(vents)
|
||||
vents -= temp_vent
|
||||
player.current.loc = get_turf(temp_vent)
|
||||
|
||||
/datum/antagonist/xenos/place_mob(var/mob/living/player)
|
||||
player.loc = get_turf(pick(get_vents()))
|
||||
|
||||
@@ -1,53 +1,76 @@
|
||||
/datum/antagonist
|
||||
|
||||
var/role_type = BE_TRAITOR
|
||||
var/role_text = "Traitor"
|
||||
var/role_text_plural = "Traitors"
|
||||
// Text shown when becoming this antagonist.
|
||||
var/list/restricted_jobs = list() // Jobs that cannot be this antagonist (depending on config)
|
||||
var/list/protected_jobs = list() // As above.
|
||||
|
||||
// Strings.
|
||||
var/welcome_text = "Cry havoc and let slip the dogs of war!"
|
||||
var/leader_welcome_text
|
||||
var/victory_text
|
||||
var/loss_text
|
||||
var/victory_feedback_tag
|
||||
var/loss_feedback_tag
|
||||
var/max_antags = 3
|
||||
var/max_antags_round = 5
|
||||
var/leader_welcome_text // Text shown to the leader, if any.
|
||||
var/victory_text // World output at roundend for victory.
|
||||
var/loss_text // As above for loss.
|
||||
var/victory_feedback_tag // Used by the database for end of round loss.
|
||||
var/loss_feedback_tag // Used by the database for end of round loss.
|
||||
|
||||
// Random spawn values.
|
||||
var/spawn_announcement
|
||||
var/spawn_announcement_title
|
||||
var/spawn_announcement_sound
|
||||
var/spawn_announcement_delay
|
||||
// Role data.
|
||||
var/id = "traitor" // Unique datum identifier.
|
||||
var/role_type = BE_TRAITOR // Preferences option for this role.
|
||||
var/role_text = "Traitor" // special_role text.
|
||||
var/role_text_plural = "Traitors" // As above but plural.
|
||||
|
||||
var/id = "traitor"
|
||||
var/landmark_id
|
||||
var/antag_indicator
|
||||
var/mob_path = /mob/living/carbon/human
|
||||
var/feedback_tag = "traitor_objective"
|
||||
var/bantype = "Syndicate"
|
||||
var/suspicion_chance = 50
|
||||
var/flags = 0
|
||||
var/cur_max = 0
|
||||
// Visual references.
|
||||
var/antag_indicator // icon_state for icons/mob/mob.dm visual indicator.
|
||||
var/faction_indicator // See antag_indicator, but for factionalized people only.
|
||||
var/faction_invisible // Can members of the faction identify other antagonists?
|
||||
|
||||
var/datum/mind/leader
|
||||
var/spawned_nuke
|
||||
var/nuke_spawn_loc
|
||||
// Faction data.
|
||||
var/faction_role_text // Role for sub-antags. Mandatory for faction role.
|
||||
var/faction_descriptor // Description of the cause. Mandatory for faction role.
|
||||
var/faction_verb // Verb added when becoming a member of the faction, if any.
|
||||
var/faction_welcome // Message shown to faction members.
|
||||
|
||||
var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance.
|
||||
var/list/current_antagonists = list()
|
||||
var/list/pending_antagonists = list()
|
||||
var/list/starting_locations = list()
|
||||
var/list/global_objectives = list()
|
||||
var/list/restricted_jobs = list()
|
||||
var/list/protected_jobs = list()
|
||||
var/list/candidates = list()
|
||||
// Spawn values (autotraitor and game mode)
|
||||
var/hard_cap = 3 // Autotraitor var. Won't spawn more than this many antags.
|
||||
var/hard_cap_round = 5 // As above but 'core' round antags ie. roundstart.
|
||||
var/initial_spawn_req = 1 // Gamemode using this template won't start without this # candidates.
|
||||
var/initial_spawn_target = 3 // Gamemode will attempt to spawn this many antags.
|
||||
var/announced // Has an announcement been sent?
|
||||
var/spawn_announcement // When the datum spawn proc is called, does it announce to the world? (ie. xenos)
|
||||
var/spawn_announcement_title // Report title.
|
||||
var/spawn_announcement_sound // Report sound clip.
|
||||
var/spawn_announcement_delay // Time between initial spawn and round announcement.
|
||||
|
||||
// Misc.
|
||||
var/landmark_id // Spawn point identifier.
|
||||
var/mob_path = /mob/living/carbon/human // Mobtype this antag will use if none is provided.
|
||||
var/feedback_tag = "traitor_objective" // End of round
|
||||
var/bantype = "Syndicate" // Ban to check when spawning this antag.
|
||||
var/suspicion_chance = 50 // Prob of being on the initial Command report
|
||||
var/flags = 0 // Various runtime options.
|
||||
|
||||
// Used for setting appearance.
|
||||
var/list/valid_species = list("Unathi","Tajara","Skrell","Human")
|
||||
|
||||
// Runtime vars.
|
||||
var/datum/mind/leader // Current leader, if any.
|
||||
var/cur_max = 0 // Autotraitor current effective maximum.
|
||||
var/spawned_nuke // Has a bomb been spawned?
|
||||
var/nuke_spawn_loc // If so, where should it be placed?
|
||||
var/list/current_antagonists = list() // All marked antagonists for this type.
|
||||
var/list/pending_antagonists = list() // Candidates that are awaiting finalized antag status.
|
||||
var/list/starting_locations = list() // Spawn points.
|
||||
var/list/global_objectives = list() // Universal objectives if any.
|
||||
var/list/candidates = list() // Potential candidates.
|
||||
var/list/faction_members = list() // Semi-antags (in-round revs, borer thralls)
|
||||
|
||||
// ID card stuff.
|
||||
var/default_access = list()
|
||||
var/id_type = /obj/item/weapon/card/id
|
||||
var/announced
|
||||
|
||||
|
||||
/datum/antagonist/New()
|
||||
..()
|
||||
cur_max = max_antags
|
||||
cur_max = hard_cap
|
||||
get_starting_locations()
|
||||
if(!role_text_plural)
|
||||
role_text_plural = role_text
|
||||
@@ -59,7 +82,7 @@
|
||||
|
||||
/datum/antagonist/proc/get_candidates(var/ghosts_only)
|
||||
candidates = list() // Clear.
|
||||
|
||||
|
||||
// Prune restricted status. Broke it up for readability.
|
||||
// Note that this is done before jobs are handed out.
|
||||
for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id))
|
||||
@@ -85,14 +108,21 @@
|
||||
|
||||
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
|
||||
if(!can_late_spawn())
|
||||
return
|
||||
if(!istype(player)) player = get_candidates(is_latejoin_template())
|
||||
return 0
|
||||
if(!istype(player))
|
||||
var/list/players = get_candidates(is_latejoin_template())
|
||||
if(players && players.len)
|
||||
player = pick(players)
|
||||
if(!istype(player))
|
||||
message_admins("AUTO[uppertext(ticker.mode.name)]: Failed to find a candidate for [role_text].")
|
||||
return 0
|
||||
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
|
||||
message_admins("AUTO[uppertext(ticker.mode.name)]: Selected [player] as a [role_text].")
|
||||
if(istype(player.current, /mob/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
add_antagonist(player,0,1,0,1,1)
|
||||
return
|
||||
add_antagonist(player,0,0,0,1,1)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/build_candidate_list(var/ghosts_only)
|
||||
// Get the raw list of potential players.
|
||||
@@ -111,8 +141,7 @@
|
||||
return 0
|
||||
|
||||
//Grab candidates randomly until we have enough.
|
||||
candidates = shuffle(candidates)
|
||||
while(candidates.len && pending_antagonists.len < cur_max)
|
||||
while(candidates.len && pending_antagonists.len < initial_spawn_target)
|
||||
var/datum/mind/player = pick(candidates)
|
||||
candidates -= player
|
||||
draft_antagonist(player)
|
||||
@@ -121,19 +150,26 @@
|
||||
|
||||
/datum/antagonist/proc/draft_antagonist(var/datum/mind/player)
|
||||
//Check if the player can join in this antag role, or if the player has already been given an antag role.
|
||||
if(!can_become_antag(player) || player.special_role)
|
||||
if(!can_become_antag(player))
|
||||
log_debug("[player.key] was selected for [role_text] by lottery, but is not allowed to be that role.")
|
||||
return 0
|
||||
if(player.special_role)
|
||||
log_debug("[player.key] was selected for [role_text] by lottery, but they already have a special role.")
|
||||
return 0
|
||||
if(!(flags & ANTAG_OVERRIDE_JOB) && (!player.current || istype(player.current, /mob/new_player)))
|
||||
log_debug("[player.key] was selected for [role_text] by lottery, but they have not joined the game.")
|
||||
return 0
|
||||
|
||||
pending_antagonists |= player
|
||||
|
||||
log_debug("[player.key] has been selected for [role_text] by lottery.")
|
||||
|
||||
//Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots.
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = role_text
|
||||
|
||||
|
||||
//Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill.
|
||||
player.special_role = role_text
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
//Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails.
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
/datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
|
||||
if(!istype(player))
|
||||
return 0
|
||||
if(!player.current)
|
||||
return 0
|
||||
if(player in current_antagonists)
|
||||
return 0
|
||||
if(!can_become_antag(player, ignore_role))
|
||||
return 0
|
||||
|
||||
current_antagonists |= player
|
||||
|
||||
if(!add_antagonist_mind(player, ignore_role))
|
||||
return
|
||||
|
||||
//do this again, just in case
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = role_text
|
||||
@@ -23,10 +16,37 @@
|
||||
equip(player.current)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/add_antagonist_mind(var/datum/mind/player, var/ignore_role, var/nonstandard_role_type, var/nonstandard_role_msg)
|
||||
if(!istype(player))
|
||||
return 0
|
||||
if(!player.current)
|
||||
return 0
|
||||
if(player in current_antagonists)
|
||||
return 0
|
||||
if(!can_become_antag(player, ignore_role))
|
||||
return 0
|
||||
current_antagonists |= player
|
||||
|
||||
if(faction_verb && player.current)
|
||||
player.current.verbs |= faction_verb
|
||||
|
||||
// Handle only adding a mind and not bothering with gear etc.
|
||||
if(nonstandard_role_type)
|
||||
faction_members |= player
|
||||
player.current << "<span class='danger'><font size=3>You are \a [nonstandard_role_type]!</span>"
|
||||
player.special_role = nonstandard_role_type
|
||||
if(nonstandard_role_msg)
|
||||
player.current << "<span class='notice'>[nonstandard_role_msg]</span>"
|
||||
update_icons_added(player)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
|
||||
if(player.current && faction_verb)
|
||||
player.current.verbs -= faction_verb
|
||||
if(player in current_antagonists)
|
||||
player.current << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>"
|
||||
current_antagonists -= player
|
||||
faction_members -= player
|
||||
player.special_role = null
|
||||
update_icons_removed(player)
|
||||
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
50
code/game/antagonist/antagonist_factions.dm
Normal file
50
code/game/antagonist/antagonist_factions.dm
Normal file
@@ -0,0 +1,50 @@
|
||||
/mob/living/proc/convert_to_rev(mob/M as mob in oview(src))
|
||||
set name = "Convert Bourgeoise"
|
||||
set category = "Abilities"
|
||||
if(!M.mind)
|
||||
return
|
||||
convert_to_faction(M.mind, revs)
|
||||
|
||||
/mob/living/proc/convert_to_faction(var/datum/mind/player, var/datum/antagonist/faction)
|
||||
|
||||
if(!player || !faction || !player.current)
|
||||
return
|
||||
|
||||
if(!faction.faction_verb || !faction.faction_descriptor || !faction.faction_verb)
|
||||
return
|
||||
|
||||
if(faction.is_antagonist(player))
|
||||
src << "<span class='warning'>\The [player.current] already serves the [faction.faction_descriptor].</span>"
|
||||
return
|
||||
|
||||
if(player_is_antag(player))
|
||||
src << "<span class='warning'>\The [player.current]'s loyalties seem to be elsewhere...</span>"
|
||||
return
|
||||
|
||||
if(!faction.can_become_antag(player))
|
||||
src << "<span class='warning'>\The [player.current] cannot be \a [faction.faction_role_text]!</span>"
|
||||
return
|
||||
|
||||
if(world.time < player.rev_cooldown)
|
||||
src << "<span class='danger'>You must wait five seconds between attempts.</span>"
|
||||
return
|
||||
|
||||
src << "<span class='danger'>You are attempting to convert \the [player.current]...</span>"
|
||||
log_admin("[src]([src.ckey]) attempted to convert [player.current].")
|
||||
message_admins("<span class='danger'>[src]([src.ckey]) attempted to convert [player.current].</span>")
|
||||
|
||||
player.rev_cooldown = world.time+100
|
||||
var/choice = alert(player.current,"Asked by [src]: Do you want to join the [faction.faction_descriptor]?","Join the [faction.faction_descriptor]?","No!","Yes!")
|
||||
if(choice == "Yes!" && faction.add_antagonist_mind(player, 0, faction.faction_role_text, faction.faction_welcome))
|
||||
src << "<span class='notice'>\The [player.current] joins the [faction.faction_descriptor]!</span>"
|
||||
return
|
||||
if(choice == "No!")
|
||||
player << "<span class='danger'>You reject this traitorous cause!</span>"
|
||||
src << "<span class='danger'>\The [player.current] does not support the [faction.faction_descriptor]!</span>"
|
||||
|
||||
/mob/living/proc/convert_to_loyalist(mob/M as mob in oview(src))
|
||||
set name = "Convert Recidivist"
|
||||
set category = "Abilities"
|
||||
if(!M.mind)
|
||||
return
|
||||
convert_to_faction(M.mind, loyalists)
|
||||
@@ -5,23 +5,20 @@
|
||||
if(L.name == landmark_id)
|
||||
starting_locations |= get_turf(L)
|
||||
|
||||
/datum/antagonist/proc/place_all_mobs()
|
||||
if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len)
|
||||
return
|
||||
for(var/datum/mind/player in current_antagonists)
|
||||
player.current.loc = pick(starting_locations)
|
||||
|
||||
/datum/antagonist/proc/announce_antagonist_spawn()
|
||||
|
||||
if(spawn_announcement)
|
||||
if(announced)
|
||||
return
|
||||
announced = 1
|
||||
if(spawn_announcement_delay)
|
||||
sleep(spawn_announcement_delay)
|
||||
if(spawn_announcement_sound)
|
||||
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
|
||||
else
|
||||
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
|
||||
spawn(0)
|
||||
if(spawn_announcement_delay)
|
||||
sleep(spawn_announcement_delay)
|
||||
if(spawn_announcement_sound)
|
||||
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
|
||||
else
|
||||
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
|
||||
return
|
||||
|
||||
/datum/antagonist/proc/place_mob(var/mob/living/mob)
|
||||
if(!starting_locations || !starting_locations.len)
|
||||
|
||||
@@ -19,53 +19,65 @@
|
||||
|
||||
/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/clear_indicators(var/datum/mind/recipient)
|
||||
if(!recipient.current || !recipient.current.client)
|
||||
return
|
||||
for(var/image/I in recipient.current.client.images)
|
||||
if(I.icon_state == antag_indicator || (faction_indicator && I.icon_state == faction_indicator))
|
||||
qdel(I)
|
||||
|
||||
/datum/antagonist/proc/get_indicator(var/datum/mind/recipient, var/datum/mind/other)
|
||||
if(!antag_indicator || !other.current || !recipient.current)
|
||||
return
|
||||
var/indicator = (faction_indicator && (other in faction_members)) ? faction_indicator : antag_indicator
|
||||
return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator)
|
||||
|
||||
/datum/antagonist/proc/update_all_icons()
|
||||
if(!antag_indicator)
|
||||
return
|
||||
for(var/datum/mind/antag in current_antagonists)
|
||||
if(antag.current && antag.current.client)
|
||||
for(var/image/I in antag.current.client.images)
|
||||
if(I.icon_state == antag_indicator)
|
||||
qdel(I)
|
||||
for(var/datum/mind/other_antag in current_antagonists)
|
||||
if(other_antag.current)
|
||||
antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator)
|
||||
clear_indicators(antag)
|
||||
if(faction_invisible && (antag in faction_members))
|
||||
continue
|
||||
for(var/datum/mind/other_antag in current_antagonists)
|
||||
if(antag.current && antag.current.client)
|
||||
antag.current.client.images |= get_indicator(antag, other_antag)
|
||||
|
||||
/datum/antagonist/proc/update_icons_added(var/datum/mind/player)
|
||||
if(!antag_indicator || !player.current)
|
||||
return
|
||||
spawn(0)
|
||||
|
||||
var/give_to_player = (!faction_invisible || !(player in faction_members))
|
||||
for(var/datum/mind/antag in current_antagonists)
|
||||
if(!antag.current)
|
||||
continue
|
||||
if(antag.current.client)
|
||||
antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator)
|
||||
antag.current.client.images |= get_indicator(antag, player)
|
||||
if(!give_to_player)
|
||||
continue
|
||||
if(player.current.client)
|
||||
player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator)
|
||||
player.current.client.images |= get_indicator(player, antag)
|
||||
|
||||
/datum/antagonist/proc/update_icons_removed(var/datum/mind/player)
|
||||
if(!antag_indicator || !player.current)
|
||||
return
|
||||
spawn(0)
|
||||
for(var/datum/mind/antag in current_antagonists)
|
||||
if(antag.current)
|
||||
if(antag.current.client)
|
||||
for(var/image/I in antag.current.client.images)
|
||||
if(I.icon_state == antag_indicator && I.loc == player.current)
|
||||
qdel(I)
|
||||
clear_indicators(player)
|
||||
if(player.current && player.current.client)
|
||||
for(var/image/I in player.current.client.images)
|
||||
if(I.icon_state == antag_indicator)
|
||||
qdel(I)
|
||||
for(var/datum/mind/antag in current_antagonists)
|
||||
if(antag.current && antag.current.client)
|
||||
for(var/image/I in antag.current.client.images)
|
||||
if(I.loc == player.current)
|
||||
qdel(I)
|
||||
|
||||
/datum/antagonist/proc/update_current_antag_max()
|
||||
var/main_type
|
||||
if(ticker && ticker.mode)
|
||||
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
|
||||
if(ticker.mode.antag_tags && (id in ticker.mode.antag_tags))
|
||||
main_type = 1
|
||||
cur_max = (main_type ? max_antags_round : max_antags)
|
||||
cur_max = (main_type ? hard_cap_round : hard_cap)
|
||||
if(ticker.mode.antag_scaling_coeff)
|
||||
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
|
||||
|
||||
@@ -8,6 +8,12 @@ var/datum/antagonist/deathsquad/mercenary/commandos
|
||||
welcome_text = "You are in the employ of a criminal syndicate hostile to corporate interests."
|
||||
id_type = /obj/item/weapon/card/id/centcom/ERT
|
||||
|
||||
hard_cap = 4
|
||||
hard_cap_round = 8
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
|
||||
/datum/antagonist/deathsquad/mercenary/New()
|
||||
..(1)
|
||||
commandos = src
|
||||
|
||||
@@ -8,9 +8,13 @@ var/datum/antagonist/deathsquad/deathsquad
|
||||
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
|
||||
max_antags_round = 6
|
||||
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
|
||||
|
||||
hard_cap = 4
|
||||
hard_cap_round = 8
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
var/deployed = 0
|
||||
|
||||
/datum/antagonist/deathsquad/New(var/no_reference)
|
||||
|
||||
@@ -8,13 +8,16 @@ var/datum/antagonist/ert/ert
|
||||
role_text_plural = "Emergency Responders"
|
||||
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"
|
||||
id_type = /obj/item/weapon/card/id/centcom/ERT
|
||||
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
|
||||
|
||||
hard_cap = 5
|
||||
hard_cap_round = 7
|
||||
initial_spawn_req = 5
|
||||
initial_spawn_target = 7
|
||||
|
||||
/datum/antagonist/ert/create_default(var/mob/source)
|
||||
var/mob/living/carbon/human/M = ..()
|
||||
if(istype(M)) M.age = rand(25,45)
|
||||
|
||||
@@ -5,15 +5,19 @@ var/datum/antagonist/mercenary/mercs
|
||||
role_type = BE_OPERATIVE
|
||||
role_text = "Mercenary"
|
||||
bantype = "operative"
|
||||
antag_indicator = "synd"
|
||||
role_text_plural = "Mercenaries"
|
||||
landmark_id = "Syndicate-Spawn"
|
||||
leader_welcome_text = "You are the leader of the mercenary strikeforce; hail to the chief. Use :t to speak to your underlings."
|
||||
welcome_text = "To speak on the strike team's private channel use :t."
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
|
||||
max_antags = 4
|
||||
max_antags_round = 6
|
||||
id_type = /obj/item/weapon/card/id/syndicate
|
||||
|
||||
hard_cap = 4
|
||||
hard_cap_round = 8
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
/datum/antagonist/mercenary/New()
|
||||
..()
|
||||
mercs = src
|
||||
@@ -44,14 +48,6 @@ var/datum/antagonist/mercenary/mercs
|
||||
create_radio(SYND_FREQ, player)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/mercenary/place_all_mobs()
|
||||
var/spawnpos = 1
|
||||
for(var/datum/mind/player in current_antagonists)
|
||||
player.current.loc = starting_locations[spawnpos]
|
||||
spawnpos++
|
||||
if(spawnpos > starting_locations.len)
|
||||
spawnpos = 1
|
||||
|
||||
/datum/antagonist/mercenary/create_nuke()
|
||||
..()
|
||||
// Create the radio.
|
||||
|
||||
@@ -9,8 +9,12 @@ var/datum/antagonist/ninja/ninjas
|
||||
landmark_id = "ninjastart"
|
||||
welcome_text = "<span class='info'>You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>"
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
|
||||
max_antags = 1
|
||||
max_antags_round = 1
|
||||
|
||||
initial_spawn_req = 1
|
||||
initial_spawn_target = 1
|
||||
hard_cap = 1
|
||||
hard_cap_round = 3
|
||||
|
||||
id_type = /obj/item/weapon/card/id/syndicate
|
||||
|
||||
/datum/antagonist/ninja/New()
|
||||
|
||||
@@ -6,11 +6,16 @@ var/datum/antagonist/raider/raiders
|
||||
role_text = "Raider"
|
||||
role_text_plural = "Raiders"
|
||||
bantype = "raider"
|
||||
antag_indicator = "mutineer"
|
||||
landmark_id = "voxstart"
|
||||
welcome_text = "Use :H to talk on your encrypted channel."
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
|
||||
max_antags = 6
|
||||
max_antags_round = 10
|
||||
|
||||
hard_cap = 6
|
||||
hard_cap_round = 10
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
id_type = /obj/item/weapon/card/id/syndicate
|
||||
|
||||
// Heist overrides check_victory() and doesn't need victory or loss strings/tags.
|
||||
|
||||
@@ -9,8 +9,12 @@ var/datum/antagonist/wizard/wizards
|
||||
landmark_id = "wizard"
|
||||
welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.<br>In your pockets you will find a teleport scroll. Use it as needed."
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
|
||||
max_antags = 1
|
||||
max_antags_round = 1
|
||||
|
||||
hard_cap = 1
|
||||
hard_cap_round = 3
|
||||
initial_spawn_req = 1
|
||||
initial_spawn_target = 1
|
||||
|
||||
|
||||
/datum/antagonist/wizard/New()
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
feedback_tag = "changeling_objective"
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
|
||||
welcome_text = "Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
|
||||
welcome_text = "Use say \"#g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
|
||||
/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player)
|
||||
|
||||
@@ -22,10 +22,12 @@ var/datum/antagonist/cultist/cult
|
||||
victory_feedback_tag = "win - cult win"
|
||||
loss_feedback_tag = "loss - staff stopped the cult"
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
max_antags = 200 // No upper limit.
|
||||
max_antags_round = 200
|
||||
var/allow_narsie = 1
|
||||
hard_cap = 5
|
||||
hard_cap_round = 6
|
||||
initial_spawn_req = 4
|
||||
initial_spawn_target = 6
|
||||
|
||||
var/allow_narsie = 1
|
||||
var/datum/mind/sacrifice_target
|
||||
var/list/startwords = list("blood","join","self","hell")
|
||||
var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide")
|
||||
@@ -104,9 +106,9 @@ var/datum/antagonist/cultist/cult
|
||||
player.current.visible_message("<FONT size = 3>[player.current] looks like they just reverted to their old faith!</FONT>")
|
||||
|
||||
/datum/antagonist/cultist/add_antagonist(var/datum/mind/player)
|
||||
if(!..())
|
||||
return
|
||||
player << "You catch a glimpse of the Realm of Nar-Sie, the Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of That Which Waits. Assist your new compatriots in their dark dealings. Their goals are yours, and yours are theirs. You serve the Dark One above all else. Bring It back."
|
||||
. = ..()
|
||||
if(.)
|
||||
player << "You catch a glimpse of the Realm of Nar-Sie, the Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of That Which Waits. Assist your new compatriots in their dark dealings. Their goals are yours, and yours are theirs. You serve the Dark One above all else. Bring It back."
|
||||
|
||||
/datum/antagonist/cultist/can_become_antag(var/datum/mind/player)
|
||||
if(!..())
|
||||
|
||||
@@ -6,8 +6,11 @@ var/datum/antagonist/highlander/highlanders
|
||||
welcome_text = "There can be only one."
|
||||
id = MODE_HIGHLANDER
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE //| ANTAG_RANDSPAWN | ANTAG_VOTABLE // Someday...
|
||||
max_antags = 5
|
||||
max_antags_round = 7
|
||||
|
||||
hard_cap = 5
|
||||
hard_cap_round = 7
|
||||
initial_spawn_req = 3
|
||||
initial_spawn_target = 5
|
||||
|
||||
/datum/antagonist/highlander/New()
|
||||
..()
|
||||
|
||||
46
code/game/antagonist/station/loyalist.dm
Normal file
46
code/game/antagonist/station/loyalist.dm
Normal file
@@ -0,0 +1,46 @@
|
||||
var/datum/antagonist/loyalists/loyalists
|
||||
|
||||
/datum/antagonist/loyalists
|
||||
id = MODE_LOYALIST
|
||||
role_type = BE_LOYALIST
|
||||
role_text = "Head Loyalist"
|
||||
role_text_plural = "Loyalists"
|
||||
bantype = "loyalist"
|
||||
feedback_tag = "loyalist_objective"
|
||||
antag_indicator = "loyal_head"
|
||||
welcome_text = "You belong to the Company, body and soul. Preserve its interests against the conspirators amongst the crew."
|
||||
victory_text = "The heads of staff remained at their posts! The loyalists win!"
|
||||
loss_text = "The heads of staff did not stop the revolution!"
|
||||
victory_feedback_tag = "win - rev heads killed"
|
||||
loss_feedback_tag = "loss - heads killed"
|
||||
flags = 0
|
||||
|
||||
hard_cap = 2
|
||||
hard_cap_round = 4
|
||||
initial_spawn_req = 2
|
||||
initial_spawn_target = 4
|
||||
|
||||
// Inround loyalists.
|
||||
faction_role_text = "Loyalist"
|
||||
faction_descriptor = "Company"
|
||||
faction_verb = /mob/living/proc/convert_to_loyalist
|
||||
faction_welcome = "Preserve NanoTrasen's interests against the traitorous recidivists amongst the crew. Protect the heads of staff with your life."
|
||||
faction_indicator = "loyal"
|
||||
faction_invisible = 1
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
|
||||
/datum/antagonist/loyalists/New()
|
||||
..()
|
||||
loyalists = src
|
||||
|
||||
/datum/antagonist/loyalists/create_global_objectives()
|
||||
if(!..())
|
||||
return
|
||||
global_objectives = list()
|
||||
for(var/mob/living/carbon/human/player in mob_list)
|
||||
if(!player.mind || player.stat==2 || !(player.mind.assigned_role in command_positions))
|
||||
continue
|
||||
var/datum/objective/protect/loyal_obj = new
|
||||
loyal_obj.target = player.mind
|
||||
loyal_obj.explanation_text = "Protect [player.real_name], the [player.mind.assigned_role]."
|
||||
global_objectives += loyal_obj
|
||||
@@ -6,30 +6,28 @@ var/datum/antagonist/renegade/renegades
|
||||
welcome_text = "Your own safety matters above all else, trust no one and kill anyone who gets in your way. However, armed as you are, now would be the perfect time to settle that score or grab that pair of yellow gloves you've been eyeing..."
|
||||
id = MODE_RENEGADE
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
max_antags = 5
|
||||
max_antags_round = 7
|
||||
hard_cap = 5
|
||||
hard_cap_round = 7
|
||||
|
||||
hard_cap = 8
|
||||
hard_cap_round = 12
|
||||
initial_spawn_req = 3
|
||||
initial_spawn_target = 6
|
||||
|
||||
var/list/spawn_guns = list(
|
||||
/obj/item/weapon/gun/energy/taser,
|
||||
/obj/item/weapon/gun/energy/gun,
|
||||
/obj/item/weapon/gun/energy/laser,
|
||||
/obj/item/weapon/gun/projectile,
|
||||
/obj/item/weapon/gun/projectile/revolver/detective,
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r,
|
||||
/obj/item/weapon/gun/energy/gun/nuclear,
|
||||
/obj/item/weapon/gun/projectile/deagle/camo,
|
||||
/obj/item/weapon/gun/projectile/pistol,
|
||||
/obj/item/weapon/silencer,
|
||||
/obj/item/weapon/gun/energy/lasercannon,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/automatic,
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi,
|
||||
/obj/item/weapon/gun/energy/crossbow
|
||||
//obj/item/weapon/gun/projectile/gyropistol,
|
||||
//obj/item/weapon/gun/energy/pulse_rifle,
|
||||
//obj/item/weapon/gun/projectile/revolver/mateba,
|
||||
//obj/item/weapon/gun/projectile/automatic/l6_saw,
|
||||
)
|
||||
|
||||
/datum/antagonist/renegade/New()
|
||||
|
||||
@@ -3,196 +3,46 @@ var/datum/antagonist/revolutionary/revs
|
||||
/datum/antagonist/revolutionary
|
||||
id = MODE_REVOLUTIONARY
|
||||
role_type = BE_REV
|
||||
role_text = "Revolutionary"
|
||||
role_text = "Head Revolutionary"
|
||||
role_text_plural = "Revolutionaries"
|
||||
bantype = "revolutionary"
|
||||
feedback_tag = "rev_objective"
|
||||
restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective")
|
||||
antag_indicator = "rev"
|
||||
welcome_text = "The flash in your possession will help you to persuade the crew to join your cause."
|
||||
antag_indicator = "rev_head"
|
||||
welcome_text = "Down with the capitalists! Down with the Bourgeoise!"
|
||||
victory_text = "The heads of staff were relieved of their posts! The revolutionaries win!"
|
||||
loss_text = "The heads of staff managed to stop the revolution!"
|
||||
victory_feedback_tag = "win - heads killed"
|
||||
loss_feedback_tag = "loss - rev heads killed"
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_VOTABLE
|
||||
max_antags = 200 // No upper limit.
|
||||
max_antags_round = 200
|
||||
|
||||
var/list/head_revolutionaries = list()
|
||||
hard_cap = 2
|
||||
hard_cap_round = 4
|
||||
initial_spawn_req = 2
|
||||
initial_spawn_target = 4
|
||||
|
||||
//Inround revs.
|
||||
faction_role_text = "Revolutionary"
|
||||
faction_descriptor = "Revolution"
|
||||
faction_verb = /mob/living/proc/convert_to_rev
|
||||
faction_welcome = "Help the cause overturn the ruling class. Do not harm your fellow freedom fighters."
|
||||
faction_indicator = "rev"
|
||||
faction_invisible = 1
|
||||
|
||||
restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective")
|
||||
|
||||
/datum/antagonist/revolutionary/New()
|
||||
..()
|
||||
revs = src
|
||||
|
||||
/datum/antagonist/revolutionary/is_antagonist(var/datum/mind/player)
|
||||
if(..() || (player in head_revolutionaries))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/antagonist/revolutionary/equip(mob/living/carbon/human/mob)
|
||||
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
if(!config.rp_rev)
|
||||
mob.verbs |= /mob/living/carbon/human/proc/convert_to_rev
|
||||
return
|
||||
|
||||
var/obj/item/device/flash/T = new(mob)
|
||||
|
||||
var/list/slots = list (
|
||||
"backpack" = slot_in_backpack,
|
||||
"left pocket" = slot_l_store,
|
||||
"right pocket" = slot_r_store,
|
||||
"left hand" = slot_l_hand,
|
||||
"right hand" = slot_r_hand,
|
||||
)
|
||||
mob.equip_in_one_of_slots(T, slots)
|
||||
|
||||
/*
|
||||
datum/antagonist/revolutionary/finalize(var/datum/mind/target)
|
||||
if(target)
|
||||
return ..(target)
|
||||
current_antagonists |= head_revolutionaries
|
||||
create_global_objectives()
|
||||
..()
|
||||
|
||||
/datum/antagonist/revolutionary/get_additional_check_antag_output(var/datum/admins/caller)
|
||||
return ..() //Todo
|
||||
|
||||
Rev extras:
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
|
||||
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
|
||||
var/mob/M = N.current
|
||||
if(!M)
|
||||
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
|
||||
for(var/datum/mind/N in ticker.mode.revolutionaries)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
|
||||
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
|
||||
for(var/datum/mind/N in ticker.mode.get_living_heads())
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
|
||||
var/turf/mob_loc = get_turf(M)
|
||||
dat += "<td>[mob_loc.loc]</td></tr>"
|
||||
else
|
||||
dat += "<tr><td><i>Head not found!</i></td></tr>"
|
||||
*/
|
||||
|
||||
/datum/antagonist/revolutionary/create_global_objectives()
|
||||
if(!..())
|
||||
return
|
||||
|
||||
global_objectives = list()
|
||||
|
||||
for(var/datum/mind/head_mind in get_living_heads())
|
||||
var/datum/objective/mutiny/rev_obj = new
|
||||
rev_obj.target = head_mind
|
||||
rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
|
||||
for(var/mob/living/carbon/human/player in mob_list)
|
||||
if(!player.mind || player.stat==2 || !(player.mind.assigned_role in command_positions))
|
||||
continue
|
||||
var/datum/objective/rev/rev_obj = new
|
||||
rev_obj.target = player.mind
|
||||
rev_obj.explanation_text = "Assassinate, capture or convert [player.real_name], the [player.mind.assigned_role]."
|
||||
global_objectives += rev_obj
|
||||
|
||||
/datum/antagonist/revolutionary/print_player_summary()
|
||||
|
||||
current_antagonists |= head_revolutionaries
|
||||
if(!current_antagonists.len)
|
||||
return
|
||||
|
||||
var/text = "<BR/><FONT size = 2><B>The [head_revolutionaries.len == 1 ? "Head Revolutionary was" : "Head Revolutionaries were"]:</B></FONT>"
|
||||
for(var/datum/mind/ply in head_revolutionaries)
|
||||
text += "<BR/><b>[ply.name]</b>"
|
||||
world << text
|
||||
|
||||
..()
|
||||
|
||||
var/list/heads = list()
|
||||
for(var/mob/player in mob_list)
|
||||
if(player.mind && (player.mind.assigned_role in command_positions))
|
||||
heads += player.mind
|
||||
|
||||
text = "<FONT size = 2><B>The heads of staff were:</B></FONT>"
|
||||
for(var/datum/mind/head in heads)
|
||||
text += "<br>[head.key] was [head.name] ("
|
||||
if(head.current)
|
||||
if(head.current.stat == DEAD)
|
||||
text += "died"
|
||||
else if(isNotStationLevel(head.current.z))
|
||||
text += "fled the station"
|
||||
else
|
||||
text += "survived the revolution"
|
||||
if(head.current.real_name != head.name)
|
||||
text += " as [head.current.real_name]"
|
||||
else
|
||||
text += "body destroyed"
|
||||
text += ")"
|
||||
world << text
|
||||
|
||||
// This is a total redefine because headrevs are greeted differently to subrevs.
|
||||
/datum/antagonist/revolutionary/add_antagonist(var/datum/mind/player, var/ignore_role)
|
||||
if((player in current_antagonists) || (player in head_revolutionaries))
|
||||
return 0
|
||||
if(!can_become_antag(player, ignore_role))
|
||||
return 0
|
||||
current_antagonists |= player
|
||||
player.current << "<span class='danger'><font size=3>You are a Revolutionary!</font></span>"
|
||||
player.current << "<span class='danger'>Help the cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them overturn the ruling class!</span>"
|
||||
player.special_role = "Revolutionary"
|
||||
create_objectives(player)
|
||||
show_objectives(player)
|
||||
update_icons_added(player)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/revolutionary/remove_antagonist(datum/mind/player, var/show_message, var/implanted)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(player in head_revolutionaries)
|
||||
return
|
||||
|
||||
if(istype(player.current, /mob/living/carbon/brain))
|
||||
player.current << "<span class='danger'>The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now.</span>"
|
||||
if(show_message)
|
||||
player.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.")
|
||||
else
|
||||
if(implanted)
|
||||
player.current << "<span class='danger'>The nanobots in the loyalty implant remove all thoughts about being a revolutionary. Get back to work!</span>"
|
||||
else
|
||||
player.current << "<span class='danger'>You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</span>"
|
||||
if(show_message)
|
||||
player.current.visible_message("[player.current] looks like they just remembered their real allegiance!")
|
||||
|
||||
// Used by RP-rev.
|
||||
/mob/living/carbon/human/proc/convert_to_rev(mob/M as mob in oview(src))
|
||||
set name = "Convert Bourgeoise"
|
||||
set category = "Abilities"
|
||||
|
||||
if(revs.is_antagonist(M.mind))
|
||||
src << "<span class='danger'>\The [M] already serves the revolution.</span>"
|
||||
return
|
||||
if(!revs.can_become_antag(M.mind))
|
||||
src << "<span class='danger'>\The [M] cannot be a revolutionary!</span>"
|
||||
|
||||
if(world.time < M.mind.rev_cooldown)
|
||||
src << "<span class='danger'>You must wait five seconds between attempts.</span>"
|
||||
return
|
||||
|
||||
src << "<span class='danger'>You are attempting to convert \the [M]...</span>"
|
||||
log_admin("[src]([src.ckey]) attempted to convert [M].")
|
||||
message_admins("<span class='danger'>[src]([src.ckey]) attempted to convert [M].</span>")
|
||||
|
||||
var/choice = alert(M,"Asked by [src]: Do you want to join the revolution?","Join the revolution?","No!","Yes!")
|
||||
if(choice == "Yes!")
|
||||
M << "<span class='notice'>You join the revolution!</span>"
|
||||
src << "<span class='notice'>[M] joins the revolution!</span>"
|
||||
revs.add_antagonist(M.mind, 0, 0, 1)
|
||||
else if(choice == "No!")
|
||||
M << "<span class='danger'>You reject this traitorous cause!</span>"
|
||||
src << "<span class='danger'>\The [M] does not support the revolution!</span>"
|
||||
M.mind.rev_cooldown = world.time+50
|
||||
@@ -11,8 +11,10 @@ var/datum/antagonist/rogue_ai/malf
|
||||
victory_text = "The AI has taken control of all of the station's systems."
|
||||
loss_text = "The AI has been shut down!"
|
||||
flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
|
||||
max_antags = 1
|
||||
max_antags_round = 1
|
||||
hard_cap = 1
|
||||
hard_cap_round = 1
|
||||
initial_spawn_req = 1
|
||||
initial_spawn_target = 1
|
||||
|
||||
|
||||
/datum/antagonist/rogue_ai/New()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
var/datum/antagonist/traitor/traitors
|
||||
|
||||
// Inherits most of its vars from the base datum.
|
||||
/datum/antagonist/traitor
|
||||
id = MODE_TRAITOR
|
||||
restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")//AI", Currently out of the list as malf does not work for shit
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
max_antags = 200 // No upper limit.
|
||||
max_antags_round = 200
|
||||
|
||||
/datum/antagonist/traitor/New()
|
||||
..()
|
||||
@@ -139,9 +137,9 @@ var/datum/antagonist/traitor/traitors
|
||||
if(istype(R,/obj/item/device/radio))
|
||||
// generate list of radio freqs
|
||||
var/obj/item/device/radio/target_radio = R
|
||||
var/freq = 1441
|
||||
var/freq = PUBLIC_LOW_FREQ
|
||||
var/list/freqlist = list()
|
||||
while (freq <= 1489)
|
||||
while (freq <= PUBLIC_HIGH_FREQ)
|
||||
if (freq < 1451 || freq > PUB_FREQ)
|
||||
freqlist += freq
|
||||
freq += 2
|
||||
|
||||
@@ -98,6 +98,7 @@ var/list/ghostteleportlocs = list()
|
||||
icon_state = "space"
|
||||
requires_power = 1
|
||||
always_unpowered = 1
|
||||
lighting_use_dynamic = 1
|
||||
power_light = 0
|
||||
power_equip = 0
|
||||
power_environ = 0
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
power_equip = 0
|
||||
power_environ = 0
|
||||
|
||||
if(lighting_use_dynamic)
|
||||
luminosity = 0
|
||||
else
|
||||
luminosity = 1
|
||||
|
||||
..()
|
||||
|
||||
/area/proc/initialize()
|
||||
@@ -266,8 +271,8 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
|
||||
for(var/mob/M in A)
|
||||
if(has_gravity)
|
||||
thunk(M)
|
||||
M.update_floating( M.Check_Dense_Object() )
|
||||
thunk(M)
|
||||
M.update_floating( M.Check_Dense_Object() )
|
||||
|
||||
/area/proc/thunk(mob)
|
||||
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
for(var/antag_id in all_antag_types)
|
||||
if(i > grab_antags)
|
||||
break
|
||||
additional_antag_types |= antag_id
|
||||
antag_tags |= antag_id
|
||||
i++
|
||||
..()
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/datum/game_mode/changeling
|
||||
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. \
|
||||
@@ -17,3 +16,4 @@
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
antag_scaling_coeff = 10
|
||||
antag_tags = list(MODE_CHANGELING)
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
required_players_secret = 15
|
||||
required_enemies = 3
|
||||
end_on_antag_death = 0
|
||||
antag_tag = MODE_CULTIST
|
||||
antag_tags = list(MODE_CULTIST)
|
||||
|
||||
@@ -1,25 +1,5 @@
|
||||
var/global/antag_add_failed // Used in antag type voting.
|
||||
var/global/list/additional_antag_types = list()
|
||||
///////////////////////////////////
|
||||
//Keeps track of all living heads//
|
||||
///////////////////////////////////
|
||||
/proc/get_living_heads()
|
||||
var/list/heads = list()
|
||||
for(var/mob/living/carbon/human/player in mob_list)
|
||||
if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions))
|
||||
heads += player.mind
|
||||
return heads
|
||||
|
||||
/*
|
||||
* GAMEMODES (by Rastaf0)
|
||||
*
|
||||
* In the new mode system all special roles are fully supported.
|
||||
* You can have proper wizards/traitors/changelings/cultists during any mode.
|
||||
* Only two things really depends on gamemode:
|
||||
* 1. Starting roles, equipment and preparations
|
||||
* 2. Conditions of finishing the round.
|
||||
*
|
||||
*/
|
||||
|
||||
/datum/game_mode
|
||||
var/name = "invalid"
|
||||
@@ -40,11 +20,12 @@ var/global/list/additional_antag_types = list()
|
||||
var/shuttle_delay = 1 // Shuttle transit time is multiplied by this.
|
||||
var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled?
|
||||
|
||||
var/antag_tag // First (main) antag template to spawn.
|
||||
var/list/antag_tags = list() // Core antag templates to spawn.
|
||||
var/list/antag_templates // Extra antagonist types to include.
|
||||
var/list/latejoin_templates = list()
|
||||
var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
|
||||
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
|
||||
var/require_all_templates = 0 // Will only start if all templates are checked and can spawn.
|
||||
|
||||
var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm.
|
||||
var/explosion_in_progress = 0 // Sit back and relax
|
||||
@@ -54,6 +35,13 @@ var/global/list/additional_antag_types = list()
|
||||
var/event_delay_mod_moderate // Modifies the timing of random events.
|
||||
var/event_delay_mod_major // As above.
|
||||
|
||||
/datum/game_mode/New()
|
||||
..()
|
||||
// Enforce some formatting.
|
||||
// This will probably break something.
|
||||
name = capitalize(lowertext(name))
|
||||
config_tag = lowertext(config_tag)
|
||||
|
||||
/datum/game_mode/Topic(href, href_list[])
|
||||
if(..())
|
||||
return
|
||||
@@ -79,18 +67,18 @@ var/global/list/additional_antag_types = list()
|
||||
shuttle_delay = choice
|
||||
if("antag_scaling")
|
||||
choice = input("Enter a new antagonist cap scaling coefficient.") as num
|
||||
if(!choice || choice < 0 || choice > 100)
|
||||
if(isnull(choice) || choice < 0 || choice > 100)
|
||||
return
|
||||
antag_scaling_coeff = choice
|
||||
if("event_modifier_moderate")
|
||||
choice = input("Enter a new moderate event time modifier.") as num
|
||||
if(!choice || choice < 0 || choice > 100)
|
||||
if(isnull(choice) || choice < 0 || choice > 100)
|
||||
return
|
||||
event_delay_mod_moderate = choice
|
||||
refresh_event_modifiers()
|
||||
if("event_modifier_severe")
|
||||
choice = input("Enter a new moderate event time modifier.") as num
|
||||
if(!choice || choice < 0 || choice > 100)
|
||||
if(isnull(choice) || choice < 0 || choice > 100)
|
||||
return
|
||||
event_delay_mod_major = choice
|
||||
refresh_event_modifiers()
|
||||
@@ -104,7 +92,7 @@ var/global/list/additional_antag_types = list()
|
||||
usr.client.debug_variables(antag)
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
|
||||
else if(href_list["remove_antag_type"])
|
||||
if(antag_tag && href_list["remove_antag_type"] == antag_tag)
|
||||
if(antag_tags && (href_list["remove_antag_type"] in antag_tags))
|
||||
usr << "Cannot remove core mode antag type."
|
||||
return
|
||||
var/datum/antagonist/antag = all_antag_types[href_list["remove_antag_type"]]
|
||||
@@ -118,14 +106,15 @@ var/global/list/additional_antag_types = list()
|
||||
return
|
||||
var/datum/antagonist/antag = all_antag_types[choice]
|
||||
if(antag)
|
||||
additional_antag_types |= antag
|
||||
ticker.mode.antag_templates |= antag
|
||||
message_admins("Admin [key_name_admin(usr)] added [antag.role_text] template to game mode.")
|
||||
|
||||
// I am very sure there's a better way to do this, but I'm not sure what it might be. ~Z
|
||||
for(var/datum/admins/admin in world)
|
||||
if(usr.client == admin.owner)
|
||||
admin.show_game_mode(usr)
|
||||
return
|
||||
spawn(1)
|
||||
for(var/datum/admins/admin in world)
|
||||
if(usr.client == admin.owner)
|
||||
admin.show_game_mode(usr)
|
||||
return
|
||||
|
||||
/datum/game_mode/proc/announce() //to be called when round starts
|
||||
world << "<B>The current game mode is [capitalize(name)]!</B>"
|
||||
@@ -166,15 +155,23 @@ var/global/list/additional_antag_types = list()
|
||||
if(!(antag_templates && antag_templates.len))
|
||||
return 1
|
||||
|
||||
var/datum/antagonist/main_antags = antag_templates[1]
|
||||
var/list/potential
|
||||
if(main_antags.flags & ANTAG_OVERRIDE_JOB)
|
||||
potential = main_antags.pending_antagonists
|
||||
else
|
||||
potential = main_antags.candidates
|
||||
|
||||
if(potential.len >= required_enemies)
|
||||
return 1
|
||||
var/enemy_count = 0
|
||||
if(antag_tags && antag_tags.len)
|
||||
for(var/antag_tag in antag_tags)
|
||||
var/datum/antagonist/antag = all_antag_types[antag_tag]
|
||||
if(!antag)
|
||||
continue
|
||||
var/list/potential = list()
|
||||
if(antag.flags & ANTAG_OVERRIDE_JOB)
|
||||
potential = antag.pending_antagonists
|
||||
else
|
||||
potential = antag.candidates
|
||||
if(islist(potential))
|
||||
if(require_all_templates && potential.len < antag.initial_spawn_req)
|
||||
return 0
|
||||
enemy_count += potential.len
|
||||
if(enemy_count >= required_enemies)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/refresh_event_modifiers()
|
||||
@@ -471,11 +468,13 @@ var/global/list/additional_antag_types = list()
|
||||
if(!config.traitor_scaling)
|
||||
antag_scaling_coeff = 0
|
||||
|
||||
if(antag_tag)
|
||||
if(antag_tags && antag_tags.len)
|
||||
antag_templates = list()
|
||||
var/datum/antagonist/antag = all_antag_types[antag_tag]
|
||||
if(antag)
|
||||
antag_templates |= antag
|
||||
for(var/antag_tag in antag_tags)
|
||||
var/datum/antagonist/antag = all_antag_types[antag_tag]
|
||||
if(antag)
|
||||
antag_templates |= antag
|
||||
|
||||
if(additional_antag_types && additional_antag_types.len)
|
||||
if(!antag_templates)
|
||||
antag_templates = list()
|
||||
@@ -484,15 +483,6 @@ var/global/list/additional_antag_types = list()
|
||||
if(antag)
|
||||
antag_templates |= antag
|
||||
|
||||
/*
|
||||
if(antag_templates && antag_templates.len)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
|
||||
continue
|
||||
antag_templates -= antag
|
||||
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
|
||||
*/
|
||||
|
||||
newscaster_announcements = pick(newscaster_standard_feeds)
|
||||
|
||||
/datum/game_mode/proc/check_victory()
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/datum/game_mode/var/next_spawn = 0
|
||||
/datum/game_mode/var/min_autotraitor_delay = 4200 // Approx 7 minutes.
|
||||
/datum/game_mode/var/max_autotraitor_delay = 12000 // Approx 20 minutes.
|
||||
|
||||
/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
|
||||
var/list/usable_templates = list()
|
||||
for(var/datum/antagonist/A in supplied_templates)
|
||||
if(A.can_late_spawn())
|
||||
message_admins("AUTO[uppertext(name)]: [A.id] selected for spawn attempt.")
|
||||
usable_templates |= A
|
||||
return usable_templates
|
||||
|
||||
@@ -21,23 +26,27 @@
|
||||
if(emergency_shuttle.departed || !round_autoantag)
|
||||
return
|
||||
|
||||
if(!prob(get_antag_prob()))
|
||||
if(world.time < next_spawn)
|
||||
return
|
||||
|
||||
message_admins("AUTO[uppertext(name)]: Attempting spawn.")
|
||||
|
||||
var/list/usable_templates
|
||||
if(latejoin_only && latejoin_templates.len)
|
||||
usable_templates = get_usable_templates(latejoin_templates)
|
||||
else if (antag_templates.len)
|
||||
else if (antag_templates && antag_templates.len)
|
||||
usable_templates = get_usable_templates(antag_templates)
|
||||
else
|
||||
message_admins("AUTO[uppertext(name)]: Failed to find configured mode spawn templates, please disable auto-antagonists until one is added.")
|
||||
round_autoantag = 0
|
||||
return
|
||||
if(usable_templates.len)
|
||||
var/datum/antagonist/spawn_antag = pick(usable_templates)
|
||||
spawn_antag.attempt_late_spawn(player)
|
||||
|
||||
/datum/game_mode/proc/get_antag_prob()
|
||||
var/player_count = 0
|
||||
for(var/mob/living/M in mob_list)
|
||||
if(M.client)
|
||||
player_count += 1
|
||||
return min(100,max(0,(player_count - 5 * 10) * 5))
|
||||
while(usable_templates.len)
|
||||
var/datum/antagonist/spawn_antag = pick(usable_templates)
|
||||
usable_templates -= spawn_antag
|
||||
if(spawn_antag.attempt_late_spawn(player))
|
||||
message_admins("AUTO[uppertext(name)]: Attempting to latespawn [spawn_antag.id]. ([spawn_antag.get_antag_count()]/[spawn_antag.cur_max])")
|
||||
next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)
|
||||
return
|
||||
message_admins("AUTO[uppertext(name)]: Failed to proc a viable spawn template.")
|
||||
next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)
|
||||
|
||||
@@ -69,33 +69,34 @@ var/global/datum/controller/gameticker/ticker
|
||||
//Create and announce mode
|
||||
if(master_mode=="secret")
|
||||
src.hide_mode = 1
|
||||
var/list/datum/game_mode/runnable_modes
|
||||
var/mode_started
|
||||
|
||||
var/list/runnable_modes = config.get_runnable_modes()
|
||||
if((master_mode=="random") || (master_mode=="secret"))
|
||||
runnable_modes = config.get_runnable_modes()
|
||||
if (runnable_modes.len==0)
|
||||
if(!runnable_modes.len)
|
||||
current_state = GAME_STATE_PREGAME
|
||||
world << "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby."
|
||||
return 0
|
||||
if(secret_force_mode != "secret")
|
||||
var/datum/game_mode/M = config.pick_mode(secret_force_mode)
|
||||
if(M.can_start())
|
||||
mode_started = 1
|
||||
src.mode = config.pick_mode(secret_force_mode)
|
||||
job_master.ResetOccupations()
|
||||
src.mode = config.pick_mode(secret_force_mode)
|
||||
if(!src.mode)
|
||||
src.mode = pickweight(runnable_modes)
|
||||
if(src.mode)
|
||||
var/mtype = src.mode.type
|
||||
src.mode = new mtype
|
||||
var/list/weighted_modes = list()
|
||||
for(var/datum/game_mode/GM in runnable_modes)
|
||||
weighted_modes[GM.config_tag] = config.probabilities[GM.config_tag]
|
||||
src.mode = gamemode_cache[pickweight(weighted_modes)]
|
||||
else
|
||||
src.mode = config.pick_mode(master_mode)
|
||||
|
||||
src.mode.pre_setup()
|
||||
if(!src.mode)
|
||||
current_state = GAME_STATE_PREGAME
|
||||
world << "<span class='danger'>Serious error in mode setup!</span> Reverting to pre-game lobby."
|
||||
return 0
|
||||
|
||||
job_master.ResetOccupations()
|
||||
src.mode.create_antagonists()
|
||||
src.mode.pre_setup()
|
||||
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
|
||||
|
||||
if(!mode_started && !src.mode.can_start())
|
||||
if(!src.mode.can_start())
|
||||
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
|
||||
current_state = GAME_STATE_PREGAME
|
||||
mode.fail_setup()
|
||||
@@ -104,12 +105,14 @@ var/global/datum/controller/gameticker/ticker
|
||||
return 0
|
||||
|
||||
if(hide_mode)
|
||||
var/list/modes = new
|
||||
for (var/datum/game_mode/M in runnable_modes)
|
||||
modes+=M.name
|
||||
modes = sortList(modes)
|
||||
world << "<B>The current game mode is - Secret!</B>"
|
||||
world << "<B>Possibilities:</B> [english_list(modes)]"
|
||||
if(runnable_modes.len)
|
||||
var/list/tmpmodes = new
|
||||
for (var/datum/game_mode/M in runnable_modes)
|
||||
tmpmodes+=M.name
|
||||
tmpmodes = sortList(tmpmodes)
|
||||
if(tmpmodes.len)
|
||||
world << "<B>Possibilities:</B> [english_list(tmpmodes)]"
|
||||
else
|
||||
src.mode.announce()
|
||||
|
||||
@@ -153,8 +156,6 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
processScheduler.start()
|
||||
|
||||
for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z
|
||||
|
||||
if(config.sql_enabled)
|
||||
statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
|
||||
|
||||
|
||||
@@ -5,14 +5,18 @@ VOX HEIST ROUNDTYPE
|
||||
var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime.
|
||||
|
||||
/datum/game_mode/heist
|
||||
antag_tag = MODE_RAIDER
|
||||
name = "heist"
|
||||
config_tag = "heist"
|
||||
required_players = 15
|
||||
required_players_secret = 25
|
||||
required_enemies = 4
|
||||
round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!"
|
||||
<<<<<<< HEAD
|
||||
end_on_antag_death = 0
|
||||
=======
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_RAIDER)
|
||||
>>>>>>> 25638218325f612b029a8c37cc802b9abbab6d92
|
||||
|
||||
/datum/game_mode/heist/check_finished()
|
||||
if(!..())
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
auto_recall_shuttle = 0
|
||||
antag_tag = MODE_MALFUNCTION
|
||||
antag_tags = list(MODE_MALFUNCTION)
|
||||
|
||||
13
code/game/gamemodes/mixed/bughunt.dm
Normal file
13
code/game/gamemodes/mixed/bughunt.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
/datum/game_mode/bughunt
|
||||
name = "Bughunt"
|
||||
round_description = "A mercenary strike force is approaching the station to eradicate a xenomorph infestation!"
|
||||
config_tag = "bughunt"
|
||||
required_players = 15
|
||||
required_players_secret = 25
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_XENOMORPH, MODE_DEATHSQUAD)
|
||||
auto_recall_shuttle = 1
|
||||
ert_disabled = 1
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
12
code/game/gamemodes/mixed/conflux.dm
Normal file
12
code/game/gamemodes/mixed/conflux.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/game_mode/conflux
|
||||
name = "conflux"
|
||||
round_description = "A space wizard and a cult have invaded the station!"
|
||||
extended_round_description = "Cultists and wizards spawn during this round."
|
||||
config_tag = "conflux"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 5
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_WIZARD, MODE_CULTIST)
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
16
code/game/gamemodes/mixed/infestation.dm
Normal file
16
code/game/gamemodes/mixed/infestation.dm
Normal file
@@ -0,0 +1,16 @@
|
||||
/datum/game_mode/infestation
|
||||
name = "infestation"
|
||||
round_description = "There's something in the walls!"
|
||||
extended_round_description = "Two alien antagonists (Xenomorphs, Cortical Borers or Changelings) may spawn during this round."
|
||||
config_tag = "infestation"
|
||||
required_players = 15
|
||||
required_enemies = 5
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_BORER, MODE_XENOMORPH, MODE_CHANGELING)
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
|
||||
/datum/game_mode/infestation/create_antagonists()
|
||||
// Two of the three.
|
||||
antag_tags -= pick(antag_tags)
|
||||
..()
|
||||
12
code/game/gamemodes/mixed/paranoia.dm
Normal file
12
code/game/gamemodes/mixed/paranoia.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/game_mode/paranoia
|
||||
name = "paranoia"
|
||||
round_description = "The AI has malfunctioned, and subversive elements infest the crew..."
|
||||
extended_round_description = "Rampant AIs, renegades and changelings spawn in this mode."
|
||||
config_tag = "paranoia"
|
||||
required_players = 2
|
||||
required_players_secret = 7
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 1
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
antag_tags = list(MODE_MALFUNCTION, MODE_RENEGADE, MODE_CHANGELING)
|
||||
11
code/game/gamemodes/mixed/traitorling.dm
Normal file
11
code/game/gamemodes/mixed/traitorling.dm
Normal file
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/traitorling
|
||||
name = "traitorling"
|
||||
round_description = "There are traitors and alien changelings on the station. Do not let the changelings succeed!"
|
||||
extended_round_description = "Traitors and changelings both spawn during this mode."
|
||||
config_tag = "traitorling"
|
||||
required_players = 10
|
||||
required_players_secret = 15
|
||||
required_enemies = 5
|
||||
end_on_antag_death = 1
|
||||
require_all_templates = 1
|
||||
antag_tags = list(MODE_CHANGELING, MODE_TRAITOR)
|
||||
12
code/game/gamemodes/mixed/uprising.dm
Normal file
12
code/game/gamemodes/mixed/uprising.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/game_mode/uprising
|
||||
name = "uprising"
|
||||
config_tag = "uprising"
|
||||
round_description = "Some crewmembers are attempting to start a revolution while a cult plots in the shadows!"
|
||||
extended_round_description = "Cultists and revolutionaries spawn in this round."
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 3
|
||||
end_on_antag_death = 1
|
||||
antag_tags = list(MODE_REVOLUTIONARY, MODE_LOYALIST, MODE_CULTIST)
|
||||
require_all_templates = 1
|
||||
votable = 0
|
||||
@@ -8,9 +8,9 @@
|
||||
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
|
||||
required_players_secret = 10
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_NINJA)
|
||||
@@ -12,10 +12,9 @@ var/list/nuke_disks = list()
|
||||
required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
antag_tag = MODE_MERCENARY
|
||||
|
||||
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
|
||||
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level
|
||||
antag_tags = list(MODE_MERCENARY)
|
||||
|
||||
//delete all nuke disks not on a station zlevel
|
||||
/datum/game_mode/nuclear/proc/check_nuke_disks()
|
||||
|
||||
@@ -64,69 +64,6 @@ datum/objective/assassinate
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
datum/objective/mutiny
|
||||
find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate [target.current.real_name], the [target.assigned_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
check_completion()
|
||||
if(target && target.current)
|
||||
if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey)
|
||||
return 1
|
||||
var/turf/T = get_turf(target.current)
|
||||
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
|
||||
return 2
|
||||
return 0
|
||||
return 1
|
||||
|
||||
datum/objective/mutiny/rp
|
||||
find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [target.assigned_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
|
||||
find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
// less violent rev objectives
|
||||
check_completion()
|
||||
var/rval = 1
|
||||
if(target && target.current)
|
||||
//assume that only carbon mobs can become rev heads for now
|
||||
if(target.current.stat == DEAD || target.current:handcuffed || !ishuman(target.current))
|
||||
return 1
|
||||
// Check if they're converted
|
||||
if(target in revs.head_revolutionaries)
|
||||
return 1
|
||||
var/turf/T = get_turf(target.current)
|
||||
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
|
||||
rval = 2
|
||||
return 0
|
||||
return rval
|
||||
|
||||
datum/objective/anti_revolution/execute
|
||||
find_target()
|
||||
..()
|
||||
@@ -933,3 +870,38 @@ datum/objective/heist/salvage
|
||||
|
||||
/datum/objective/cult/sacrifice/check_completion()
|
||||
return (target && cult && !cult.sacrificed.Find(target))
|
||||
|
||||
/datum/objective/rev/find_target()
|
||||
..()
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [target.assigned_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
|
||||
/datum/objective/rev/find_target_by_role(role, role_type=0)
|
||||
..(role, role_type)
|
||||
if(target && target.current)
|
||||
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
|
||||
else
|
||||
explanation_text = "Free Objective"
|
||||
return target
|
||||
|
||||
/datum/objective/rev/check_completion()
|
||||
var/rval = 1
|
||||
if(target && target.current)
|
||||
var/mob/living/carbon/human/H = target.current
|
||||
if(!istype(H))
|
||||
return 1
|
||||
if(H.stat == DEAD || H.restrained())
|
||||
return 1
|
||||
// Check if they're converted
|
||||
if(target in revs.current_antagonists)
|
||||
return 1
|
||||
var/turf/T = get_turf(H)
|
||||
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
|
||||
rval = 2
|
||||
return 0
|
||||
return rval
|
||||
|
||||
|
||||
@@ -2,47 +2,12 @@
|
||||
name = "Revolution"
|
||||
config_tag = "revolution"
|
||||
round_description = "Some crewmembers are attempting to start a revolution!"
|
||||
extended_round_description = "Revolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.<BR>\nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head)."
|
||||
extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders."
|
||||
required_players = 4
|
||||
required_players_secret = 15
|
||||
required_enemies = 3
|
||||
auto_recall_shuttle = 0 //NO THANKS
|
||||
end_on_antag_death = 0
|
||||
shuttle_delay = 3
|
||||
antag_tag = MODE_REVOLUTIONARY
|
||||
|
||||
/datum/game_mode/revolution/New()
|
||||
if(config && config.rp_rev)
|
||||
extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders."
|
||||
|
||||
/datum/game_mode/revolution/send_intercept()
|
||||
|
||||
..()
|
||||
|
||||
if(config.announce_revheads)
|
||||
spawn(54000)
|
||||
var/intercepttext = ""
|
||||
command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Local agitators have been determined.")
|
||||
intercepttext = "<FONT size = 3><B>Cent. Com. Update</B> Requested status information:</FONT><HR>"
|
||||
intercepttext += "We have determined several members of your staff to be political activists. They are:"
|
||||
for(var/datum/mind/revmind in revs.head_revolutionaries)
|
||||
intercepttext += "<br>[revmind.current.real_name]"
|
||||
intercepttext += "<br>Please arrest them at once."
|
||||
for (var/obj/machinery/computer/communications/comm in world)
|
||||
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
|
||||
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
|
||||
intercept.name = "Cent. Com. Status Summary"
|
||||
intercept.info = intercepttext
|
||||
comm.messagetitle.Add("Cent. Com. Status Summary")
|
||||
comm.messagetext.Add(intercepttext)
|
||||
spawn(12000)
|
||||
command_announcement.Announce("Repeating the previous message over intercoms due to urgency. The station has political agitators onboard by the names of [reveal_rev_heads()], please arrest them at once.", "Local agitators have been determined.")
|
||||
|
||||
/datum/game_mode/revolution/proc/reveal_rev_heads()
|
||||
. = ""
|
||||
for(var/i = 1, i <= revs.head_revolutionaries.len,i++)
|
||||
var/datum/mind/revmind = revs.head_revolutionaries[i]
|
||||
if(i < revs.head_revolutionaries.len)
|
||||
. += "[revmind.current.real_name],"
|
||||
else
|
||||
. += "and [revmind.current.real_name]"
|
||||
antag_tags = list(MODE_REVOLUTIONARY, MODE_LOYALIST)
|
||||
require_all_templates = 1
|
||||
|
||||
@@ -14,5 +14,11 @@
|
||||
required_players = 0
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_TRAITOR)
|
||||
antag_scaling_coeff = 10
|
||||
antag_tag = MODE_TRAITOR
|
||||
|
||||
/datum/game_mode/traitor/auto
|
||||
name = "autotraitor"
|
||||
config_tag = "autotraitor"
|
||||
round_autoantag = 1
|
||||
antag_scaling_coeff = 5
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
required_players_secret = 10
|
||||
required_enemies = 1
|
||||
end_on_antag_death = 0
|
||||
antag_tag = MODE_WIZARD
|
||||
antag_tags = list(MODE_WIZARD)
|
||||
|
||||
@@ -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))
|
||||
//AI can do whatever he wants
|
||||
return 1
|
||||
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()
|
||||
@@ -32,12 +28,15 @@
|
||||
if(!req_one_access) req_one_access = list()
|
||||
if(!L) return 0
|
||||
if(!istype(L, /list)) return 0
|
||||
for(var/req in src.req_access)
|
||||
if(!(req in L)) //doesn't have this access
|
||||
return has_access(req_access, req_one_access, L)
|
||||
|
||||
/proc/has_access(var/list/req_access, var/list/req_one_access, var/list/accesses)
|
||||
for(var/req in req_access)
|
||||
if(!(req in accesses)) //doesn't have this access
|
||||
return 0
|
||||
if(src.req_one_access.len)
|
||||
for(var/req in src.req_one_access)
|
||||
if(req in L) //has an access from the single access list
|
||||
if(req_one_access.len)
|
||||
for(var/req in req_one_access)
|
||||
if(req in accesses) //has an access from the single access list
|
||||
return 1
|
||||
return 0
|
||||
return 1
|
||||
@@ -191,18 +190,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
|
||||
|
||||
@@ -214,13 +222,12 @@ proc/get_all_job_icons() //For all existing HUD icons
|
||||
|
||||
if(I)
|
||||
var/job_icons = get_all_job_icons()
|
||||
var/centcom = get_all_centcom_jobs()
|
||||
|
||||
if(I.assignment in job_icons) //Check if the job has a hud icon
|
||||
return I.assignment
|
||||
if(I.rank in job_icons)
|
||||
return I.rank
|
||||
|
||||
var/centcom = get_all_centcom_jobs()
|
||||
if(I.assignment in centcom) //Return with the NT logo if it is a Centcom job
|
||||
return "Centcom"
|
||||
if(I.rank in centcom)
|
||||
|
||||
@@ -447,6 +447,12 @@
|
||||
/*******
|
||||
* Misc *
|
||||
*******/
|
||||
/var/const/access_synth = 199
|
||||
/datum/access/synthetic
|
||||
id = access_synth
|
||||
desc = "Synthetic"
|
||||
access_type = ACCESS_TYPE_NONE
|
||||
|
||||
/var/const/access_crate_cash = 200
|
||||
/datum/access/crate_cash
|
||||
id = access_crate_cash
|
||||
|
||||
@@ -64,9 +64,8 @@
|
||||
spawn_positions = 1
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
access = list(access_hydroponics, access_bar, access_kitchen) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
|
||||
minimal_access = list(access_hydroponics) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
|
||||
alt_titles = list("Hydroponicist")
|
||||
access = list(access_hydroponics, access_bar, access_kitchen)
|
||||
minimal_access = list(access_hydroponics) alt_titles = list("Hydroponicist")
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#ffeef0"
|
||||
economic_modifier = 7
|
||||
access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
|
||||
minimal_access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_virology)
|
||||
alt_titles = list("Surgeon","Emergency Physician","Nurse","Virologist")
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
@@ -107,6 +109,8 @@
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#ffeef0"
|
||||
economic_modifier = 5
|
||||
access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
|
||||
minimal_access = list(access_medical, access_medical_equip, access_chemistry)
|
||||
alt_titles = list("Pharmacist")
|
||||
|
||||
|
||||
@@ -136,6 +140,8 @@
|
||||
supervisors = "the chief medical officer and research director"
|
||||
selection_color = "#ffeef0"
|
||||
economic_modifier = 7
|
||||
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics, access_research)
|
||||
minimal_access = list(access_medical, access_morgue, access_genetics, access_research)
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
@@ -197,6 +203,7 @@
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#ffeef0"
|
||||
economic_modifier = 4
|
||||
access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_chemistry, access_virology, access_eva, access_maint_tunnels, access_external_airlocks, access_psychiatrist)
|
||||
minimal_access = list(access_medical, access_medical_equip, access_eva, access_maint_tunnels, access_external_airlocks)
|
||||
alt_titles = list("Emergency Medical Technician")
|
||||
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks)
|
||||
minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks)
|
||||
economic_modifier = 5
|
||||
minimal_player_age = 3
|
||||
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)
|
||||
if(!H) return 0
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_l_ear)
|
||||
@@ -105,7 +107,7 @@
|
||||
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
|
||||
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/det(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/detective(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/flame/lighter/zippo(H), slot_l_store)
|
||||
@@ -118,8 +120,8 @@
|
||||
if(H.mind.role_alt_title && H.mind.role_alt_title == "Forensic Technician")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/forensics/blue(H), slot_wear_suit)
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_trench(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/det(H), slot_head)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -134,10 +136,10 @@
|
||||
spawn_positions = 4
|
||||
supervisors = "the head of security"
|
||||
selection_color = "#ffeeee"
|
||||
alt_titles = list("Junior Officer")
|
||||
economic_modifier = 4
|
||||
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)
|
||||
alt_titles = list("Security Cadet")
|
||||
minimal_player_age = 3
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -86,6 +86,12 @@ var/list/science_positions = list(
|
||||
)
|
||||
|
||||
//BS12 EDIT
|
||||
var/list/cargo_positions = list(
|
||||
"Quartermaster",
|
||||
"Cargo Technician",
|
||||
"Shaft Miner"
|
||||
)
|
||||
|
||||
var/list/civilian_positions = list(
|
||||
"Head of Personnel",
|
||||
"Bartender",
|
||||
@@ -93,9 +99,6 @@ var/list/civilian_positions = list(
|
||||
"Chef",
|
||||
"Janitor",
|
||||
"Librarian",
|
||||
"Quartermaster",
|
||||
"Cargo Technician",
|
||||
"Shaft Miner",
|
||||
"Lawyer",
|
||||
"Chaplain",
|
||||
"Assistant"
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
/obj/machinery/cablelayer/attack_hand(mob/user as mob)
|
||||
if(!cable&&!on)
|
||||
user << "\The [src] don't work with no cable."
|
||||
user << "<span class='warning'>\The [src] doesn't have any cable loaded.</span>"
|
||||
return
|
||||
on=!on
|
||||
user.visible_message("\The [src] [!on?"dea":"a"]ctivated.", "[user] [!on?"dea":"a"]ctivated \the [src].")
|
||||
user.visible_message("\The [user] [!on?"dea":"a"]ctivates \the [src].", "You switch [src] [on? "on" : "off"]")
|
||||
return
|
||||
|
||||
/obj/machinery/cablelayer/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
@@ -31,26 +31,27 @@
|
||||
|
||||
var/result = load_cable(O)
|
||||
if(!result)
|
||||
user << "Reel is full."
|
||||
user << "<span class='warning'>\The [src]'s cable reel is full.</span>"
|
||||
else
|
||||
user << "[result] meters of cable successfully loaded."
|
||||
user << "You load [result] lengths of cable into [src]."
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/weapon/screwdriver))
|
||||
if(istype(O, /obj/item/weapon/wirecutters))
|
||||
if(cable && cable.amount)
|
||||
var/m = round(input(usr,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1)
|
||||
m = min(m, cable.amount)
|
||||
m = min(m, 30)
|
||||
if(m)
|
||||
playsound(loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
use_cable(m)
|
||||
var/obj/item/stack/cable_coil/CC = new (get_turf(src))
|
||||
CC.amount = m
|
||||
else
|
||||
usr << "There's no more cable on the reel."
|
||||
usr << "<span class='warning'>There's no more cable on the reel.</span>"
|
||||
|
||||
/obj/machinery/cablelayer/examine(mob/user)
|
||||
..()
|
||||
user << "\The [src] has [cable.amount] meter\s."
|
||||
user << "\The [src]'s cable reel has [cable.amount] length\s left."
|
||||
|
||||
/obj/machinery/cablelayer/proc/load_cable(var/obj/item/stack/cable_coil/CC)
|
||||
if(istype(CC) && CC.amount)
|
||||
@@ -70,12 +71,11 @@
|
||||
|
||||
/obj/machinery/cablelayer/proc/use_cable(amount)
|
||||
if(!cable || cable.amount<1)
|
||||
visible_message("Cable depleted, [src] deactivated.")
|
||||
visible_message("A red light flashes on \the [src].")
|
||||
return
|
||||
/* if(cable.amount < amount)
|
||||
visible_message("No enough cable to finish the task.")
|
||||
return*/
|
||||
cable.use(amount)
|
||||
if(deleted(cable))
|
||||
cable = null
|
||||
return 1
|
||||
|
||||
/obj/machinery/cablelayer/proc/reset()
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -137,8 +137,7 @@
|
||||
return
|
||||
|
||||
if(M.brainmob.mind)
|
||||
cult.remove_antagonist(M.brainmob.mind, 1)
|
||||
revs.remove_antagonist(M.brainmob.mind, 1)
|
||||
clear_antag_roles(M.brainmob.mind, 1)
|
||||
|
||||
user.drop_item()
|
||||
P.loc = src
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/obj/item/toy/blink = 2,
|
||||
/obj/item/clothing/under/syndicate/tacticool = 2,
|
||||
/obj/item/toy/sword = 2,
|
||||
/obj/item/toy/gun = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun = 2,
|
||||
/obj/item/toy/crossbow = 2,
|
||||
/obj/item/clothing/suit/syndicatefake = 2,
|
||||
/obj/item/weapon/storage/fancy/crayons = 2,
|
||||
@@ -168,8 +168,8 @@
|
||||
var/prizeselect = pickweight(prizes)
|
||||
new prizeselect(src.loc)
|
||||
|
||||
if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
|
||||
new /obj/item/toy/ammo/gun(src.loc)
|
||||
if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun
|
||||
new /obj/item/projectile/bullet/pistol/cap(src.loc)
|
||||
|
||||
else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit
|
||||
new /obj/item/clothing/head/syndicatefake(src.loc)
|
||||
|
||||
@@ -257,3 +257,7 @@
|
||||
icon_state = "syndicam"
|
||||
network = list("NUKE")
|
||||
circuit = null
|
||||
|
||||
/obj/machinery/computer/security/nuclear/New()
|
||||
..()
|
||||
req_access = list(150)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 << "<span class='warning'>There is already ID card inside.</span>"
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -278,7 +277,11 @@ What a mess.*/
|
||||
else
|
||||
P.info += "<B>General Record Lost!</B><BR>"
|
||||
P.info += "</TT>"
|
||||
P.name = "Employment Record ([active1.fields["name"]])"
|
||||
if(active1)
|
||||
P.name = "Employment Record ([active1.fields["name"]])"
|
||||
else
|
||||
P.name = "Employment Record (Unknown/Invald Entry)"
|
||||
log_debug("[usr] ([usr.ckey]) attempted to print a null employee record, this should be investigated.")
|
||||
printing = null
|
||||
//RECORD DELETE
|
||||
if ("Delete All Records")
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/obj/item/toy/blink = 2,
|
||||
/obj/item/clothing/under/syndicate/tacticool = 2,
|
||||
/obj/item/toy/sword = 2,
|
||||
/obj/item/toy/gun = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun = 2,
|
||||
/obj/item/toy/crossbow = 2,
|
||||
/obj/item/clothing/suit/syndicatefake = 2,
|
||||
/obj/item/weapon/storage/fancy/crayons = 2,
|
||||
@@ -28,8 +28,8 @@
|
||||
if(computer && !computer.stat)
|
||||
var/prizeselect = pickweight(prizes)
|
||||
new prizeselect(computer.loc)
|
||||
if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
|
||||
new /obj/item/toy/ammo/gun(computer.loc)
|
||||
if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun
|
||||
new /obj/item/projectile/bullet/pistol/cap(src.loc)
|
||||
else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit
|
||||
new /obj/item/clothing/head/syndicatefake(computer.loc)
|
||||
feedback_inc("arcade_win_normal")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -419,20 +419,10 @@
|
||||
for(var/datum/objective/O in all_objectives)
|
||||
// We don't want revs to get objectives that aren't for heads of staff. Letting
|
||||
// them win or lose based on cryo is silly so we remove the objective.
|
||||
if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind)
|
||||
if(O.target == occupant.mind)
|
||||
if(O.owner && O.owner.current)
|
||||
O.owner.current << "<span class='warning'>You get the feeling your target is no longer within your reach...</span>"
|
||||
qdel(O)
|
||||
else if(O.target && istype(O.target,/datum/mind))
|
||||
if(O.target == occupant.mind)
|
||||
if(O.owner && O.owner.current)
|
||||
O.owner.current << "<span class='warning'>You get the feeling your target is no longer within your reach. Time for Plan [pick(list("A","B","C","D","X","Y","Z"))]...</span>"
|
||||
O.target = null
|
||||
spawn(1) //This should ideally fire after the occupant is deleted.
|
||||
if(!O) return
|
||||
O.find_target()
|
||||
if(!(O.target))
|
||||
all_objectives -= O
|
||||
O.owner.objectives -= O
|
||||
qdel(O)
|
||||
|
||||
//Handle job slot/tater cleanup.
|
||||
var/job = occupant.mind.assigned_role
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
use_power(5)
|
||||
icon_state = "doorctrl1"
|
||||
desiredstate = !desiredstate
|
||||
trigger()
|
||||
trigger(user)
|
||||
spawn(15)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
health = between(health, health + repairing.amount*DOOR_REPAIR_AMOUNT, maxhealth)
|
||||
update_icon()
|
||||
qdel(repairing)
|
||||
repairing = null
|
||||
return
|
||||
|
||||
if(repairing && istype(I, /obj/item/weapon/crowbar))
|
||||
|
||||
@@ -67,25 +67,22 @@
|
||||
if (get_dist(src, O) > src.range)
|
||||
continue
|
||||
|
||||
var/flash_time = strength
|
||||
if (istype(O, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = O
|
||||
if(!H.eyecheck() <= 0)
|
||||
continue
|
||||
|
||||
if (istype(O, /mob/living/carbon/alien))//So aliens don't get flashed (they have no external eyes)/N
|
||||
continue
|
||||
|
||||
O.Weaken(strength)
|
||||
if (istype(O, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = O
|
||||
flash_time *= H.species.flash_mod
|
||||
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
if (E && (E.damage > E.min_bruised_damage && prob(E.damage + 50)))
|
||||
if(!E)
|
||||
return
|
||||
if(E.is_bruised() && prob(E.damage + 50))
|
||||
flick("e_flash", O:flash)
|
||||
E.damage += rand(1, 5)
|
||||
else
|
||||
if(!O.blinded)
|
||||
flick("flash", O:flash)
|
||||
|
||||
O.Weaken(flash_time)
|
||||
|
||||
/obj/machinery/flasher/emp_act(severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
|
||||
@@ -623,7 +623,6 @@ var/list/turret_icons
|
||||
else
|
||||
A = new projectile(loc)
|
||||
playsound(loc, shot_sound, 75, 1)
|
||||
A.original = target
|
||||
|
||||
// Lethal/emagged turrets use twice the power due to higher energy beams
|
||||
// Emagged turrets again use twice as much power due to higher firing rates
|
||||
@@ -631,19 +630,15 @@ var/list/turret_icons
|
||||
|
||||
//Turrets aim for the center of mass by default.
|
||||
//If the target is grabbing someone then the turret smartly aims for extremities
|
||||
var/def_zone
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
A.def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
def_zone = pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
else
|
||||
A.def_zone = pick("chest", "groin")
|
||||
def_zone = pick("chest", "groin")
|
||||
|
||||
//Shooting Code:
|
||||
A.current = T
|
||||
A.starting = T
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
spawn(1)
|
||||
A.process()
|
||||
A.launch(target, def_zone)
|
||||
|
||||
/datum/turret_checks
|
||||
var/enabled
|
||||
|
||||
117
code/game/machinery/supplybeacon.dm
Normal file
117
code/game/machinery/supplybeacon.dm
Normal file
@@ -0,0 +1,117 @@
|
||||
// Used to deploy the bacon.
|
||||
/obj/item/supply_beacon
|
||||
name = "inactive supply beacon"
|
||||
icon = 'icons/obj/supplybeacon.dmi'
|
||||
desc = "An inactive, hacked supply beacon stamped with the Nyx Rapid Fabrication logo. Good for one (1) ballistic supply pod shipment."
|
||||
icon_state = "beacon"
|
||||
var/deploy_path = /obj/machinery/power/supply_beacon
|
||||
var/deploy_time = 30
|
||||
|
||||
/obj/item/supply_beacon/supermatter
|
||||
name = "inactive supermatter supply beacon"
|
||||
deploy_path = /obj/machinery/power/supply_beacon/supermatter
|
||||
|
||||
/obj/item/supply_beacon/attack_self(var/mob/user)
|
||||
user.visible_message("<span class='notice'>\The [user] begins setting up \the [src].</span>")
|
||||
if(!do_after(user, deploy_time))
|
||||
return
|
||||
var/obj/S = new deploy_path(get_turf(user))
|
||||
user.visible_message("<span class='notice'>\The [user] deploys \the [S].</span>")
|
||||
user.unEquip(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/power/supply_beacon
|
||||
name = "supply beacon"
|
||||
desc = "A bulky moonshot supply beacon. Someone has been messing with the wiring."
|
||||
icon = 'icons/obj/supplybeacon.dmi'
|
||||
icon_state = "beacon"
|
||||
|
||||
anchored = 0
|
||||
density = 1
|
||||
layer = MOB_LAYER - 0.1
|
||||
stat = 0
|
||||
|
||||
var/target_drop_time
|
||||
var/drop_delay = 450
|
||||
var/expended
|
||||
var/drop_type
|
||||
|
||||
/obj/machinery/power/supply_beacon/New()
|
||||
..()
|
||||
if(!drop_type) drop_type = pick(supply_drop_random_loot_types())
|
||||
|
||||
/obj/machinery/power/supply_beacon/supermatter
|
||||
name = "supermatter supply beacon"
|
||||
drop_type = "supermatter"
|
||||
|
||||
/obj/machinery/power/supply_beacon/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(!use_power && istype(W, /obj/item/weapon/wrench))
|
||||
if(!anchored && !connect_to_network())
|
||||
user << "<span class='warning'>This device must be placed over an exposed cable.</span>"
|
||||
return
|
||||
anchored = !anchored
|
||||
user.visible_message("<span class='notice'>\The [user] [anchored ? "secures" : "unsecures"] \the [src].</span>")
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/supply_beacon/attack_hand(var/mob/user)
|
||||
|
||||
if(expended)
|
||||
use_power = 0
|
||||
user << "<span class='warning'>\The [src] has used up its charge.</span>"
|
||||
return
|
||||
|
||||
if(anchored)
|
||||
return use_power ? deactivate(user) : activate(user)
|
||||
else
|
||||
user << "<span class='warning'>You need to secure the beacon with a wrench first!</span>"
|
||||
return
|
||||
|
||||
/obj/machinery/power/supply_beacon/attack_ai(var/mob/user)
|
||||
if(user.Adjacent(src))
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/power/supply_beacon/proc/activate(var/mob/user)
|
||||
if(expended)
|
||||
return
|
||||
if(surplus() < 500)
|
||||
if(user) user << "<span class='notice'>The connected wire doesn't have enough current.</span>"
|
||||
return
|
||||
set_light(3, 3, "#00CCAA")
|
||||
icon_state = "beacon_active"
|
||||
use_power = 1
|
||||
if(user) user << "<span class='notice'>You activate the beacon. The supply drop will be dispatched soon.</span>"
|
||||
|
||||
/obj/machinery/power/supply_beacon/proc/deactivate(var/mob/user, var/permanent)
|
||||
if(permanent)
|
||||
expended = 1
|
||||
icon_state = "beacon_depleted"
|
||||
else
|
||||
icon_state = "beacon"
|
||||
set_light(0)
|
||||
use_power = 0
|
||||
target_drop_time = null
|
||||
if(user) user << "<span class='notice'>You deactivate the beacon.</span>"
|
||||
|
||||
/obj/machinery/power/supply_beacon/Destroy()
|
||||
if(use_power)
|
||||
deactivate()
|
||||
..()
|
||||
|
||||
/obj/machinery/power/supply_beacon/process()
|
||||
if(!use_power || expended)
|
||||
return PROCESS_KILL
|
||||
if(draw_power(500) < 500)
|
||||
deactivate()
|
||||
return
|
||||
if(!target_drop_time)
|
||||
target_drop_time = world.time + drop_delay
|
||||
else if(world.time >= target_drop_time)
|
||||
deactivate(permanent = 1)
|
||||
var/drop_x = src.x-2
|
||||
var/drop_y = src.y-2
|
||||
var/drop_z = src.z
|
||||
command_announcement.Announce("Nyx Rapid Fabrication priority supply request #[rand(1000,9999)]-[rand(100,999)] recieved. Shipment dispatched via ballistic supply pod for immediate delivery. Have a nice day.", "Thank You For Your Patronage")
|
||||
spawn(rand(100,300))
|
||||
new /datum/random_map/droppod/supply(null, drop_x, drop_y, drop_z, supplied_drop = drop_type) // Splat.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user