Lay groundwork for megafauna, and add Ashdragon.
Includes a refactor for gun turrets (merged into portable turrets), hostile simple_animal behaviour, spells (sounds have been added) and poi_list items.
@@ -4,7 +4,7 @@
|
||||
"aad" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_n"; name = "north of station"; width = 18},/turf/space,/area/space)
|
||||
"aae" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/abandoned)
|
||||
"aaf" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate)
|
||||
"aag" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate)
|
||||
"aag" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate)
|
||||
"aah" = (/obj/effect/landmark{name = "carpspawn"},/turf/space,/area/space)
|
||||
"aai" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_mid"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate)
|
||||
"aaj" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate)
|
||||
@@ -33,7 +33,7 @@
|
||||
"aaG" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
|
||||
"aaH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
|
||||
"aaI" = (/obj/machinery/biogenerator,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
|
||||
"aaJ" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate)
|
||||
"aaJ" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate)
|
||||
"aaK" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/permabrig)
|
||||
"aaL" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/camera{c_tag = "Prison Garden"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
|
||||
"aaM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig)
|
||||
@@ -8516,7 +8516,7 @@
|
||||
"dhN" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate)
|
||||
"dhO" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate)
|
||||
"dhP" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate)
|
||||
"dhQ" = (/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate)
|
||||
"dhQ" = (/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate)
|
||||
"dhR" = (/obj/structure/closet/syndicate/suits,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate)
|
||||
"dhS" = (/obj/effect/landmark{name = "Syndicate-Uplink"; tag = ""},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate)
|
||||
"dhT" = (/obj/structure/table,/obj/item/device/aicard,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate)
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
"it" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_mothership)
|
||||
"iu" = (/obj/effect/decal/warning_stripes/southeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership)
|
||||
"iv" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/assault_pod)
|
||||
"iw" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"iw" = (/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"ix" = (/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/wizard_station)
|
||||
"iy" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/wizard_station)
|
||||
"iz" = (/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/wizard_station)
|
||||
@@ -447,7 +447,7 @@
|
||||
"iE" = (/turf/space,/turf/unsimulated/wall{dir = 1; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/space)
|
||||
"iF" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/turf/simulated/floor/plating,/area/shuttle/assault_pod)
|
||||
"iG" = (/obj/effect/decal/warning_stripes/southwest,/turf/simulated/floor/plating/airless,/area/syndicate_mothership)
|
||||
"iH" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"iH" = (/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"iI" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plating/airless,/area/syndicate_mothership)
|
||||
"iJ" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod)
|
||||
"iK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod)
|
||||
@@ -484,8 +484,8 @@
|
||||
"jp" = (/turf/simulated/floor/plasteel,/area/tdome/arena_source)
|
||||
"jq" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/tdome/arena_source)
|
||||
"jr" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/energy/sword/saber/green,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source)
|
||||
"js" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod)
|
||||
"jt" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"js" = (/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod)
|
||||
"jt" = (/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod)
|
||||
"ju" = (/obj/effect/decal/warning_stripes/northeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership)
|
||||
"jv" = (/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plating/airless,/area/syndicate_mothership)
|
||||
"jw" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/obj/docking_port/mobile/assault_pod,/turf/simulated/floor/plating,/area/shuttle/assault_pod)
|
||||
|
||||
@@ -620,7 +620,7 @@
|
||||
"lW" = (/obj/machinery/power/apc/noalarm{dir = 0; name = "Worn-out APC"; pixel_y = -24},/turf/simulated/floor/plasteel/airless,/area/derelict/teleporter)
|
||||
"lX" = (/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot)
|
||||
"lY" = (/turf/simulated/mineral,/area/syndicate_depot)
|
||||
"lZ" = (/obj/structure/lattice,/obj/machinery/gun_turret/exterior,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot)
|
||||
"lZ" = (/obj/structure/lattice,/obj/machinery/porta_turret/syndicate/exterior,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot)
|
||||
"ma" = (/turf/simulated/mineral/random,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_depot)
|
||||
"mb" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_depot)
|
||||
"mc" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; icon_state = "window5"; name = "window"; opacity = 0},/area/syndicate_depot)
|
||||
@@ -633,16 +633,16 @@
|
||||
"mj" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mk" = (/obj/structure/closet/crate{name = "foot locker"},/obj/item/ammo_box/magazine/smgm45{pixel_x = 3},/obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate{pixel_x = -3; pixel_y = -2},/obj/item/weapon/lighter/zippo/gonzofist,/obj/item/clothing/under/syndicate{pixel_x = 3; pixel_y = 3},/obj/item/clothing/suit/armor/vest/combat{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"ml" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/unsimulated/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; dir = 8; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; name = "window"; opacity = 0; tag = "icon-window5_end (WEST)"},/area/syndicate_depot)
|
||||
"mm" = (/obj/machinery/gun_turret/interior,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mm" = (/obj/machinery/porta_turret/syndicate/interior,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mn" = (/obj/item/device/radio/intercom/syndicate{pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mo" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mp" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/unsimulated/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; name = "window"; opacity = 0; tag = "icon-window5 (EAST)"},/area/syndicate_depot)
|
||||
"mq" = (/turf/simulated/mineral,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_depot)
|
||||
"mr" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_depot)
|
||||
"ms" = (/obj/machinery/gun_turret/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = -27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"ms" = (/obj/machinery/porta_turret/syndicate/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = -27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mt" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/syndicake,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mu" = (/obj/machinery/gun_turret/grenade,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mv" = (/obj/machinery/gun_turret/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mu" = (/obj/machinery/porta_turret/syndicate/grenade,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mv" = (/obj/machinery/porta_turret/syndicate/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"mw" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_depot)
|
||||
"mx" = (/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot)
|
||||
"my" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/syndicate_depot)
|
||||
|
||||
1
cfg/admin.txt
Normal file
@@ -0,0 +1 @@
|
||||
markva role=root
|
||||
@@ -47,3 +47,8 @@
|
||||
#define ANTAG_HUD_CHANGELING 15
|
||||
#define ANTAG_HUD_VAMPIRE 16
|
||||
#define ANTAG_HUD_ABDUCTOR 17 //For Fox
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
#define NOTIFY_ATTACK "attack"
|
||||
#define NOTIFY_FOLLOW "orbit"
|
||||
@@ -287,3 +287,19 @@
|
||||
#define SHELTER_DEPLOY_BAD_TURFS "bad turfs"
|
||||
#define SHELTER_DEPLOY_BAD_AREA "bad area"
|
||||
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
|
||||
|
||||
// Medal names
|
||||
#define BOSS_KILL_MEDAL "Killer"
|
||||
#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type
|
||||
|
||||
// Score names
|
||||
#define LEGION_SCORE "Legion Killed"
|
||||
#define COLOSSUS_SCORE "Colossus Killed"
|
||||
#define BUBBLEGUM_SCORE "Bubblegum Killed"
|
||||
#define DRAKE_SCORE "Drakes Killed"
|
||||
#define BIRD_SCORE "Hierophants Killed"
|
||||
#define BOSS_SCORE "Bosses Killed"
|
||||
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
|
||||
|
||||
//Timing controller
|
||||
#define GLOBAL_PROC "some_magic_bullshit"
|
||||
@@ -72,6 +72,14 @@
|
||||
return 0
|
||||
return L[A.type]
|
||||
|
||||
//returns a new list with only atoms that are in typecache L
|
||||
/proc/typecache_filter_list(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for (var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if (typecache[A.type])
|
||||
. += A
|
||||
|
||||
//Like typesof() or subtypesof(), but returns a typecache instead of a list
|
||||
/proc/typecacheof(path, ignore_root_path)
|
||||
if(ispath(path))
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
/*
|
||||
@@ -550,13 +549,19 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl
|
||||
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
var/turf/current = get_turf(source)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
var/steps = 0
|
||||
var/steps = 1
|
||||
|
||||
if(current != target_turf)
|
||||
current = get_step_towards(current, target_turf)
|
||||
while(current != target_turf)
|
||||
if(steps > length) return 0
|
||||
if(current.opacity) return 0
|
||||
for(var/atom/A in current)
|
||||
if(A.opacity) return 0
|
||||
if(steps > length)
|
||||
return 0
|
||||
if(current.opacity)
|
||||
return 0
|
||||
for(var/thing in current)
|
||||
var/atom/A = thing
|
||||
if(A.opacity)
|
||||
return 0
|
||||
current = get_step_towards(current, target_turf)
|
||||
steps++
|
||||
|
||||
@@ -1767,3 +1772,46 @@ var/global/list/g_fancy_list_of_types = null
|
||||
sleep(world.tick_lag*4)
|
||||
//you might be thinking of adding more steps to this, or making it use a loop and a counter var
|
||||
// not worth it.
|
||||
|
||||
/proc/getpois(mobs_only=0,skip_mindless=0)
|
||||
var/list/mobs = sortmobs()
|
||||
var/list/names = list()
|
||||
var/list/pois = list()
|
||||
var/list/namecounts = list()
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
if(skip_mindless && (!M.mind && !M.ckey))
|
||||
if(!isbot(M) && !istype(M, /mob/camera/))
|
||||
continue
|
||||
if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins
|
||||
continue
|
||||
var/name = M.name
|
||||
if (name in names)
|
||||
namecounts[name]++
|
||||
name = "[name] ([namecounts[name]])"
|
||||
else
|
||||
names.Add(name)
|
||||
namecounts[name] = 1
|
||||
if (M.real_name && M.real_name != M.name)
|
||||
name += " \[[M.real_name]\]"
|
||||
if (M.stat == 2)
|
||||
if(istype(M, /mob/dead/observer/))
|
||||
name += " \[ghost\]"
|
||||
else
|
||||
name += " \[dead\]"
|
||||
pois[name] = M
|
||||
|
||||
if(!mobs_only)
|
||||
for(var/atom/A in poi_list)
|
||||
if(!A || !A.loc)
|
||||
continue
|
||||
var/name = A.name
|
||||
if (names.Find(name))
|
||||
namecounts[name]++
|
||||
name = "[name] ([namecounts[name]])"
|
||||
else
|
||||
names.Add(name)
|
||||
namecounts[name] = 1
|
||||
pois[name] = A
|
||||
|
||||
return pois
|
||||
@@ -36,3 +36,8 @@ var/eventchance = 10 //% per 5 mins
|
||||
var/event = 0
|
||||
var/hadevent = 0
|
||||
var/blobevent = 0
|
||||
|
||||
//Medals hub related variables
|
||||
var/global/medal_hub = null
|
||||
var/global/medal_pass = " "
|
||||
var/global/medals_enabled = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
|
||||
@@ -19,3 +19,5 @@ var/list/restricted_camera_networks = list( //Those networks can only be accesse
|
||||
)
|
||||
|
||||
var/list/mineral_turfs = list()
|
||||
|
||||
var/list/ruin_landmarks = list()
|
||||
@@ -34,3 +34,5 @@ var/global/list/tracked_implants = list() //list of all current implants that
|
||||
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
|
||||
var/global/list/abductor_equipment = list() //list of all abductor equipment
|
||||
var/global/list/global_intercoms = list() //list of all intercomms, across all z-levels
|
||||
|
||||
var/global/list/poi_list = list() //list of points of interest for observe/follow
|
||||
@@ -51,5 +51,5 @@ var/list/datum/map_template/map_templates = list()
|
||||
|
||||
var/list/datum/map_template/ruins_templates = list()
|
||||
var/list/datum/map_template/space_ruins_templates = list()
|
||||
//var/list/datum/map_template/lava_ruins_templates = list()
|
||||
var/list/datum/map_template/lava_ruins_templates = list()
|
||||
var/list/datum/map_template/shelter_templates = list()
|
||||
@@ -334,25 +334,28 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
var/mob/dead/observer/G = usr
|
||||
G.reenter_corpse()
|
||||
|
||||
/obj/screen/alert/notify_jump
|
||||
/obj/screen/alert/notify_action
|
||||
name = "Body created"
|
||||
desc = "A body was created. You can enter it."
|
||||
icon_state = "template"
|
||||
timeout = 300
|
||||
var/atom/jump_target = null
|
||||
var/attack_not_jump = null
|
||||
var/atom/target = null
|
||||
var/action = NOTIFY_JUMP
|
||||
|
||||
/obj/screen/alert/notify_jump/Click()
|
||||
/obj/screen/alert/notify_action/Click()
|
||||
if(!usr || !usr.client) return
|
||||
if(!jump_target) return
|
||||
if(!target) return
|
||||
var/mob/dead/observer/G = usr
|
||||
if(!istype(G)) return
|
||||
if(attack_not_jump)
|
||||
jump_target.attack_ghost(G)
|
||||
else
|
||||
var/turf/T = get_turf(jump_target)
|
||||
switch(action)
|
||||
if(NOTIFY_ATTACK)
|
||||
target.attack_ghost(G)
|
||||
if(NOTIFY_JUMP)
|
||||
var/turf/T = get_turf(target)
|
||||
if(T && isturf(T))
|
||||
G.loc = T
|
||||
if(NOTIFY_FOLLOW)
|
||||
G.ManualFollow(target)
|
||||
|
||||
//OBJECT-BASED
|
||||
|
||||
|
||||
@@ -548,6 +548,12 @@
|
||||
if("round_abandon_penalty_period")
|
||||
config.round_abandon_penalty_period = MinutesToTicks(text2num(value))
|
||||
|
||||
if("medal_hub_address")
|
||||
global.medal_hub = value
|
||||
|
||||
if("medal_hub_password")
|
||||
global.medal_pass = value
|
||||
|
||||
else
|
||||
diary << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
|
||||
|
||||
/datum
|
||||
var/var_edited = 0 //Warrenty void if seal is broken
|
||||
|
||||
/datum/proc/on_varedit(modified_var) //called whenever a var is edited
|
||||
var_edited = 1
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
set category = "Debug"
|
||||
set name = "View Variables"
|
||||
|
||||
@@ -55,6 +55,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
var/action_icon_state = "spell_default"
|
||||
var/action_background_icon_state = "bg_spell"
|
||||
|
||||
var/sound = null //The sound the spell makes when it is cast
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
|
||||
if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list))
|
||||
@@ -130,6 +132,9 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
if("emote")
|
||||
user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/playMagSound()
|
||||
playsound(get_turf(usr), sound,50,1)
|
||||
|
||||
/obj/effect/proc_holder/spell/New()
|
||||
..()
|
||||
action = new(src)
|
||||
@@ -166,6 +171,10 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
spawn(0)
|
||||
if(charge_type == "recharge" && recharge)
|
||||
start_recharge()
|
||||
|
||||
if(sound)
|
||||
playMagSound()
|
||||
|
||||
if(prob(critfailchance))
|
||||
critfail(targets)
|
||||
else
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
|
||||
var/invocation_area = 1 //if the invocation appends the selected area
|
||||
|
||||
var/sound1 = "sound/weapons/ZapBang.ogg"
|
||||
var/sound2 = "sound/weapons/ZapBang.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1)
|
||||
var/thearea = before_cast(targets)
|
||||
if(!thearea || !cast_check(1))
|
||||
@@ -32,7 +36,8 @@
|
||||
|
||||
return thearea
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea)
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea,mob/living/user = usr)
|
||||
playsound(get_turf(user), sound1, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
@@ -64,7 +69,8 @@
|
||||
break
|
||||
|
||||
if(!success)
|
||||
target.loc = pick(L)
|
||||
target.forceMove(pick(L))
|
||||
playsound(get_turf(user), sound2, 50,1)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
//should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example
|
||||
var/delay = 1//Go Go Gadget Inheritance
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets)
|
||||
var/cast_sound = 'sound/items/welder.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets,mob/living/user = usr)
|
||||
playsound(get_turf(user), cast_sound, 50,1)
|
||||
for(var/turf/T in targets)
|
||||
if(T.density && !summon_ignore_density)
|
||||
targets -= T
|
||||
@@ -42,6 +44,7 @@
|
||||
for(var/varName in newVars)
|
||||
if(varName in summoned_object.vars)
|
||||
summoned_object.vars[varName] = newVars[varName]
|
||||
summoned_object.admin_spawned = TRUE
|
||||
|
||||
if(summon_lifespan)
|
||||
spawn(summon_lifespan)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
selection_type = "range"
|
||||
|
||||
action_icon_state = "barn"
|
||||
sound = "sound/magic/HorseHead_curse.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr)
|
||||
if(!targets.len)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
cooldown_min = 20 //20 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "knock"
|
||||
sound = "sound/magic/Knock.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets)
|
||||
for(var/turf/T in targets)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/ready = 0
|
||||
var/image/halo = null
|
||||
action_icon_state = "lightning"
|
||||
var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lightning/lightnian
|
||||
clothes_req = 0
|
||||
@@ -31,8 +32,10 @@
|
||||
/obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr)
|
||||
ready = 1
|
||||
to_chat(user, "<span class='notice'>You start gathering the power.</span>")
|
||||
Snd = new/sound('sound/magic/lightning_chargeup.ogg',channel = 7)
|
||||
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
|
||||
user.overlays.Add(halo)
|
||||
playsound(get_turf(user), Snd, 50, 0)
|
||||
start_time = world.time
|
||||
if(do_mob(user,user,100,uninterruptible=1))
|
||||
if(ready)
|
||||
@@ -59,11 +62,14 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
|
||||
/obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr)
|
||||
ready = 0
|
||||
var/mob/living/carbon/target = targets[1]
|
||||
Snd=sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
|
||||
playsound(get_turf(user),Snd,50,0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
|
||||
if(get_dist(user,target)>range)
|
||||
to_chat(user, "<span class='notice'>They are too far away!</span>")
|
||||
Reset(user)
|
||||
return
|
||||
|
||||
playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, 1)
|
||||
user.Beam(target,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
|
||||
|
||||
var/energy = min(world.time - start_time,100)
|
||||
@@ -75,10 +81,10 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
|
||||
var/mob/living/carbon/current = target
|
||||
if(bounces < 1)
|
||||
current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
|
||||
playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
|
||||
else
|
||||
current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
|
||||
playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
|
||||
var/list/possible_targets = new
|
||||
for(var/mob/living/M in view_or_range(range,target,"view"))
|
||||
if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
range = 0
|
||||
cast_sound = null
|
||||
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
@@ -102,8 +102,10 @@
|
||||
if(butterfingers)
|
||||
item_to_retrive.loc = user.loc
|
||||
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears!</span>")
|
||||
playsound(get_turf(user),"sound/magic/SummonItems_generic.ogg",50,1)
|
||||
else
|
||||
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears in [user]'s hand!</span>")
|
||||
playsound(get_turf(user),"sound/magic/SummonItems_generic.ogg",50,1)
|
||||
|
||||
if(message)
|
||||
to_chat(user, message)
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
var/include_space = 0 //whether it includes space tiles in possible teleport locations
|
||||
var/include_dense = 0 //whether it includes dense tiles in possible teleport locations
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets)
|
||||
var/sound1 = "sound/weapons/ZapBang.ogg"
|
||||
var/sound2 = "sound/weapons/ZapBang.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets,mob/living/user = usr)
|
||||
playsound(get_turf(user), sound1, 50,1)
|
||||
for(var/mob/living/target in targets)
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in range(target,outer_tele_radius))
|
||||
@@ -31,4 +35,5 @@
|
||||
if(!picked || !isturf(picked))
|
||||
return
|
||||
|
||||
target.loc = picked
|
||||
target.forceMove(picked)
|
||||
playsound(get_turf(user), sound2, 50,1)
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
|
||||
action_icon_state = "magicm"
|
||||
|
||||
sound = "sound/magic/MAGIC_MISSILE.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_weakened = 3
|
||||
sound = "sound/magic/MM_Hit.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/noclothes
|
||||
name = "No Clothes"
|
||||
@@ -52,6 +55,7 @@
|
||||
cooldown_min = 300 //25 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "mutate"
|
||||
sound = "sound/magic/Mutate.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate/cast(list/targets)
|
||||
for(var/mob/living/target in targets)
|
||||
@@ -94,6 +98,8 @@
|
||||
emp_heavy = 6
|
||||
emp_light = 10
|
||||
|
||||
sound = "sound/magic/Disable_Tech.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
@@ -118,6 +124,9 @@
|
||||
|
||||
action_icon_state = "blink"
|
||||
|
||||
sound1 = "sound/magic/blink.ogg"
|
||||
sound2 = "sound/magic/blink.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
@@ -136,6 +145,9 @@
|
||||
|
||||
action_icon_state = "spell_teleport"
|
||||
|
||||
sound1="sound/magic/Teleport_diss.ogg"
|
||||
sound2="sound/magic/Teleport_app.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall
|
||||
name = "Forcewall"
|
||||
desc = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
|
||||
@@ -152,6 +164,7 @@
|
||||
summon_lifespan = 300
|
||||
|
||||
action_icon_state = "shield"
|
||||
cast_sound = "sound/magic/ForceWall.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
|
||||
name = "Stop Time"
|
||||
@@ -180,6 +193,7 @@
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/carp)
|
||||
|
||||
cast_sound = "sound/magic/Summon_Karp.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
|
||||
name = "Artificer"
|
||||
@@ -195,6 +209,7 @@
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
|
||||
action_icon_state = "artificer"
|
||||
cast_sound = "sound/magic/SummonItems_generic.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
@@ -209,6 +224,7 @@
|
||||
range = 3
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/creature)
|
||||
cast_sound = "sound/magic/SummonItems_generic.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
name = "Blind"
|
||||
@@ -229,10 +245,12 @@
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound="sound/magic/Blind.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
disabilities = BLIND
|
||||
duration = 300
|
||||
sound="sound/magic/Blind.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/fireball
|
||||
name = "Fireball"
|
||||
@@ -254,6 +272,7 @@
|
||||
proj_step_delay = 1
|
||||
|
||||
action_icon_state = "fireball"
|
||||
sound = "sound/magic/Fireball.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/turf/fireball/cast(var/turf/T)
|
||||
explosion(T, -1, 0, 2, 3, 0, flame_range = 2)
|
||||
@@ -282,12 +301,14 @@
|
||||
var/maxthrow = 5
|
||||
|
||||
action_icon_state = "repulse"
|
||||
sound = 'sound/magic/Repulse.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets)
|
||||
var/mob/user = usr
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
playMagSound()
|
||||
for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
@@ -314,3 +335,24 @@
|
||||
M.Weaken(2)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by a mystical force!</span>")
|
||||
spawn(0) AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
max_targets = 0
|
||||
range = 6
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = "sound/magic/Fireball.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
U.IgniteMob()
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
var/allow_spin = 1 //Set this to 1 for a _target_ that is being thrown at; if an atom has this set to 1 then atoms thrown AT it will not spin; currently used for the singularity. -Fox
|
||||
|
||||
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
|
||||
|
||||
/atom/proc/onCentcom()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
@@ -455,3 +457,7 @@
|
||||
|
||||
/atom/proc/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
|
||||
return
|
||||
|
||||
/atom/on_varedit(modified_var)
|
||||
if(!Debug2)
|
||||
admin_spawned = TRUE
|
||||
@@ -213,6 +213,10 @@
|
||||
if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement
|
||||
src.throw_impact(A,speed)
|
||||
|
||||
/atom/movable/proc/throw_at_fast(atom/target, range, speed, thrower, no_spin)
|
||||
set waitfor = 0
|
||||
throw_at(target, range, speed, thrower, no_spin)
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, thrower, no_spin)
|
||||
if(!target || !src || (flags & NODROP))
|
||||
return 0
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring)
|
||||
blob_cores += src
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
adjustcolors(color) //so it atleast appears
|
||||
if(!overmind)
|
||||
create_overmind(new_overmind)
|
||||
@@ -41,6 +42,7 @@
|
||||
overmind.blob_core = null
|
||||
overmind = null
|
||||
processing_objects.Remove(src)
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
|
||||
@@ -73,9 +73,11 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
AI.client.images += blood
|
||||
cult_viewpoints += src
|
||||
poi_list |= src
|
||||
|
||||
/obj/effect/rune/Destroy()
|
||||
cult_viewpoints -= src
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/rune/examine(mob/user)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_state = "swarmer_unactivated"
|
||||
|
||||
/obj/item/unactivated_swarmer/New()
|
||||
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "<a href=?src=[UID()];ghostjoin=1>(Click to enter)</a>", source = src, attack_not_jump = 1)
|
||||
notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "<a href=?src=[UID()];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
..()
|
||||
|
||||
/obj/item/unactivated_swarmer/Topic(href, href_list)
|
||||
@@ -63,7 +63,7 @@
|
||||
mob_size = MOB_SIZE_TINY
|
||||
ventcrawler = 2
|
||||
ranged = 1
|
||||
ranged_cooldown_cap = 1
|
||||
ranged_cooldown_time = 20
|
||||
universal_speak = 0
|
||||
universal_understand = 0
|
||||
projectilesound = 'sound/weapons/taser2.ogg'
|
||||
|
||||
@@ -496,7 +496,7 @@
|
||||
melee_damage_upper = 10
|
||||
damage_transfer = 0.9
|
||||
projectiletype = /obj/item/projectile/guardian
|
||||
ranged_cooldown_cap = 1
|
||||
ranged_cooldown_time = 1
|
||||
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
|
||||
ranged = 1
|
||||
rapid = 1
|
||||
|
||||
@@ -307,7 +307,7 @@ proc/issyndicate(mob/living/M as mob)
|
||||
|
||||
/datum/game_mode/nuclear/declare_completion()
|
||||
var/disk_rescued = 1
|
||||
for(var/obj/item/weapon/disk/nuclear/D in world)
|
||||
for(var/obj/item/weapon/disk/nuclear/D in poi_list)
|
||||
if(!D.onCentcom())
|
||||
disk_rescued = 0
|
||||
break
|
||||
|
||||
@@ -32,10 +32,12 @@ var/bomb_set
|
||||
r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
|
||||
wires = new/datum/wires/nuclearbomb(src)
|
||||
previous_level = get_security_level()
|
||||
poi_list |= src
|
||||
|
||||
/obj/machinery/nuclearbomb/Destroy()
|
||||
qdel(wires)
|
||||
wires = null
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/process()
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
new /obj/item/weapon/gun/projectile/revolver/grenadelauncher(get_turf(H))
|
||||
if("medibeam")
|
||||
new /obj/item/weapon/gun/medbeam(get_turf(H))
|
||||
|
||||
playsound(get_turf(H),'sound/magic/Summon_guns.ogg', 50, 1)
|
||||
else
|
||||
switch(randomizemagic)
|
||||
if("fireball")
|
||||
@@ -155,3 +157,5 @@
|
||||
if("necromantic")
|
||||
new /obj/item/device/necromantic_stone(get_turf(H))
|
||||
to_chat(H, "<span class='notice'>You suddenly feel lucky.</span>")
|
||||
|
||||
playsound(get_turf(H),'sound/magic/Summon_Magic.ogg', 50, 1)
|
||||
|
||||
@@ -854,3 +854,9 @@
|
||||
spellname = "disintegrate"
|
||||
icon_state ="bookfireball"
|
||||
desc = "This book feels like it will rip stuff apart."
|
||||
|
||||
/obj/item/weapon/spellbook/oneuse/sacredflame
|
||||
spell = /obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
spellname = "sacred flame"
|
||||
icon_state ="booksacredflame"
|
||||
desc = "Become one with the flames that burn within... and invite others to do so as well."
|
||||
@@ -57,6 +57,12 @@
|
||||
var/screen = 0 // Screen 0: main control, screen 1: access levels
|
||||
var/one_access = 0 // Determines if access control is set to req_one_access or req_access
|
||||
|
||||
var/faction = "neutral"
|
||||
var/emp_vulnerable = 1 // Can be empd
|
||||
var/scan_range = 7
|
||||
var/always_up = 0 //Will stay active
|
||||
var/has_cover = 1 //Hides the cover
|
||||
|
||||
/obj/machinery/porta_turret/centcom
|
||||
enabled = 0
|
||||
ailock = 1
|
||||
@@ -460,7 +466,7 @@ var/list/turret_icons
|
||||
take_damage(Proj.damage)
|
||||
|
||||
/obj/machinery/porta_turret/emp_act(severity)
|
||||
if(enabled)
|
||||
if(enabled && emp_vulnerable)
|
||||
//if the turret is on, the EMP no matter how severe disables the turret for a while
|
||||
//and scrambles its settings, with a slight chance of having an emag effect
|
||||
check_arrest = prob(50)
|
||||
@@ -502,11 +508,13 @@ var/list/turret_icons
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(!always_up)
|
||||
//if the turret has no power or is broken, make the turret pop down if it hasn't already
|
||||
popDown()
|
||||
return
|
||||
|
||||
if(!enabled)
|
||||
if(!always_up)
|
||||
//if the turret is off, make it pop down
|
||||
popDown()
|
||||
return
|
||||
@@ -514,23 +522,29 @@ var/list/turret_icons
|
||||
var/list/targets = list() //list of primary targets
|
||||
var/list/secondarytargets = list() //targets that are least important
|
||||
|
||||
for(var/obj/mecha/ME in view(7,src))
|
||||
for(var/obj/mecha/ME in view(scan_range,src))
|
||||
assess_and_assign(ME.occupant, targets, secondarytargets)
|
||||
|
||||
for(var/obj/spacepod/SP in view(7,src))
|
||||
for(var/obj/spacepod/SP in view(scan_range,src))
|
||||
assess_and_assign(SP.pilot, targets, secondarytargets)
|
||||
|
||||
for(var/obj/vehicle/T in view(7,src))
|
||||
for(var/obj/vehicle/T in view(scan_range,src))
|
||||
assess_and_assign(T.buckled_mob, targets, secondarytargets)
|
||||
|
||||
for(var/mob/living/C in view(7,src)) //loops through all living lifeforms in view
|
||||
for(var/mob/living/C in view(scan_range,src)) //loops through all living lifeforms in view
|
||||
assess_and_assign(C, targets, secondarytargets)
|
||||
|
||||
if(!tryToShootAt(targets))
|
||||
if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets
|
||||
if(!always_up)
|
||||
spawn()
|
||||
popDown() // no valid targets, close the cover
|
||||
|
||||
/obj/machinery/porta_turret/proc/in_faction(mob/living/target)
|
||||
if(!(faction in target.faction))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets)
|
||||
switch(assess_living(L))
|
||||
if(TURRET_PRIORITY_TARGET)
|
||||
@@ -557,12 +571,15 @@ var/list/turret_icons
|
||||
if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really
|
||||
return TURRET_NOT_TARGET //move onto next potential victim!
|
||||
|
||||
if(get_dist(src, L) > 7) //if it's too far away, why bother?
|
||||
if(get_dist(src, L) > scan_range) //if it's too far away, why bother?
|
||||
return TURRET_NOT_TARGET
|
||||
|
||||
if(emagged) // If emagged not even the dead get a rest
|
||||
return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET
|
||||
|
||||
if(in_faction(L))
|
||||
return TURRET_NOT_TARGET
|
||||
|
||||
if(lethal && locate(/mob/living/silicon/ai) in get_turf(L)) //don't accidentally kill the AI!
|
||||
return TURRET_NOT_TARGET
|
||||
|
||||
@@ -648,8 +665,8 @@ var/list/turret_icons
|
||||
return ..()
|
||||
|
||||
/obj/machinery/porta_turret/proc/set_raised_raising(var/raised, var/raising)
|
||||
src.raised = raised
|
||||
src.raising = raising
|
||||
raised = raised
|
||||
raising = raising
|
||||
density = raised || raising
|
||||
|
||||
/obj/machinery/porta_turret/proc/target(var/mob/living/target)
|
||||
@@ -657,6 +674,7 @@ var/list/turret_icons
|
||||
return
|
||||
if(target)
|
||||
last_target = target
|
||||
if(has_cover)
|
||||
spawn()
|
||||
popUp() //pop the turret up if it's not already up.
|
||||
dir = get_dir(src, target) //even if you can't shoot, follow the target
|
||||
@@ -666,7 +684,7 @@ var/list/turret_icons
|
||||
return
|
||||
|
||||
/obj/machinery/porta_turret/proc/shootAt(var/mob/living/target)
|
||||
if(!raised) //the turret has to be raised in order to fire - makes sense, right?
|
||||
if(!raised && has_cover) //the turret has to be raised in order to fire - makes sense, right?
|
||||
return
|
||||
//any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power!
|
||||
if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate
|
||||
@@ -718,9 +736,9 @@ var/list/turret_icons
|
||||
/obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC)
|
||||
if(controllock)
|
||||
return
|
||||
src.enabled = TC.enabled
|
||||
src.lethal = TC.lethal
|
||||
src.iconholder = TC.lethal
|
||||
enabled = TC.enabled
|
||||
lethal = TC.lethal
|
||||
iconholder = TC.lethal
|
||||
|
||||
check_synth = TC.check_synth
|
||||
check_access = TC.check_access
|
||||
@@ -730,7 +748,7 @@ var/list/turret_icons
|
||||
check_anomalies = TC.check_anomalies
|
||||
ailock = TC.ailock
|
||||
|
||||
src.power_change()
|
||||
power_change()
|
||||
|
||||
/*
|
||||
Portable turret constructions
|
||||
@@ -943,3 +961,74 @@ var/list/turret_icons
|
||||
|
||||
/atom/movable/porta_turret_cover
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
|
||||
// Syndicate turrets
|
||||
/obj/machinery/porta_turret/syndicate
|
||||
installation = null
|
||||
always_up = 1
|
||||
use_power = 0
|
||||
has_cover = 0
|
||||
scan_range = 9
|
||||
projectile = /obj/item/projectile/bullet
|
||||
eprojectile = /obj/item/projectile/bullet
|
||||
shot_sound = 'sound/weapons/Gunshot.ogg'
|
||||
eshot_sound = 'sound/weapons/Gunshot.ogg'
|
||||
icon_state = "syndieturret0"
|
||||
var/icon_state_initial = "syndieturret0"
|
||||
var/icon_state_active = "syndieturret1"
|
||||
var/icon_state_destroyed = "syndieturret2"
|
||||
faction = "syndicate"
|
||||
emp_vulnerable = 0
|
||||
raised = 1
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/New()
|
||||
..()
|
||||
if(req_one_access && req_one_access.len)
|
||||
req_one_access.Cut()
|
||||
req_access = list(access_syndicate)
|
||||
one_access = 0
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/update_icon()
|
||||
if(stat & BROKEN)
|
||||
icon_state = icon_state_destroyed
|
||||
else if(enabled)
|
||||
icon_state = icon_state_active
|
||||
else
|
||||
icon_state = icon_state_initial
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/setup()
|
||||
return
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/assess_perp(mob/living/carbon/human/perp)
|
||||
return 10 //Syndicate turrets shoot everything not in their faction
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/pod
|
||||
health = 40
|
||||
projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
eprojectile = /obj/item/projectile/bullet/weakbullet3
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/interior
|
||||
name = "machine gun turret (.45)"
|
||||
desc = "Syndicate interior defense turret chambered for .45 rounds. Designed to down intruders without damaging the hull."
|
||||
projectile = /obj/item/projectile/bullet/midbullet
|
||||
eprojectile = /obj/item/projectile/bullet/midbullet
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/exterior
|
||||
name = "machine gun turret (7.62)"
|
||||
desc = "Syndicate exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets."
|
||||
projectile = /obj/item/projectile/bullet
|
||||
eprojectile = /obj/item/projectile/bullet/midbullet
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/grenade
|
||||
name = "mounted grenade launcher (40mm)"
|
||||
desc = "Syndicate 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead."
|
||||
projectile = /obj/item/projectile/bullet/a40mm
|
||||
eprojectile = /obj/item/projectile/bullet/midbullet
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/assault_pod
|
||||
name = "machine gun turret (4.6x30mm)"
|
||||
desc = "Syndicate exterior defense turret chambered for 4.6x30mm rounds. Designed to be fitted to assault pods, it uses low calliber bullets to save space."
|
||||
health = 100
|
||||
projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
eprojectile = /obj/item/projectile/bullet/midbullet
|
||||
|
||||
|
||||
@@ -257,6 +257,7 @@
|
||||
var/obj/machinery/syndicatebomb/B = src.loc
|
||||
for(var/i = 0; i < amt_summon; i++)
|
||||
var/atom/movable/X = new summon_path
|
||||
X.admin_spawned = TRUE
|
||||
X.loc = get_turf(src)
|
||||
if(prob(50))
|
||||
for(var/j = 1, j <= rand(1, 3), j++)
|
||||
|
||||
@@ -1,580 +0,0 @@
|
||||
/area/turret_protected
|
||||
name = "Turret Protected Area"
|
||||
var/list/turretTargets = list()
|
||||
|
||||
/area/turret_protected/proc/subjectDied(target)
|
||||
if( isliving(target) )
|
||||
if( !issilicon(target) )
|
||||
var/mob/living/L = target
|
||||
if( L.stat )
|
||||
if( L in turretTargets )
|
||||
src.Exited(L)
|
||||
|
||||
|
||||
/area/turret_protected/Entered(O)
|
||||
..()
|
||||
if( iscarbon(O) )
|
||||
turretTargets |= O
|
||||
else if( istype(O, /obj/mecha) )
|
||||
var/obj/mecha/Mech = O
|
||||
if( Mech.occupant )
|
||||
turretTargets |= Mech
|
||||
else if( istype(O, /obj/spacepod) )
|
||||
var/obj/spacepod/Pod = O
|
||||
if( Pod.pilot )
|
||||
turretTargets |= Pod
|
||||
else if(istype(O,/mob/living/simple_animal))
|
||||
turretTargets |= O
|
||||
return 1
|
||||
|
||||
/area/turret_protected/Exited(O)
|
||||
if( ismob(O) && !issilicon(O) )
|
||||
turretTargets -= O
|
||||
else if( istype(O, /obj/mecha) )
|
||||
turretTargets -= O
|
||||
else if( istype(O, /obj/spacepod) )
|
||||
turretTargets -= O
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/turret
|
||||
name = "turret"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
icon_state = "grey_target_prism"
|
||||
var/raised = 0
|
||||
var/enabled = 1
|
||||
anchored = 1
|
||||
layer = 3
|
||||
invisibility = INVISIBILITY_LEVEL_TWO
|
||||
density = 1
|
||||
var/lasers = 0
|
||||
var/lasertype = 1
|
||||
// 1 = lasers
|
||||
// 2 = cannons
|
||||
// 3 = pulse
|
||||
// 4 = change (HONK)
|
||||
// 5 = bluetag
|
||||
// 6 = redtag
|
||||
var/health = 80
|
||||
var/obj/machinery/turretcover/cover = null
|
||||
var/popping = 0
|
||||
var/wasvalid = 0
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 30 //3 seconds between shots
|
||||
var/datum/effect/system/spark_spread/spark_system
|
||||
use_power = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 300
|
||||
// var/list/targets
|
||||
var/atom/movable/cur_target
|
||||
var/targeting_active = 0
|
||||
var/area/turret_protected/protected_area
|
||||
|
||||
|
||||
/obj/machinery/turret/New()
|
||||
spark_system = new /datum/effect/system/spark_spread
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
// targets = new
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/turretcover
|
||||
name = "pop-up turret cover"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
icon_state = "turretCover"
|
||||
anchored = 1
|
||||
layer = 3.5
|
||||
density = 0
|
||||
var/obj/machinery/turret/host = null
|
||||
|
||||
/obj/machinery/turret/proc/isPopping()
|
||||
return (popping!=0)
|
||||
|
||||
/obj/machinery/turret/power_change()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "grey_target_prism"
|
||||
else
|
||||
if( powered() )
|
||||
if(src.enabled)
|
||||
if(src.lasers)
|
||||
icon_state = "orange_target_prism"
|
||||
else
|
||||
icon_state = "target_prism"
|
||||
else
|
||||
icon_state = "grey_target_prism"
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
src.icon_state = "grey_target_prism"
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/turret/proc/setState(var/enabled, var/lethal)
|
||||
src.enabled = enabled
|
||||
src.lasers = lethal
|
||||
src.power_change()
|
||||
|
||||
|
||||
/obj/machinery/turret/proc/get_protected_area()
|
||||
var/area/turret_protected/TP = get_area(src)
|
||||
if(istype(TP))
|
||||
return TP
|
||||
return
|
||||
|
||||
/obj/machinery/turret/proc/check_target(var/atom/movable/T as mob|obj)
|
||||
if( T && T in protected_area.turretTargets )
|
||||
var/area/area_T = get_area(T)
|
||||
if( !area_T || (area_T.type != protected_area.type) )
|
||||
protected_area.Exited(T)
|
||||
return 0 //If the guy is somehow not in the turret's area (teleportation), get them out the damn list. --NEO
|
||||
if( iscarbon(T) )
|
||||
var/mob/living/carbon/MC = T
|
||||
if( !MC.stat )
|
||||
if( !MC.lying || lasers )
|
||||
return 1
|
||||
else if( istype(T, /obj/mecha) )
|
||||
var/obj/mecha/ME = T
|
||||
if( ME.occupant )
|
||||
return 1
|
||||
else if( istype(T, /obj/spacepod) )
|
||||
var/obj/spacepod/SP = T
|
||||
if( SP.pilot )
|
||||
return 1
|
||||
else if(istype(T,/mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/A = T
|
||||
if( !A.stat )
|
||||
if(lasers)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/turret/proc/get_new_target()
|
||||
var/list/new_targets = new
|
||||
var/new_target
|
||||
for(var/mob/living/carbon/M in protected_area.turretTargets)
|
||||
if(!M.stat)
|
||||
if(!M.lying || lasers)
|
||||
new_targets += M
|
||||
for(var/obj/mecha/M in protected_area.turretTargets)
|
||||
if(M.occupant)
|
||||
new_targets += M
|
||||
for(var/obj/spacepod/M in protected_area.turretTargets)
|
||||
if(M.pilot)
|
||||
new_targets += M.pilot
|
||||
for(var/mob/living/simple_animal/M in protected_area.turretTargets)
|
||||
if(!M.stat)
|
||||
new_targets += M
|
||||
if(new_targets.len)
|
||||
new_target = pick(new_targets)
|
||||
return new_target
|
||||
|
||||
|
||||
/obj/machinery/turret/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(src.cover==null)
|
||||
src.cover = new /obj/machinery/turretcover(src.loc)
|
||||
src.cover.host = src
|
||||
protected_area = get_protected_area()
|
||||
if(!enabled || !protected_area || protected_area.turretTargets.len<=0)
|
||||
if(!isDown() && !isPopping())
|
||||
popDown()
|
||||
return
|
||||
if(!check_target(cur_target)) //if current target fails target check
|
||||
cur_target = get_new_target() //get new target
|
||||
|
||||
if(cur_target) //if it's found, proceed
|
||||
// to_chat(world, "[cur_target]")
|
||||
if(!isPopping())
|
||||
if(isDown())
|
||||
popUp()
|
||||
use_power = 2
|
||||
else
|
||||
spawn()
|
||||
if(!targeting_active)
|
||||
targeting_active = 1
|
||||
target()
|
||||
targeting_active = 0
|
||||
|
||||
if(prob(15))
|
||||
if(prob(50))
|
||||
playsound(get_turf(src), 'sound/effects/turret/move1.wav', 60, 1)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/effects/turret/move2.wav', 60, 1)
|
||||
|
||||
else if(!isPopping())//else, pop down
|
||||
if(!isDown())
|
||||
popDown()
|
||||
use_power = 1
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/turret/proc/target()
|
||||
while(src && enabled && !stat && check_target(cur_target))
|
||||
src.dir = get_dir(src, cur_target)
|
||||
shootAt(cur_target)
|
||||
sleep(shot_delay)
|
||||
return
|
||||
|
||||
/obj/machinery/turret/proc/shootAt(var/atom/movable/target)
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = get_turf(target)
|
||||
if(!T || !U)
|
||||
return
|
||||
var/obj/item/projectile/A
|
||||
if(src.lasers)
|
||||
switch(lasertype)
|
||||
if(1)
|
||||
A = new /obj/item/projectile/beam(loc)
|
||||
if(2)
|
||||
A = new /obj/item/projectile/beam/laser/heavylaser(loc)
|
||||
if(3)
|
||||
A = new /obj/item/projectile/beam/pulse(loc)
|
||||
if(4)
|
||||
A = new /obj/item/projectile/magic/change(loc)
|
||||
if(5)
|
||||
A = new /obj/item/projectile/beam/lasertag/bluetag(loc)
|
||||
if(6)
|
||||
A = new /obj/item/projectile/beam/lasertag/redtag(loc)
|
||||
use_power(500)
|
||||
else
|
||||
A = new /obj/item/projectile/energy/electrode( loc )
|
||||
use_power(200)
|
||||
if(src.lasers)
|
||||
playsound(get_turf(src), 'sound/weapons/Laser.ogg', 60, 1)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/weapons/Taser.ogg', 60, 1)
|
||||
A.original = target
|
||||
A.current = T
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
A.fire()
|
||||
return A
|
||||
|
||||
|
||||
/obj/machinery/turret/proc/isDown()
|
||||
return (invisibility!=0)
|
||||
|
||||
/obj/machinery/turret/proc/popUp()
|
||||
if((!isPopping()) || src.popping==-1)
|
||||
invisibility = 0
|
||||
popping = 1
|
||||
playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1)
|
||||
if(src.cover!=null)
|
||||
flick("popup", src.cover)
|
||||
src.cover.icon_state = "openTurretCover"
|
||||
spawn(10)
|
||||
if(popping==1) popping = 0
|
||||
|
||||
/obj/machinery/turret/proc/popDown()
|
||||
if((!isPopping()) || src.popping==1)
|
||||
popping = -1
|
||||
playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1)
|
||||
if(src.cover!=null)
|
||||
flick("popdown", src.cover)
|
||||
src.cover.icon_state = "turretCover"
|
||||
spawn(10)
|
||||
if(popping==-1)
|
||||
invisibility = INVISIBILITY_LEVEL_TWO
|
||||
popping = 0
|
||||
|
||||
/obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
src.health -= Proj.damage
|
||||
..()
|
||||
if(prob(45) && Proj.damage > 0) src.spark_system.start()
|
||||
qdel(Proj)
|
||||
if(src.health <= 0)
|
||||
src.die()
|
||||
return
|
||||
|
||||
/obj/machinery/turret/attackby(obj/item/weapon/W, mob/user)//I can't believe no one added this before/N
|
||||
..()
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
playsound(src.loc, 'sound/weapons/smash.ogg', 60, 1)
|
||||
src.spark_system.start()
|
||||
src.health -= W.force * 0.5
|
||||
if(src.health <= 0)
|
||||
src.die()
|
||||
return
|
||||
|
||||
/obj/machinery/turret/emp_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
enabled = 0
|
||||
lasers = 0
|
||||
power_change()
|
||||
..()
|
||||
|
||||
/obj/machinery/turret/ex_act(severity)
|
||||
if(severity < 3)
|
||||
src.die()
|
||||
|
||||
/obj/machinery/turret/proc/die()
|
||||
src.health = 0
|
||||
src.density = 0
|
||||
src.stat |= BROKEN
|
||||
src.icon_state = "destroyed_target_prism"
|
||||
if(cover!=null)
|
||||
qdel(cover)
|
||||
sleep(3)
|
||||
flick("explosion", src)
|
||||
spawn(13)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/turret/attack_animal(mob/living/simple_animal/M as mob)
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper == 0) return
|
||||
if(!(stat & BROKEN))
|
||||
visible_message("<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
|
||||
add_logs(src, M, "attacked", admin=0)
|
||||
//src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
|
||||
src.health -= M.melee_damage_upper
|
||||
if(src.health <= 0)
|
||||
src.die()
|
||||
else
|
||||
to_chat(M, "<span class='danger'>That object is useless to you.</span>")
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/turret/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
M.do_attack_animation(src)
|
||||
if(!(stat & BROKEN))
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
src.health -= 15
|
||||
if(src.health <= 0)
|
||||
src.die()
|
||||
else
|
||||
to_chat(M, "\green That object is useless to you.")
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0)
|
||||
if(..(href, href_list))
|
||||
return 1
|
||||
if(src.locked)
|
||||
if(!istype(usr, /mob/living/silicon))
|
||||
to_chat(usr, "Control panel is locked!")
|
||||
return
|
||||
if(href_list["toggleOn"])
|
||||
src.enabled = !src.enabled
|
||||
src.updateTurrets()
|
||||
else if(href_list["toggleLethal"])
|
||||
src.lethal = !src.lethal
|
||||
src.updateTurrets()
|
||||
if(!nowindow)
|
||||
src.attack_hand(usr)
|
||||
|
||||
/obj/machinery/turretid/proc/update_icons()
|
||||
if(src.enabled)
|
||||
if(src.lethal)
|
||||
icon_state = "control_kill"
|
||||
else
|
||||
icon_state = "control_stun"
|
||||
else
|
||||
icon_state = "control_standby"
|
||||
//CODE FIXED BUT REMOVED
|
||||
// if(control_area) //USE: updates other controls in the area
|
||||
// for(var/obj/machinery/turretid/Turret_Control in world) //I'm not sure if this is what it was
|
||||
// if( Turret_Control.control_area != src.control_area ) continue //supposed to do. Or whether the person
|
||||
// Turret_Control.icon_state = icon_state //who coded it originally was just tired
|
||||
// Turret_Control.enabled = enabled //or something. I don't see any situation
|
||||
// Turret_Control.lethal = lethal //in which this would be used on the current map.
|
||||
//If he wants it back he can uncomment it
|
||||
|
||||
|
||||
/obj/machinery/gun_turret //related to turrets but work way differentely because of being mounted on a moving ship.
|
||||
name = "machine gun turret"
|
||||
desc = "Syndicate heavy defense turret. It really packs a bunch."
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/state = 0 //Like stat on mobs, 0 is alive, 1 is damaged, 2 is dead
|
||||
var/faction = "syndicate"
|
||||
var/atom/cur_target = null
|
||||
var/scan_range = 9 //You will never see them coming
|
||||
var/health = 200 //Because it lacks a cover, and is mostly to keep people from touching the syndie shuttle.
|
||||
var/bullet_type = /obj/item/projectile/bullet
|
||||
var/firing_sound = 'sound/weapons/Gunshot3.ogg'
|
||||
var/base_icon = "syndieturret"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
icon_state = "syndieturret0"
|
||||
|
||||
/obj/machinery/gun_turret/New()
|
||||
..()
|
||||
take_damage(0) //check your health
|
||||
|
||||
/obj/machinery/gun_turret/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
die()
|
||||
if(2)
|
||||
take_damage(100)
|
||||
if(3)
|
||||
take_damage(50)
|
||||
return
|
||||
|
||||
/obj/machinery/gun_turret/emp_act() //Can't emp an mechanical turret.
|
||||
return
|
||||
|
||||
/obj/machinery/gun_turret/update_icon()
|
||||
if(state > 2 || state < 0) //someone fucked up the vars so fix them
|
||||
take_damage(0)
|
||||
icon_state = "[base_icon]" + "[state]"
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/proc/take_damage(damage)
|
||||
health -= damage
|
||||
var/orig_health = initial(health)
|
||||
var/health_percent = (health/orig_health) * 100
|
||||
|
||||
if(health_percent > 50)
|
||||
state = 0
|
||||
else
|
||||
state = 1
|
||||
if(health_percent <= 0)
|
||||
if(state != 2)
|
||||
die()
|
||||
return
|
||||
state = 2
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/bullet_act(var/obj/item/projectile/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
take_damage(Proj.damage)
|
||||
return
|
||||
|
||||
/obj/machinery/gun_turret/proc/die()
|
||||
state = 2
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/gun_turret/attack_hand(mob/user)
|
||||
return
|
||||
|
||||
/obj/machinery/gun_turret/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/attack_alien(mob/living/user as mob)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
user.visible_message("[user] slashes at [src]", "You slash at [src]")
|
||||
take_damage(15)
|
||||
return
|
||||
|
||||
/obj/machinery/gun_turret/proc/validate_target(atom/target)
|
||||
if(get_dist(target, src)>scan_range)
|
||||
return 0
|
||||
if(istype(target, /mob))
|
||||
var/mob/M = target
|
||||
if(!M.stat)
|
||||
return 1
|
||||
else if(istype(target, /obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
if(M.occupant)
|
||||
return 1
|
||||
else if(istype(target, /obj/spacepod))
|
||||
var/obj/spacepod/S = target
|
||||
if(S.pilot)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/process()
|
||||
if(state == 2)
|
||||
return
|
||||
if(cur_target && !validate_target(cur_target))
|
||||
cur_target = null
|
||||
if(!cur_target)
|
||||
cur_target = get_target()
|
||||
if(cur_target)
|
||||
fire(cur_target)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/proc/get_target()
|
||||
var/list/pos_targets = list()
|
||||
var/target = null
|
||||
for(var/mob/living/M in view(scan_range,src))
|
||||
if(M.stat)
|
||||
continue
|
||||
if(faction in M.faction)
|
||||
continue
|
||||
if(ispAI(M))
|
||||
continue
|
||||
pos_targets += M
|
||||
for(var/obj/mecha/M in oview(scan_range, src))
|
||||
if(M.occupant)
|
||||
if(faction in M.occupant.faction)
|
||||
continue
|
||||
if(!M.occupant)
|
||||
continue //Don't shoot at empty mechs.
|
||||
pos_targets += M
|
||||
for(var/obj/spacepod/M in oview(scan_range, src))
|
||||
if(M.pilot)
|
||||
var/mob/P = M.pilot
|
||||
if(faction in P.faction)
|
||||
continue
|
||||
if(!M.pilot)
|
||||
continue //Don't shoot at empty pods.
|
||||
pos_targets += M
|
||||
if(pos_targets.len)
|
||||
target = pick(pos_targets)
|
||||
return target
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/proc/fire(atom/target)
|
||||
if(!target)
|
||||
cur_target = null
|
||||
return
|
||||
src.dir = get_dir(src,target)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if(!src)
|
||||
return
|
||||
var/turf/curloc = get_turf(src)
|
||||
if(!targloc || !curloc)
|
||||
return
|
||||
if(targloc == curloc)
|
||||
return
|
||||
playsound(get_turf(src), firing_sound, 60, 1)
|
||||
var/obj/item/projectile/A = new bullet_type(curloc)
|
||||
A.original = target
|
||||
A.current = curloc
|
||||
A.yo = targloc.y - curloc.y
|
||||
A.xo = targloc.x - curloc.x
|
||||
A.fire()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/interior
|
||||
name = "machine gun turret (.45)"
|
||||
desc = "Syndicate interior defense turret chambered for .45 rounds. Designed to down intruders without damaging the hull."
|
||||
bullet_type = /obj/item/projectile/bullet/midbullet
|
||||
|
||||
/obj/machinery/gun_turret/exterior
|
||||
name = "machine gun turret (7.62)"
|
||||
desc = "Syndicate exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets."
|
||||
bullet_type = /obj/item/projectile/bullet
|
||||
|
||||
/obj/machinery/gun_turret/grenade
|
||||
name = "mounted grenade launcher (40mm)"
|
||||
desc = "Syndicate 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead."
|
||||
bullet_type = /obj/item/projectile/bullet/a40mm
|
||||
|
||||
/obj/machinery/gun_turret/assault_pod
|
||||
name = "machine gun turret (4.6x30mm)"
|
||||
desc = "Syndicate exterior defense turret chambered for 4.6x30mm rounds. Designed to be fitted to assault pods, it uses low calliber bullets to save space."
|
||||
health = 100
|
||||
bullet_type = /obj/item/projectile/bullet/weakbullet3
|
||||
@@ -92,6 +92,7 @@
|
||||
|
||||
processing_objects.Add(src)
|
||||
removeVerb(/obj/mecha/verb/disconnect_from_port)
|
||||
poi_list |= src
|
||||
log_message("[src] created.")
|
||||
mechas_list += src //global mech list
|
||||
prepare_huds()
|
||||
@@ -611,6 +612,7 @@
|
||||
qdel(internal_tank)
|
||||
|
||||
processing_objects.Remove(src)
|
||||
poi_list.Remove(src)
|
||||
equipment.Cut()
|
||||
cell = null
|
||||
internal_tank = null
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
|
||||
var/new_frequency = sanitize_frequency(rand(PUBLIC_LOW_FREQ, PUBLIC_HIGH_FREQ))
|
||||
aSignal.set_frequency(new_frequency)
|
||||
poi_list |= src
|
||||
|
||||
/obj/effect/anomaly/Destroy()
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/proc/anomalyEffect()
|
||||
if(prob(50))
|
||||
|
||||
@@ -262,3 +262,17 @@
|
||||
new /obj/item/clothing/mask/gas/sexymime(src.loc)
|
||||
new /obj/item/clothing/under/sexymime(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/ruin
|
||||
var/datum/map_template/ruin/ruin_template
|
||||
|
||||
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
|
||||
name = "ruin_[ruin_landmarks.len + 1]"
|
||||
..(loc)
|
||||
ruin_template = my_ruin_template
|
||||
ruin_landmarks |= src
|
||||
|
||||
/obj/effect/landmark/ruin/Destroy()
|
||||
ruin_landmarks -= src
|
||||
ruin_template = null
|
||||
. = ..()
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/obj/effect/overlay
|
||||
name = "overlay"
|
||||
unacidable = 1
|
||||
@@ -17,8 +16,8 @@
|
||||
var/tmp/atom/BeamSource
|
||||
New()
|
||||
..()
|
||||
spawn(10) qdel(src)
|
||||
|
||||
spawn(10)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/overlay/temp
|
||||
anchored = 1
|
||||
@@ -30,6 +29,9 @@
|
||||
/obj/effect/overlay/temp/New()
|
||||
if(randomdir)
|
||||
dir = pick(cardinal)
|
||||
|
||||
flick("[icon_state]", src) //Because we might be pulling it from a pool, flick whatever icon it uses so it starts at the start of the icon's animation.
|
||||
|
||||
spawn(duration)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -102,19 +102,41 @@ var/global/list/datum/stack_recipe/human_recipes = list( \
|
||||
icon_state = "sheet-leather"
|
||||
origin_tech = "materials=2"
|
||||
|
||||
/obj/item/stack/sheet/sinew
|
||||
name = "watcher sinew"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
desc = "Long stringy filaments which presumably came from a watcher's wings."
|
||||
singular_name = "watcher sinew"
|
||||
icon_state = "sinew"
|
||||
origin_tech = "biotech=4"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
singular_name = "hide plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = 3
|
||||
layer = MOB_LAYER
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake
|
||||
name = "ash drake hide"
|
||||
desc = "The strong, scaled hide of an ash drake."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "dragon_hide"
|
||||
singular_name = "drake plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = 3
|
||||
layer = MOB_LAYER
|
||||
|
||||
//Step one - dehairing.
|
||||
|
||||
/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if( istype(W, /obj/item/weapon/kitchen/knife) || \
|
||||
istype(W, /obj/item/weapon/twohanded/fireaxe) || \
|
||||
istype(W, /obj/item/weapon/hatchet) )
|
||||
|
||||
//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
|
||||
usr.visible_message("\blue \the [usr] starts cutting hair off \the [src]", "\blue You start cutting the hair off \the [src]", "You hear the sound of a knife rubbing against flesh")
|
||||
if(W.sharp)
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user,50, target = src))
|
||||
to_chat(usr, "\blue You cut the hair from this [src.singular_name]")
|
||||
user << "<span class='notice'>You cut the hair from this [src.singular_name].</span>"
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc)
|
||||
if(HS.amount < 50)
|
||||
@@ -128,7 +150,6 @@ var/global/list/datum/stack_recipe/human_recipes = list( \
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Step two - washing..... it's actually in washing machine code.
|
||||
|
||||
//Step three - drying
|
||||
|
||||
@@ -201,3 +201,19 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list (
|
||||
/obj/item/stack/sheet/cardboard/New(var/loc, var/amt = null)
|
||||
recipes = cardboard_recipes
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Bones
|
||||
*/
|
||||
/obj/item/stack/sheet/bone
|
||||
name = "bones"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bone"
|
||||
singular_name = "bone"
|
||||
desc = "Someone's been drinking their milk."
|
||||
force = 7
|
||||
throwforce = 5
|
||||
w_class = 3
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
origin_tech = "materials=2;biotech=2"
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
for(var/i=1, i<=deliveryamt, i++)
|
||||
var/atom/movable/x = new spawner_type
|
||||
x.admin_spawned = admin_spawned
|
||||
x.loc = T
|
||||
if(prob(50))
|
||||
for(var/j = 1, j <= rand(1, 3), j++)
|
||||
|
||||
@@ -794,7 +794,8 @@ var/global/nologevent = 0
|
||||
var/turf/T = get_turf(usr.loc)
|
||||
T.ChangeTurf(chosen)
|
||||
else
|
||||
new chosen(usr.loc)
|
||||
var/atom/A = new chosen(usr.loc)
|
||||
A.admin_spawned = TRUE
|
||||
|
||||
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
|
||||
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -163,7 +163,9 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/map_template_upload,
|
||||
/client/proc/view_runtimes,
|
||||
/client/proc/admin_serialize,
|
||||
/client/proc/admin_deserialize
|
||||
/client/proc/admin_deserialize,
|
||||
/client/proc/jump_to_ruin,
|
||||
/client/proc/toggle_medal_disable
|
||||
)
|
||||
var/list/admin_verbs_possess = list(
|
||||
/proc/possess,
|
||||
|
||||
@@ -431,7 +431,7 @@
|
||||
else
|
||||
dat += "<tr><td><i>Nuclear Operative not found!</i></td></tr>"
|
||||
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
|
||||
for(var/obj/item/weapon/disk/nuclear/N in world)
|
||||
for(var/obj/item/weapon/disk/nuclear/N in poi_list)
|
||||
dat += "<tr><td>[N.name], "
|
||||
var/atom/disk_loc = N.loc
|
||||
while(!istype(disk_loc, /turf))
|
||||
|
||||
@@ -2154,6 +2154,7 @@
|
||||
else
|
||||
var/atom/O = new path(target)
|
||||
if(O)
|
||||
O.admin_spawned = TRUE
|
||||
O.dir = obj_dir
|
||||
if(obj_name)
|
||||
O.name = obj_name
|
||||
|
||||
@@ -1474,3 +1474,57 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return
|
||||
|
||||
error_cache.showTo(usr)
|
||||
|
||||
/client/proc/jump_to_ruin()
|
||||
set category = "Debug"
|
||||
set name = "Jump to Ruin"
|
||||
set desc = "Displays a list of all placed ruins to teleport to."
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/list/names = list()
|
||||
for(var/i in ruin_landmarks)
|
||||
var/obj/effect/landmark/ruin/ruin_landmark = i
|
||||
var/datum/map_template/ruin/template = ruin_landmark.ruin_template
|
||||
|
||||
var/count = 1
|
||||
var/name = template.name
|
||||
var/original_name = name
|
||||
|
||||
while(name in names)
|
||||
count++
|
||||
name = "[original_name] ([count])"
|
||||
|
||||
names[name] = ruin_landmark
|
||||
|
||||
var/ruinname = input("Select ruin", "Jump to Ruin") as null|anything in names
|
||||
|
||||
var/obj/effect/landmark/ruin/landmark = names[ruinname]
|
||||
|
||||
if(istype(landmark))
|
||||
var/datum/map_template/ruin/template = landmark.ruin_template
|
||||
admin_forcemove(usr, get_turf(landmark))
|
||||
|
||||
usr << "<span class='name'>[template.name]</span>"
|
||||
usr << "<span class='italics'>[template.description]</span>"
|
||||
|
||||
log_admin("[key_name(usr)] jumped to ruin [ruinname]")
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to ruin [ruinname]", 1)
|
||||
|
||||
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/toggle_medal_disable()
|
||||
set category = "Debug"
|
||||
set name = "Toggle Medal Disable"
|
||||
set desc = "Toggles the safety lock on trying to contact the medal hub."
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
global.medals_enabled = !global.medals_enabled
|
||||
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.</span>")
|
||||
feedback_add_details("admin_verb","TMH") // If...
|
||||
log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
|
||||
|
||||
@@ -137,32 +137,38 @@
|
||||
for(var/mob/M in mob_list)
|
||||
if( istype(M , O.type) )
|
||||
M.vars[variable] = O.vars[variable]
|
||||
M.on_varedit(variable)
|
||||
|
||||
else if(istype(O, /obj))
|
||||
for(var/obj/A in world)
|
||||
if( istype(A , O.type) )
|
||||
A.vars[variable] = O.vars[variable]
|
||||
A.on_varedit(variable)
|
||||
|
||||
else if(istype(O, /turf))
|
||||
for(var/turf/A in world)
|
||||
if( istype(A , O.type) )
|
||||
A.vars[variable] = O.vars[variable]
|
||||
A.on_varedit(variable)
|
||||
|
||||
else
|
||||
if(istype(O, /mob))
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.type == O.type)
|
||||
M.vars[variable] = O.vars[variable]
|
||||
M.on_varedit(variable)
|
||||
|
||||
else if(istype(O, /obj))
|
||||
for(var/obj/A in world)
|
||||
if(A.type == O.type)
|
||||
A.vars[variable] = O.vars[variable]
|
||||
A.on_varedit(variable)
|
||||
|
||||
else if(istype(O, /turf))
|
||||
for(var/turf/A in world)
|
||||
if(A.type == O.type)
|
||||
A.vars[variable] = O.vars[variable]
|
||||
A.on_varedit(variable)
|
||||
|
||||
if("edit referenced object")
|
||||
return .(O.vars[variable])
|
||||
|
||||
@@ -440,6 +440,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
|
||||
if(var_as_text == null)
|
||||
var_as_text = "[O.vars[variable]]"
|
||||
O.on_varedit(variable)
|
||||
log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[var_as_text]")]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] to [var_as_text]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [var_as_text]", 1)
|
||||
|
||||
@@ -205,7 +205,17 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
|
||||
template = safepick(possible_ruins)
|
||||
if(!template)
|
||||
return 0
|
||||
var/turf/central_turf = get_turf(src)
|
||||
for(var/i in template.get_affected_turfs(central_turf, 1))
|
||||
var/turf/T = i
|
||||
for(var/mob/living/simple_animal/monster in T)
|
||||
qdel(monster)
|
||||
for(var/obj/structure/flora/ash/plant in T)
|
||||
qdel(plant)
|
||||
template.load(get_turf(src),centered = 1)
|
||||
template.loaded++
|
||||
var/datum/map_template/ruin = template
|
||||
if(istype(ruin))
|
||||
new /obj/effect/landmark/ruin(central_turf, ruin)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
@@ -34,9 +34,14 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
loc = start
|
||||
z_original = z
|
||||
destination = end
|
||||
poi_list |= src
|
||||
if(end && end.z==z_original)
|
||||
walk_towards(src, destination, 1)
|
||||
|
||||
/obj/effect/immovablerod/Destroy()
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/immovablerod/Move()
|
||||
if(z != z_original || loc == destination)
|
||||
qdel(src)
|
||||
|
||||
@@ -332,3 +332,10 @@
|
||||
desc = "A cup with the british flag emblazoned on it."
|
||||
icon_state = "britcup"
|
||||
volume = 30
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl
|
||||
name = "mushroom bowl"
|
||||
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "mushroom_bowl"
|
||||
w_class = 2
|
||||
@@ -725,7 +725,7 @@
|
||||
ranged = 1
|
||||
sentience_type = SENTIENCE_MINEBOT
|
||||
ranged_message = "shoots"
|
||||
ranged_cooldown_cap = 3
|
||||
ranged_cooldown_time = 30
|
||||
projectiletype = /obj/item/projectile/kinetic
|
||||
projectilesound = 'sound/weapons/Gunshot4.ogg'
|
||||
speak_emote = list("states")
|
||||
@@ -958,10 +958,10 @@
|
||||
name = "minebot cooldown upgrade"
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
if(M.ranged_cooldown_cap != initial(M.ranged_cooldown_cap))
|
||||
if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time))
|
||||
to_chat(user, "[M] already has a decreased weapon cooldown!")
|
||||
return
|
||||
M.ranged_cooldown_cap = 1
|
||||
M.ranged_cooldown_time = 10
|
||||
to_chat(user, "You upgrade [M]'s ranged weaponry, reducing its cooldown.")
|
||||
qdel(src)
|
||||
|
||||
|
||||
211
code/modules/mining/lavaland/ash_flora.dm
Normal file
@@ -0,0 +1,211 @@
|
||||
/obj/structure/flora/ash
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "l_mushroom"
|
||||
name = "large mushrooms"
|
||||
desc = "A number of large mushrooms, covered in a faint layer of ash and what can only be spores."
|
||||
var/harvested_name = "shortened mushrooms"
|
||||
var/harvested_desc = "Some quickly regrowing mushrooms, formerly known to be quite large."
|
||||
var/needs_sharp_harvest = TRUE
|
||||
var/harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings
|
||||
var/harvest_amount_low = 1
|
||||
var/harvest_amount_high = 3
|
||||
var/harvest_time = 60
|
||||
var/harvest_message_low = "You pick a mushroom, but fail to collect many shavings from its cap."
|
||||
var/harvest_message_med = "You pick a mushroom, carefully collecting the shavings from its cap."
|
||||
var/harvest_message_high = "You harvest and collect shavings from several mushroom caps."
|
||||
var/harvested = FALSE
|
||||
var/base_icon
|
||||
var/regrowth_time_low = 4800
|
||||
var/regrowth_time_high = 8400
|
||||
|
||||
/obj/structure/flora/ash/New()
|
||||
..()
|
||||
base_icon = "[icon_state][rand(1, 4)]"
|
||||
icon_state = base_icon
|
||||
if(prob(15))
|
||||
harvest(null, TRUE)
|
||||
|
||||
/obj/structure/flora/ash/proc/harvest(user, no_drop)
|
||||
if(harvested)
|
||||
return 0
|
||||
if(!no_drop)
|
||||
var/rand_harvested = rand(harvest_amount_low, harvest_amount_high)
|
||||
if(rand_harvested)
|
||||
if(user)
|
||||
var/msg = harvest_message_med
|
||||
if(rand_harvested == harvest_amount_low)
|
||||
msg = harvest_message_low
|
||||
else if(rand_harvested == harvest_amount_high)
|
||||
msg = harvest_message_high
|
||||
user << "<span class='notice'>[msg]</span>"
|
||||
for(var/i in 1 to rand_harvested)
|
||||
new harvest(get_turf(src))
|
||||
icon_state = "[base_icon]p"
|
||||
name = harvested_name
|
||||
desc = harvested_desc
|
||||
harvested = TRUE
|
||||
addtimer(src, "regrow", rand(regrowth_time_low, regrowth_time_high))
|
||||
return 1
|
||||
|
||||
/obj/structure/flora/ash/proc/regrow()
|
||||
icon_state = base_icon
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
harvested = FALSE
|
||||
|
||||
/obj/structure/flora/ash/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(!harvested && needs_sharp_harvest && W.sharp)
|
||||
user.visible_message("<span class='notice'>[user] starts to harvest from [src] with [W].</span>","<span class='notice'>You begin to harvest from [src] with [W].</span>")
|
||||
if(do_after(user, harvest_time, target = src))
|
||||
harvest(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/flora/ash/attack_hand(mob/user)
|
||||
if(!harvested && !needs_sharp_harvest)
|
||||
user.visible_message("<span class='notice'>[user] starts to harvest from [src].</span>","<span class='notice'>You begin to harvest from [src].</span>")
|
||||
if(do_after(user, harvest_time, target = src))
|
||||
harvest(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ash/tall_shroom //exists only so that the spawning check doesn't allow these spawning near other things
|
||||
regrowth_time_low = 4200
|
||||
|
||||
/obj/structure/flora/ash/leaf_shroom
|
||||
icon_state = "s_mushroom"
|
||||
name = "leafy mushrooms"
|
||||
desc = "A number of mushrooms, each of which surrounds a greenish sporangium with a number of leaf-like structures."
|
||||
harvested_name = "leafless mushrooms"
|
||||
harvested_desc = "A bunch of formerly-leafed mushrooms, with their sporangiums exposed. Scandalous?"
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf
|
||||
needs_sharp_harvest = FALSE
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 20
|
||||
harvest_message_low = "You pluck a single, suitable leaf."
|
||||
harvest_message_med = "You pluck a number of leaves, leaving a few unsuitable ones."
|
||||
harvest_message_high = "You pluck quite a lot of suitable leaves."
|
||||
regrowth_time_low = 2400
|
||||
regrowth_time_high = 6000
|
||||
|
||||
/obj/structure/flora/ash/cap_shroom
|
||||
icon_state = "r_mushroom"
|
||||
name = "tall mushrooms"
|
||||
desc = "Several mushrooms, the larger of which have a ring of conks at the midpoint of their stems."
|
||||
harvested_name = "small mushrooms"
|
||||
harvested_desc = "Several small mushrooms near the stumps of what likely were larger mushrooms."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 50
|
||||
harvest_message_low = "You slice the cap off of a mushroom."
|
||||
harvest_message_med = "You slice off a few conks from the larger mushrooms."
|
||||
harvest_message_high = "You slice off a number of caps and conks from these mushrooms."
|
||||
regrowth_time_low = 3000
|
||||
regrowth_time_high = 5400
|
||||
|
||||
/obj/structure/flora/ash/stem_shroom
|
||||
icon_state = "t_mushroom"
|
||||
name = "numerous mushrooms"
|
||||
desc = "A large number of mushrooms, some of which have long, fleshy stems. They're radiating light!"
|
||||
luminosity = 1
|
||||
harvested_name = "tiny mushrooms"
|
||||
harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem
|
||||
harvest_amount_high = 4
|
||||
harvest_time = 40
|
||||
harvest_message_low = "You pick and slice the cap off of a mushroom, leaving the stem."
|
||||
harvest_message_med = "You pick and decapitate several mushrooms for their stems."
|
||||
harvest_message_high = "You acquire a number of stems from these mushrooms."
|
||||
regrowth_time_low = 3000
|
||||
regrowth_time_high = 6000
|
||||
|
||||
/obj/structure/flora/ash/cacti
|
||||
icon_state = "cactus"
|
||||
name = "fruiting cacti"
|
||||
desc = "Several prickly cacti, brimming with ripe fruit and covered in a thin layer of ash."
|
||||
harvested_name = "cacti"
|
||||
harvested_desc = "A bunch of prickly cacti. You can see fruits slowly growing beneath the covering of ash."
|
||||
harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit
|
||||
needs_sharp_harvest = FALSE
|
||||
harvest_amount_high = 2
|
||||
harvest_time = 10
|
||||
harvest_message_low = "You pick a cactus fruit."
|
||||
harvest_message_med = "You pick several cactus fruit." //shouldn't show up, because you can't get more than two
|
||||
harvest_message_high = "You pick a pair of cactus fruit."
|
||||
regrowth_time_low = 4800
|
||||
regrowth_time_high = 7200
|
||||
|
||||
/obj/structure/flora/ash/cacti/Crossed(mob/AM)
|
||||
if(ishuman(AM) && has_gravity(loc) && prob(70))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(!H.shoes && !H.lying) //ouch, my feet.
|
||||
var/picked_def_zone = pick("l_leg", "r_leg")
|
||||
var/obj/item/organ/external/affected = H.get_organ(picked_def_zone)
|
||||
if(!istype(affected))
|
||||
return
|
||||
H.apply_damage(rand(3, 6), BRUTE, picked_def_zone)
|
||||
H.Weaken(2)
|
||||
H.visible_message("<span class='danger'>[H] steps on a cactus!</span>", \
|
||||
"<span class='userdanger'>You step on a cactus!</span>")
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/
|
||||
name = "mushroom shavings"
|
||||
desc = "Some shavings from a tall mushroom. With enough, might serve as a bowl."
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "mushroom_shavings"
|
||||
list_reagents = list("sugar" = 3, "ethanol" = 2, "stabilizing_agent" = 3, "minttoxin" = 2)
|
||||
w_class = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/New()
|
||||
..()
|
||||
pixel_x = rand(-4, 4)
|
||||
pixel_y = rand(-4, 4)
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings //for actual crafting
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf
|
||||
name = "mushroom leaf"
|
||||
desc = "A leaf, from a mushroom."
|
||||
list_reagents = list("nutriment" = 3, "vitfro" = 2, "nicotine" = 2)
|
||||
icon_state = "mushroom_leaf"
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap
|
||||
name = "mushroom cap"
|
||||
desc = "The cap of a large mushroom."
|
||||
list_reagents = list("mindbreaker" = 2, "entpoly" = 4, "mushroomhallucinogen" = 2)
|
||||
icon_state = "mushroom_cap"
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem
|
||||
name = "mushroom stem"
|
||||
desc = "A long mushroom stem. It's slightly glowing."
|
||||
list_reagents = list("tinlux" = 2, "vitamin" = 1, "space_drugs" = 1)
|
||||
icon_state = "mushroom_stem"
|
||||
luminosity = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit
|
||||
name = "cactus fruit"
|
||||
list_reagents = list("vitamin" = 2, "nutriment" = 2, "vitfro" = 4)
|
||||
desc = "A cactus fruit covered in a thick, reddish skin. And some ash."
|
||||
icon_state = "cactus_fruit"
|
||||
|
||||
|
||||
/obj/item/mushroom_bowl
|
||||
name = "mushroom bowl"
|
||||
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
|
||||
icon = 'icons/obj/lavaland/ash_flora.dmi'
|
||||
icon_state = "mushroom_bowl"
|
||||
w_class = 2
|
||||
|
||||
//what you can craft with these things
|
||||
/datum/crafting_recipe/mushroom_bowl
|
||||
name = "Mushroom Bowl"
|
||||
result = /obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl
|
||||
reqs = list(/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings = 5)
|
||||
time = 30
|
||||
category = CAT_PRIMAL
|
||||
229
code/modules/mining/lavaland/necropolis_chests.dm
Normal file
@@ -0,0 +1,229 @@
|
||||
//The chests dropped by mob spawner tendrils. Also contains associated loot.
|
||||
|
||||
/obj/structure/closet/crate/necropolis
|
||||
name = "necropolis chest"
|
||||
desc = "It's watching you closely."
|
||||
icon_state = "necrocrate"
|
||||
icon_opened = "necrocrateopen"
|
||||
icon_closed = "necrocrate"
|
||||
|
||||
///Bosses
|
||||
//Dragon
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon
|
||||
name = "dragon chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon/New()
|
||||
..()
|
||||
var/loot = rand(1,4)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/weapon/melee/ghost_sword(src)
|
||||
if(2)
|
||||
new /obj/item/weapon/lava_staff(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/spellbook/oneuse/sacredflame(src)
|
||||
new /obj/item/weapon/gun/magic/wand/fireball(src)
|
||||
if(4)
|
||||
new /obj/item/weapon/dragons_blood(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword
|
||||
name = "spectral blade"
|
||||
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
|
||||
icon_state = "spectral"
|
||||
item_state = "spectral"
|
||||
flags = CONDUCT
|
||||
sharp = 1
|
||||
w_class = 4
|
||||
force = 1
|
||||
throwforce = 1
|
||||
hitsound = 'sound/effects/ghost2.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
|
||||
var/summon_cooldown = 0
|
||||
var/list/mob/dead/observer/spirits
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/New()
|
||||
..()
|
||||
spirits = list()
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Destroy()
|
||||
for(var/mob/dead/observer/G in spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
spirits.Cut()
|
||||
processing_objects.Remove(src)
|
||||
poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack_self(mob/user)
|
||||
if(summon_cooldown > world.time)
|
||||
to_chat(user, "You just recently called out for aid. You don't want to annoy the spirits.")
|
||||
return
|
||||
to_chat(user, "You call out for aid, attempting to summon spirits to your side.")
|
||||
|
||||
notify_ghosts("[user] is raising their [src], calling for your help!", enter_link="<a href=?src=[UID()];follow=1>(Click to help)</a>", source = user, action = NOTIFY_FOLLOW)
|
||||
|
||||
summon_cooldown = world.time + 600
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/process()
|
||||
ghost_check()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/proc/ghost_check()
|
||||
var/ghost_counter = 0
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/contents = T.GetAllContents()
|
||||
var/mob/dead/observer/current_spirits = list()
|
||||
var/list/followers = list()
|
||||
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(is_type_in_list(O.following, contents))
|
||||
followers += O
|
||||
|
||||
for(var/thing in followers)
|
||||
if (isobserver(thing))
|
||||
var/mob/dead/observer/G = thing
|
||||
ghost_counter++
|
||||
G.invisibility = 0
|
||||
current_spirits |= G
|
||||
|
||||
for(var/mob/dead/observer/G in spirits - current_spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
|
||||
spirits = current_spirits
|
||||
|
||||
return ghost_counter
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
force = 0
|
||||
var/ghost_counter = ghost_check()
|
||||
|
||||
force = Clamp((ghost_counter * 4), 0, 75)
|
||||
user.visible_message("<span class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirits!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
|
||||
var/ghost_counter = ghost_check()
|
||||
final_block_chance += Clamp((ghost_counter * 5), 0, 75)
|
||||
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghosts!</span>")
|
||||
return ..()
|
||||
|
||||
// Blood
|
||||
|
||||
/obj/item/weapon/dragons_blood
|
||||
name = "bottle of dragons blood"
|
||||
desc = "You're not actually going to drink this, are you?"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/random = rand(1,3)
|
||||
|
||||
switch(random)
|
||||
if(1)
|
||||
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
|
||||
H.set_species("Skeleton")
|
||||
if(2)
|
||||
to_chat(user, "<span class='danger'>You don't feel so good...</span>")
|
||||
message_admins("[key_name_admin(user)] has started transforming into a dragon via dragon's blood.")
|
||||
H.ForceContractDisease(new /datum/disease/transformation/dragon(0))
|
||||
if(3)
|
||||
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
|
||||
H.weather_immunities |= "lava"
|
||||
|
||||
playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
qdel(src)
|
||||
|
||||
/datum/disease/transformation/dragon
|
||||
name = "dragon transformation"
|
||||
cure_text = "nothing"
|
||||
cures = list("adminordrazine")
|
||||
agent = "dragon's blood"
|
||||
desc = "What do dragons have to do with Space Station 13?"
|
||||
stage_prob = 20
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your bones ache.")
|
||||
stage2 = list("Your skin feels scaley.")
|
||||
stage3 = list("<span class='danger'>You have an overwhelming urge to terrorize some peasants.</span>", "<span class='danger'>Your teeth feel sharper.</span>")
|
||||
stage4 = list("<span class='danger'>Your blood burns.</span>")
|
||||
stage5 = list("<span class='danger'>You're a fucking dragon. However, any previous allegiances you held still apply. It'd be incredibly rude to eat your still human friends for no reason.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
|
||||
//Lava Staff
|
||||
|
||||
/obj/item/weapon/lava_staff
|
||||
name = "staff of lava"
|
||||
desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?"
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/turf_type = /turf/unsimulated/floor/lava // /turf/simulated/floor/plating/lava/smooth once Lavaland turfs are added
|
||||
var/transform_string = "lava"
|
||||
var/reset_turf_type = /turf/simulated/floor/plating/airless/asteroid // /turf/simulated/floor/plating/asteroid/basalt once Lavaland turfs are added
|
||||
var/reset_string = "basalt"
|
||||
var/create_cooldown = 100
|
||||
var/create_delay = 30
|
||||
var/reset_cooldown = 50
|
||||
var/timer = 0
|
||||
var/banned_turfs
|
||||
|
||||
/obj/item/weapon/lava_staff/New()
|
||||
. = ..()
|
||||
banned_turfs = typecacheof(list(/turf/space/transit, /turf/unsimulated))
|
||||
|
||||
/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
if(timer > world.time)
|
||||
return
|
||||
|
||||
if(is_type_in_typecache(target, banned_turfs))
|
||||
return
|
||||
|
||||
if(target in view(user.client.view, get_turf(user)))
|
||||
|
||||
var/turf/simulated/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!istype(T, turf_type))
|
||||
var/obj/effect/overlay/temp/lavastaff/L = PoolOrNew(/obj/effect/overlay/temp/lavastaff, T)
|
||||
L.alpha = 0
|
||||
animate(L, alpha = 255, time = create_delay)
|
||||
user.visible_message("<span class='danger'>[user] points [src] at [T]!</span>")
|
||||
timer = world.time + create_delay + 1
|
||||
if(do_after(user, create_delay, target = T))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>).")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
|
||||
T.ChangeTurf(turf_type)
|
||||
timer = world.time + create_cooldown
|
||||
qdel(L)
|
||||
else
|
||||
timer = world.time
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [reset_string]!</span>")
|
||||
T.ChangeTurf(reset_turf_type)
|
||||
timer = world.time + reset_cooldown
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
/obj/effect/overlay/temp/lavastaff
|
||||
icon_state = "lavastaff_warn"
|
||||
duration = 50
|
||||
@@ -63,6 +63,10 @@
|
||||
refined_type = /obj/item/stack/sheet/glass
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/weapon/ore/glass/basalt
|
||||
name = "volcanic ash"
|
||||
icon_state = "volcanic_sand"
|
||||
|
||||
/obj/item/weapon/ore/glass/attack_self(mob/living/user as mob)
|
||||
to_chat(user, "<span class='notice'>You use the sand to make sandstone.</span>")
|
||||
var/sandAmt = 1
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/living/simple_animal/hostile
|
||||
faction = list("hostile")
|
||||
mouse_opacity = 2 //This makes it easier to hit hostile mobs, you only need to click on their tile, and is set back to 1 when they die
|
||||
stop_automated_movement_when_pulled = 0
|
||||
environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
|
||||
var/atom/target
|
||||
@@ -13,7 +12,8 @@
|
||||
var/list/friends = list()
|
||||
var/ranged_message = "fires" //Fluff text for ranged mobs
|
||||
var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks
|
||||
var/ranged_cooldown_cap = 3 //What ranged attacks, after being used are set to, to go back on cooldown, defaults to 3 life() ticks
|
||||
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
|
||||
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
|
||||
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
|
||||
@@ -31,10 +31,30 @@
|
||||
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
|
||||
//typecache of things this mob will attack in DestroySurroundings() if it has environment_smash
|
||||
var/list/environment_target_typecache = list(
|
||||
/obj/machinery/door/window,
|
||||
/obj/structure/window,
|
||||
/obj/structure/closet,
|
||||
/obj/structure/table,
|
||||
/obj/structure/grille,
|
||||
/obj/structure/girder,
|
||||
/obj/structure/rack,
|
||||
/obj/structure/barricade) //turned into a typecache in New()
|
||||
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
|
||||
|
||||
/mob/living/simple_animal/hostile/New()
|
||||
..()
|
||||
if(!targets_from)
|
||||
targets_from = src
|
||||
environment_target_typecache = typecacheof(environment_target_typecache)
|
||||
|
||||
/mob/living/simple_animal/hostile/Destroy()
|
||||
targets_from = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
. = ..()
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
@@ -62,20 +82,19 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see
|
||||
var/list/L = list()
|
||||
. = list()
|
||||
if(!search_objects)
|
||||
var/list/Mobs = hearers(vision_range, src) - src //Remove self, so we don't suicide
|
||||
L += Mobs
|
||||
for(var/obj/mecha/M in mechas_list)
|
||||
if(get_dist(M, src) <= vision_range && can_see(src, M, vision_range))
|
||||
L += M
|
||||
for(var/obj/spacepod/S in spacepods_list)
|
||||
if(get_dist(S, src) <= vision_range && can_see(src, S, vision_range))
|
||||
L += S
|
||||
var/list/Mobs = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
|
||||
. += Mobs
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/spacepod))
|
||||
|
||||
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
. += HM
|
||||
else
|
||||
var/list/Objects = oview(vision_range, src)
|
||||
L += Objects
|
||||
return L
|
||||
var/list/Objects = oview(vision_range, targets_from)
|
||||
. += Objects
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
|
||||
var/list/Targets = list()
|
||||
@@ -100,8 +119,8 @@
|
||||
return
|
||||
if(target != null)//If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets
|
||||
for(var/atom/A in Targets)
|
||||
var/target_dist = get_dist(src, target)
|
||||
var/possible_target_distance = get_dist(src, A)
|
||||
var/target_dist = get_dist(targets_from, target)
|
||||
var/possible_target_distance = get_dist(targets_from, A)
|
||||
if(target_dist < possible_target_distance)
|
||||
Targets -= A
|
||||
var/chosen_target = safepick(Targets)//Pick the remaining targets (if any) at random
|
||||
@@ -111,16 +130,6 @@
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return 0
|
||||
if(search_objects < 2)
|
||||
if(istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
if(CanAttack(M.occupant))
|
||||
return 1
|
||||
if(istype(the_target, /obj/spacepod))
|
||||
var/obj/spacepod/S = the_target
|
||||
if(S.pilot) //Just so we don't attack empty pods
|
||||
if(CanAttack(S.pilot))
|
||||
return 1
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
var/faction_check = 0
|
||||
@@ -141,6 +150,28 @@
|
||||
if(faction_check && !attack_same)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
if(istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
if(CanAttack(M.occupant))
|
||||
return 1
|
||||
|
||||
if(istype(the_target, /obj/spacepod))
|
||||
var/obj/spacepod/S = the_target
|
||||
if(S.pilot) //Just so we don't attack empty pods
|
||||
if(CanAttack(S.pilot))
|
||||
return 1
|
||||
|
||||
if(istype(the_target, /obj/machinery/porta_turret))
|
||||
var/obj/machinery/porta_turret/P = the_target
|
||||
if(P.faction in faction)
|
||||
return 0
|
||||
if(!P.raised) //Don't attack invincible turrets
|
||||
return 0
|
||||
if(P.stat & BROKEN) //Or turrets that are already broken
|
||||
return 0
|
||||
return 1
|
||||
if(isobj(the_target))
|
||||
if(is_type_in_list(the_target, wanted_objects))
|
||||
return 1
|
||||
@@ -157,9 +188,12 @@
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(target in possible_targets)
|
||||
var/target_distance = get_dist(src,target)
|
||||
if(target.z != z)
|
||||
LoseTarget()
|
||||
return 0
|
||||
var/target_distance = get_dist(targets_from,target)
|
||||
if(ranged)//We ranged? Shoot at em
|
||||
if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
|
||||
OpenFire(target)
|
||||
if(retreat_distance != null)//If we have a retreat distance, check if we need to run from our target
|
||||
if(target_distance <= retreat_distance)//If target's closer than our retreat distance, run
|
||||
@@ -168,11 +202,15 @@
|
||||
Goto(target,move_to_delay,minimum_distance)//Otherwise, get to our minimum distance so we chase them
|
||||
else
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
|
||||
if(target)
|
||||
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack
|
||||
AttackingTarget()
|
||||
return 1
|
||||
return 1
|
||||
if(environment_smash)
|
||||
if(target.loc != null && get_dist(src, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still
|
||||
if(target.loc != null && get_dist(targets_from, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still
|
||||
if(ranged_ignores_vision && ranged_cooldown <= world.time) //we can't see our target... but we can fire at them!
|
||||
OpenFire(target)
|
||||
if(environment_smash >= 2)//If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
FindHidden()
|
||||
@@ -221,59 +259,60 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/death(gibbed)
|
||||
LoseAggro()
|
||||
mouse_opacity = 1
|
||||
..()
|
||||
walk(src, 0)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
|
||||
var/target = the_target
|
||||
/mob/living/simple_animal/hostile/proc/summon_backup(distance)
|
||||
do_alert_animation(src)
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1)
|
||||
for(var/mob/living/simple_animal/hostile/M in oview(distance, targets_from))
|
||||
var/list/L = M.faction&faction
|
||||
if(L.len)
|
||||
if(M.AIStatus == AI_OFF)
|
||||
return
|
||||
else
|
||||
M.Goto(src,M.move_to_delay,M.minimum_distance)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(atom/A)
|
||||
if(check_friendly_fire)
|
||||
for(var/turf/T in getline(src, target)) // Not 100% reliable but this is faster than simulating actual trajectory
|
||||
for(var/mob/living/L in T)
|
||||
if(L == src || L == target)
|
||||
if(L == src || L == A)
|
||||
continue
|
||||
if(faction_check(L) && !attack_same)
|
||||
return
|
||||
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [target]!</span>")
|
||||
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [A]!</span>")
|
||||
|
||||
if(rapid)
|
||||
spawn(1)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
Shoot(A)
|
||||
spawn(4)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
Shoot(A)
|
||||
spawn(6)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
Shoot(A)
|
||||
else
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype
|
||||
ranged_cooldown = ranged_cooldown_cap
|
||||
Shoot(A)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
|
||||
if(target == start)
|
||||
/mob/living/simple_animal/hostile/proc/Shoot(atom/targeted_atom)
|
||||
if(targeted_atom == targets_from.loc || targeted_atom == targets_from)
|
||||
return
|
||||
|
||||
var/turf/startloc = get_turf(targets_from)
|
||||
if(casingtype)
|
||||
var/obj/item/ammo_casing/casing = new casingtype
|
||||
var/obj/item/ammo_casing/casing = new casingtype(startloc)
|
||||
playsound(src, projectilesound, 100, 1)
|
||||
casing.fire(target, src, zone_override = ran_zone())
|
||||
casing.loc = loc
|
||||
casing.fire(targeted_atom, src, zone_override = ran_zone())
|
||||
else
|
||||
var/obj/item/projectile/A = new projectiletype(loc)
|
||||
playsound(user, projectilesound, 100, 1)
|
||||
playsound(src, projectilesound, 100, 1)
|
||||
A.current = target
|
||||
A.firer = src
|
||||
A.yo = target:y - start:y
|
||||
A.xo = target:x - start:x
|
||||
A.yo = targeted_atom.y - startloc.y
|
||||
A.xo = targeted_atom.x - startloc.x
|
||||
if(AIStatus == AI_OFF)//Don't want mindless mobs to have their movement screwed up firing in space
|
||||
newtonian_move(get_dir(target, user))
|
||||
newtonian_move(get_dir(target, targets_from))
|
||||
A.original = target
|
||||
A.fire()
|
||||
return A
|
||||
@@ -282,22 +321,22 @@
|
||||
if(environment_smash)
|
||||
EscapeConfinement()
|
||||
for(var/dir in cardinal)
|
||||
var/turf/T = get_step(src, dir)
|
||||
var/turf/T = get_step(targets_from, dir)
|
||||
if(istype(T, /turf/simulated/wall) || istype(T, /turf/simulated/mineral))
|
||||
if(T.Adjacent(src))
|
||||
if(T.Adjacent(targets_from))
|
||||
T.attack_animal(src)
|
||||
for(var/atom/A in T)
|
||||
if(!A.Adjacent(src))
|
||||
if(!A.Adjacent(targets_from))
|
||||
continue
|
||||
if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/rack))
|
||||
if(is_type_in_typecache(A, environment_target_typecache))
|
||||
A.attack_animal(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/EscapeConfinement()
|
||||
if(buckled)
|
||||
buckled.attack_animal(src)
|
||||
if(!isturf(src.loc) && src.loc != null)//Did someone put us in something?
|
||||
var/atom/A = src.loc
|
||||
if(!isturf(targets_from.loc) && targets_from.loc != null)//Did someone put us in something?
|
||||
var/atom/A = get_turf(targets_from)
|
||||
A.attack_animal(src)//Bang on it till we get out
|
||||
return
|
||||
|
||||
@@ -305,12 +344,12 @@
|
||||
if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper) || istype(target.loc, /obj/machinery/bodyscanner) || istype(target.loc, /obj/machinery/recharge_station))
|
||||
var/atom/A = target.loc
|
||||
Goto(A,move_to_delay,minimum_distance)
|
||||
if(A.Adjacent(src))
|
||||
if(A.Adjacent(targets_from))
|
||||
A.attack_animal(src)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/RangedAttack(var/atom/A, var/params) //Player firing
|
||||
if(ranged && ranged_cooldown <= 0)
|
||||
if(ranged && ranged_cooldown <= world.time)
|
||||
target = A
|
||||
OpenFire(A)
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
#define MEDAL_PREFIX "Drake"
|
||||
/*
|
||||
|
||||
ASH DRAKE
|
||||
|
||||
Ash drakes spawn randomly wherever a lavaland creature is able to spawn. They are the draconic guardians of the Necropolis.
|
||||
|
||||
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
|
||||
|
||||
Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast.
|
||||
It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs.
|
||||
The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage.
|
||||
- Sometimes it will chain these swooping attacks over and over, making swiftness a necessity.
|
||||
|
||||
When an ash drake dies, it leaves behind a chest that can contain four things:
|
||||
1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power
|
||||
2. A lava staff that allows its wielder to create lava
|
||||
3. A spellbook and wand of fireballs
|
||||
4. A bottle of dragon's blood with several effects, including turning its imbiber into a drake themselves.
|
||||
|
||||
When butchered, they leave behind diamonds, sinew, bone, and ash drake hide. Ash drake hide can be used to create a hooded cloak that protects its wearer from ash storms.
|
||||
|
||||
Difficulty: Medium
|
||||
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon
|
||||
name = "ash drake"
|
||||
desc = "Guardians of the necropolis."
|
||||
health = 2500
|
||||
maxHealth = 2500
|
||||
attacktext = "chomps"
|
||||
attack_sound = 'sound/misc/demon_attack1.ogg'
|
||||
icon_state = "dragon"
|
||||
icon_living = "dragon"
|
||||
icon_dead = "dragon_dead"
|
||||
friendly = "stares down"
|
||||
icon = 'icons/mob/lavaland/dragon.dmi'
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 40
|
||||
melee_damage_lower = 40
|
||||
melee_damage_upper = 40
|
||||
speed = 1
|
||||
move_to_delay = 10
|
||||
ranged = 1
|
||||
pixel_x = -16
|
||||
loot = list(/obj/structure/closet/crate/necropolis/dragon)
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
|
||||
var/swooping = 0
|
||||
var/swoop_cooldown = 0
|
||||
medal_type = MEDAL_PREFIX
|
||||
score_type = DRAKE_SCORE
|
||||
deathmessage = "collapses into a pile of bones, its flesh sloughing away."
|
||||
death_sound = 'sound/misc/demon_dies.ogg'
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/New()
|
||||
..()
|
||||
internal_gps = new/obj/item/device/gps/internal/dragon(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target)
|
||||
if(severity == 3)
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount)
|
||||
if(swooping)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget()
|
||||
if(!swooping)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/DestroySurroundings()
|
||||
if(!swooping)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/Move()
|
||||
if(!swooping)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/Goto(target, delay, minimum_distance)
|
||||
if(!swooping)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/Process_Spacemove(movement_dir = 0)
|
||||
return 1
|
||||
|
||||
/obj/effect/overlay/temp/fireball
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "fireball"
|
||||
name = "fireball"
|
||||
desc = "Get out of the way!"
|
||||
layer = 6
|
||||
randomdir = 0
|
||||
duration = 12
|
||||
pixel_z = 500
|
||||
|
||||
/obj/effect/overlay/temp/fireball/New(loc)
|
||||
..()
|
||||
animate(src, pixel_z = 0, time = 12)
|
||||
|
||||
/obj/effect/overlay/temp/target
|
||||
icon = 'icons/mob/actions.dmi'
|
||||
icon_state = "sniper_zoom"
|
||||
layer = MOB_LAYER - 0.1
|
||||
luminosity = 2
|
||||
duration = 12
|
||||
|
||||
/obj/effect/overlay/temp/dragon_swoop
|
||||
name = "certain death"
|
||||
desc = "Don't just stand there, move!"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "landing"
|
||||
layer = MOB_LAYER - 0.1
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
color = "#FF0000"
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/target/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/temp/target/New(loc)
|
||||
..()
|
||||
spawn(0)
|
||||
fall()
|
||||
|
||||
/obj/effect/overlay/temp/target/proc/fall()
|
||||
var/turf/T = get_turf(src)
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
PoolOrNew(/obj/effect/overlay/temp/fireball,T)
|
||||
sleep(12)
|
||||
explosion(T, 0, 0, 1, 0, 0, 0, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
|
||||
anger_modifier = Clamp(((maxHealth - health)/50),0,20)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
if(swooping)
|
||||
fire_rain()
|
||||
return
|
||||
|
||||
if(prob(15 + anger_modifier) && !client)
|
||||
if(health < maxHealth/2)
|
||||
spawn(0)
|
||||
swoop_attack(1)
|
||||
else
|
||||
fire_rain()
|
||||
|
||||
else if(prob(10+anger_modifier) && !client)
|
||||
if(health > maxHealth/2)
|
||||
spawn(0)
|
||||
swoop_attack(0)
|
||||
else
|
||||
spawn(0)
|
||||
triple_swoop(0)
|
||||
else
|
||||
fire_walls()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain()
|
||||
visible_message("<span class='boldwarning'>Fire rains from the sky!</span>")
|
||||
for(var/turf/turf in range(12,get_turf(src)))
|
||||
if(prob(10))
|
||||
PoolOrNew(/obj/effect/overlay/temp/target, turf)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls()
|
||||
playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
for(var/d in cardinal)
|
||||
spawn(0)
|
||||
fire_wall(d)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir)
|
||||
var/list/hit_things = list(src)
|
||||
var/turf/E = get_edge_target_turf(src, dir)
|
||||
var/range = 10
|
||||
var/turf/previousturf = get_turf(src)
|
||||
for(var/turf/J in getline(src,E))
|
||||
if(!range || !previousturf.CanAtmosPass(J))
|
||||
break
|
||||
range--
|
||||
PoolOrNew(/obj/effect/hotspot,J)
|
||||
J.hotspot_expose(700,50,1)
|
||||
for(var/mob/living/L in J.contents - hit_things)
|
||||
L.adjustFireLoss(20)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by the drake's fire breath!</span>")
|
||||
hit_things += L
|
||||
previousturf = J
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop()
|
||||
swoop_attack()
|
||||
swoop_attack()
|
||||
swoop_attack()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target)
|
||||
if(stat || swooping)
|
||||
return
|
||||
swoop_cooldown = world.time + 200
|
||||
var/atom/swoop_target
|
||||
if(manual_target)
|
||||
swoop_target = manual_target
|
||||
else
|
||||
swoop_target = target
|
||||
stop_automated_movement = TRUE
|
||||
swooping = 1
|
||||
density = 0
|
||||
icon_state = "swoop"
|
||||
visible_message("<span class='boldwarning'>[src] swoops up high!</span>")
|
||||
if(prob(50))
|
||||
animate(src, pixel_x = 500, pixel_z = 500, time = 10)
|
||||
else
|
||||
animate(src, pixel_x = -500, pixel_z = 500, time = 10)
|
||||
sleep(30)
|
||||
|
||||
var/turf/tturf
|
||||
if(fire_rain)
|
||||
fire_rain()
|
||||
|
||||
icon_state = "dragon"
|
||||
if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z)
|
||||
tturf = get_turf(swoop_target)
|
||||
else
|
||||
tturf = get_turf(src)
|
||||
forceMove(tturf)
|
||||
PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, tturf)
|
||||
animate(src, pixel_x = initial(pixel_x), pixel_z = 0, time = 10)
|
||||
sleep(10)
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1)
|
||||
for(var/mob/living/L in orange(1, src))
|
||||
if(L.stat)
|
||||
visible_message("<span class='warning'>[src] slams down on [L], crushing them!</span>")
|
||||
L.gib()
|
||||
else
|
||||
L.adjustBruteLoss(75)
|
||||
if(L && !qdeleted(L)) // Some mobs are deleted on death
|
||||
var/throw_dir = get_dir(src, L)
|
||||
if(L.loc == loc)
|
||||
throw_dir = pick(alldirs)
|
||||
var/throwtarget = get_edge_target_turf(src, throw_dir)
|
||||
L.throw_at_fast(throwtarget, 3)
|
||||
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
|
||||
|
||||
for(var/mob/M in range(7, src))
|
||||
shake_camera(M, 15, 1)
|
||||
|
||||
stop_automated_movement = FALSE
|
||||
swooping = 0
|
||||
density = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A)
|
||||
if(!istype(A))
|
||||
return
|
||||
if(swoop_cooldown >= world.time)
|
||||
to_chat(src, "<span class='warning'>You need to wait 20 seconds between swoop attacks!</span>")
|
||||
return
|
||||
swoop_attack(1, A)
|
||||
|
||||
/obj/item/device/gps/internal/dragon
|
||||
icon_state = null
|
||||
gpstag = "Fiery Signal"
|
||||
desc = "Here there be dragons."
|
||||
invisibility = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
name = "lesser ash drake"
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
faction = list("neutral")
|
||||
melee_damage_upper = 30
|
||||
melee_damage_lower = 30
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
||||
loot = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
|
||||
return
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
@@ -0,0 +1,219 @@
|
||||
#define MEDAL_PREFIX "Boss"
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna
|
||||
name = "boss of this gym"
|
||||
desc = "Attack the weak point for massive damage."
|
||||
health = 1000
|
||||
maxHealth = 1000
|
||||
a_intent = "harm"
|
||||
sentience_type = SENTIENCE_BOSS
|
||||
environment_smash = 3
|
||||
luminosity = 3
|
||||
faction = list("mining", "boss")
|
||||
weather_immunities = list("lava","ash")
|
||||
flying = 1
|
||||
robust_searching = 1
|
||||
ranged_ignores_vision = TRUE
|
||||
stat_attack = 2
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
aggro_vision_range = 18
|
||||
idle_vision_range = 5
|
||||
environment_target_typecache = list(
|
||||
/obj/machinery/door/window,
|
||||
/obj/structure/window,
|
||||
/obj/structure/closet,
|
||||
/obj/structure/table,
|
||||
/obj/structure/grille,
|
||||
/obj/structure/girder,
|
||||
/obj/structure/rack,
|
||||
/obj/structure/barricade,
|
||||
/obj/machinery/field,
|
||||
/obj/machinery/power/emitter)
|
||||
var/medal_type = MEDAL_PREFIX
|
||||
var/score_type = BOSS_SCORE
|
||||
var/elimination = 0
|
||||
var/anger_modifier = 0
|
||||
var/obj/item/device/gps/internal_gps
|
||||
anchored = TRUE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = MOB_LAYER + 0.5 //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
mouse_opacity = 2 // Easier to click on in melee, they're giant targets anyway
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Destroy()
|
||||
qdel(internal_gps)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
|
||||
if(health > 0)
|
||||
return
|
||||
else
|
||||
if(!admin_spawned)
|
||||
feedback_set_details("megafauna_kills","[initial(name)]")
|
||||
if(!elimination) //used so the achievment only occurs for the last legion to die.
|
||||
grant_achievement(medal_type,score_type)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/gib()
|
||||
if(health > 0)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dust()
|
||||
if(health > 0)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/AttackingTarget()
|
||||
..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat != DEAD)
|
||||
if(ranged && ranged_cooldown <= world.time)
|
||||
OpenFire()
|
||||
else
|
||||
devour(L)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
|
||||
if(!L)
|
||||
return
|
||||
visible_message(
|
||||
"<span class='danger'>[src] devours [L]!</span>",
|
||||
"<span class='userdanger'>You feast on [L], restoring your health!</span>")
|
||||
adjustBruteLoss(-L.maxHealth/2)
|
||||
L.gib()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target)
|
||||
switch (severity)
|
||||
if (1)
|
||||
adjustBruteLoss(250)
|
||||
|
||||
if (2)
|
||||
adjustBruteLoss(100)
|
||||
|
||||
if(3)
|
||||
adjustBruteLoss(50)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype,scoretype)
|
||||
|
||||
if(medal_type == "Boss") //Don't award medals if the medal type isn't set
|
||||
return
|
||||
|
||||
if(admin_spawned)
|
||||
return
|
||||
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
for(var/mob/living/L in view(7,src))
|
||||
if(L.stat)
|
||||
continue
|
||||
if(L.client)
|
||||
var/client/C = L.client
|
||||
var/suffixm = BOSS_KILL_MEDAL
|
||||
UnlockMedal("Boss [suffixm]",C)
|
||||
UnlockMedal("[medaltype] [suffixm]",C)
|
||||
SetScore(BOSS_SCORE,C,1)
|
||||
SetScore(score_type,C,1)
|
||||
|
||||
/proc/UnlockMedal(medal,client/player)
|
||||
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
spawn()
|
||||
var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
|
||||
else if (result)
|
||||
to_chat(player.mob, "<span class='greenannounce'><B>Achievement unlocked: [medal]!</B></span>")
|
||||
|
||||
|
||||
/proc/SetScore(score,client/player,increment,force)
|
||||
|
||||
if(!score || !player)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
spawn()
|
||||
var/list/oldscore = GetScore(score,player,1)
|
||||
|
||||
if(increment)
|
||||
if(!oldscore[score])
|
||||
oldscore[score] = 1
|
||||
else
|
||||
oldscore[score] = (text2num(oldscore[score]) + 1)
|
||||
else
|
||||
oldscore[score] = force
|
||||
|
||||
var/newscoreparam = list2params(oldscore)
|
||||
|
||||
var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass)
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
|
||||
|
||||
|
||||
/proc/GetScore(score,client/player,returnlist)
|
||||
|
||||
if(!score || !player)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
|
||||
var/scoreget = world.GetScores(player.ckey, score, global.medal_hub, global.medal_pass)
|
||||
if(isnull(scoreget))
|
||||
global.medals_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!")
|
||||
return
|
||||
|
||||
var/list/scoregetlist = params2list(scoreget)
|
||||
|
||||
if(returnlist)
|
||||
return scoregetlist
|
||||
else
|
||||
return scoregetlist[score]
|
||||
|
||||
|
||||
/proc/CheckMedal(medal,client/player)
|
||||
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
|
||||
var/result = world.GetMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
|
||||
else if (result)
|
||||
to_chat(player.mob, "[medal] is unlocked")
|
||||
|
||||
/proc/LockMedal(medal,client/player)
|
||||
|
||||
if(!player || !medal)
|
||||
return
|
||||
if(global.medal_hub && global.medal_pass && global.medals_enabled)
|
||||
|
||||
var/result = world.ClearMedal(medal, player, global.medal_hub, global.medal_pass)
|
||||
|
||||
if(isnull(result))
|
||||
global.medals_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]")
|
||||
message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
|
||||
else if (result)
|
||||
message_admins("Medal: [medal] removed for [player.ckey]")
|
||||
else
|
||||
message_admins("Medal: [medal] was not found for [player.ckey]. Unable to clear.")
|
||||
|
||||
|
||||
/proc/ClearScore(client/player)
|
||||
world.SetScores(player.ckey, "", global.medal_hub, global.medal_pass)
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
@@ -58,7 +58,7 @@
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged = 1
|
||||
ranged_message = "stares"
|
||||
ranged_cooldown_cap = 20
|
||||
ranged_cooldown_time = 30
|
||||
throw_message = "does nothing against the hard shell of"
|
||||
vision_range = 2
|
||||
speed = 3
|
||||
@@ -71,7 +71,6 @@
|
||||
a_intent = I_HARM
|
||||
speak_emote = list("chitters")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
ranged_cooldown_cap = 4
|
||||
aggro_vision_range = 9
|
||||
idle_vision_range = 2
|
||||
turns_per_move = 5
|
||||
@@ -231,7 +230,7 @@
|
||||
attack_sound = 'sound/weapons/pierce.ogg'
|
||||
throw_message = "falls right through the strange body of the"
|
||||
ranged_cooldown = 0
|
||||
ranged_cooldown_cap = 0
|
||||
ranged_cooldown_time = 20
|
||||
environment_smash = 0
|
||||
retreat_distance = 3
|
||||
minimum_distance = 3
|
||||
@@ -344,7 +343,7 @@
|
||||
move_to_delay = 40
|
||||
ranged = 1
|
||||
ranged_cooldown = 2 //By default, start the Goliath with his cooldown off so that people can run away quickly on first sight
|
||||
ranged_cooldown_cap = 8
|
||||
ranged_cooldown_time = 120
|
||||
friendly = "wails at"
|
||||
speak_emote = list("bellows")
|
||||
vision_range = 4
|
||||
@@ -368,7 +367,7 @@
|
||||
handle_preattack()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack()
|
||||
if(ranged_cooldown <= 2 && !pre_attack)
|
||||
if(ranged_cooldown <= world.time + ranged_cooldown_time * 0.25 && !pre_attack)
|
||||
pre_attack++
|
||||
if(!pre_attack || stat || AIStatus == AI_IDLE)
|
||||
return
|
||||
@@ -383,7 +382,7 @@
|
||||
if(get_dist(src, target) <= 7)//Screen range check, so you can't get tentacle'd offscreen
|
||||
visible_message("<span class='warning'>The [src.name] digs its tentacles under [target.name]!</span>")
|
||||
new /obj/effect/goliath_tentacle/original(tturf)
|
||||
ranged_cooldown = ranged_cooldown_cap
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
icon_state = icon_aggro
|
||||
pre_attack = 0
|
||||
return
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
return 0
|
||||
spawn_delay = world.time + spawn_time
|
||||
var/mob/living/simple_animal/L = new mob_type(src.loc)
|
||||
L.admin_spawned = admin_spawned //If we were admin spawned, lets have our children count as that as well.
|
||||
spawned_mobs += L
|
||||
L.nest = src
|
||||
L.faction = src.faction
|
||||
|
||||
@@ -440,20 +440,20 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM)
|
||||
lname = "<span class='name'>[lname]</span> "
|
||||
to_chat(M, "<span class='deadsay'>[lname][follow][message]</span>")
|
||||
|
||||
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/attack_not_jump = 0) //Easy notification of ghosts.
|
||||
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/action = NOTIFY_JUMP) //Easy notification of ghosts.
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(O.client)
|
||||
to_chat(O, "<span class='ghostalert'>[message][(enter_link) ? " [enter_link]" : ""]<span>")
|
||||
if(ghost_sound)
|
||||
O << sound(ghost_sound)
|
||||
if(source)
|
||||
var/obj/screen/alert/notify_jump/A = O.throw_alert("\ref[source]_notify_jump", /obj/screen/alert/notify_jump)
|
||||
var/obj/screen/alert/notify_action/A = O.throw_alert("\ref[source]_notify_action", /obj/screen/alert/notify_action)
|
||||
if(A)
|
||||
if(O.client.prefs && O.client.prefs.UI_style)
|
||||
A.icon = ui_style2icon(O.client.prefs.UI_style)
|
||||
A.desc = message
|
||||
A.attack_not_jump = attack_not_jump
|
||||
A.jump_target = source
|
||||
A.action = action
|
||||
A.target = source
|
||||
if(!alert_overlay)
|
||||
var/old_layer = source.layer
|
||||
var/old_plane = source.plane
|
||||
|
||||
@@ -19,8 +19,6 @@ and reset all of its vars to their default
|
||||
You can override your object's destroy to return QDEL_HINT_PUTINPOOL
|
||||
to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice)
|
||||
|
||||
For almost all pooling purposes, it is better to use the QDEL hint than to pool it directly with PlaceInPool
|
||||
|
||||
*/
|
||||
|
||||
var/global/list/GlobalPool = list()
|
||||
@@ -36,7 +34,7 @@ var/global/list/GlobalPool = list()
|
||||
//Or a list of arguments
|
||||
//Either way it gets passed to new
|
||||
|
||||
/proc/PoolOrNew(get_type,second_arg)
|
||||
/proc/PoolOrNew(var/get_type,var/second_arg)
|
||||
if(!get_type)
|
||||
return
|
||||
|
||||
@@ -50,7 +48,7 @@ var/global/list/GlobalPool = list()
|
||||
. = new get_type (second_arg)
|
||||
|
||||
|
||||
/proc/GetFromPool(get_type,second_arg)
|
||||
/proc/GetFromPool(var/get_type,var/second_arg)
|
||||
if(!get_type)
|
||||
return
|
||||
|
||||
@@ -62,6 +60,8 @@ var/global/list/GlobalPool = list()
|
||||
|
||||
var/datum/pooled = pop(GlobalPool[get_type])
|
||||
if(pooled)
|
||||
pooled.gcDestroyed = null
|
||||
|
||||
var/atom/movable/AM
|
||||
if(istype(pooled, /atom/movable))
|
||||
AM = pooled
|
||||
@@ -79,7 +79,7 @@ var/global/list/GlobalPool = list()
|
||||
return pooled
|
||||
|
||||
|
||||
/proc/PlaceInPool(datum/diver, destroy = 1)
|
||||
/proc/PlaceInPool(var/datum/diver, destroy = 1)
|
||||
if(!istype(diver))
|
||||
return
|
||||
|
||||
@@ -94,9 +94,11 @@ var/global/list/GlobalPool = list()
|
||||
if (destroy)
|
||||
diver.Destroy()
|
||||
|
||||
diver.gcDestroyed = 1
|
||||
|
||||
diver.ResetVars()
|
||||
|
||||
var/list/exclude = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type")
|
||||
var/list/exclude = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type", "gc_destroyed")
|
||||
var/list/pooledvariables = list()
|
||||
//thanks to clusterfack @ /vg/station for these two procs
|
||||
/datum/proc/createVariables()
|
||||
@@ -106,6 +108,9 @@ var/list/pooledvariables = list()
|
||||
for(var/key in vars)
|
||||
if(key in exclude)
|
||||
continue
|
||||
if(islist(vars[key]))
|
||||
pooledvariables[type][key] = list()
|
||||
else
|
||||
pooledvariables[type][key] = initial(vars[key])
|
||||
|
||||
/datum/proc/ResetVars()
|
||||
@@ -113,6 +118,9 @@ var/list/pooledvariables = list()
|
||||
createVariables(args)
|
||||
|
||||
for(var/key in pooledvariables[type])
|
||||
if (islist(pooledvariables[type][key]))
|
||||
vars[key] = list()
|
||||
else
|
||||
vars[key] = pooledvariables[type][key]
|
||||
|
||||
/atom/movable/ResetVars()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
var/image/alert_overlay = image('icons/effects/effects.dmi', "ghostalertsie")
|
||||
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, attack_not_jump = 1)
|
||||
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK)
|
||||
|
||||
narsie_spawn_animation()
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
src.energy = starting_energy
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
for(var/obj/machinery/power/singularity_beacon/singubeacon in world)
|
||||
if(singubeacon.active)
|
||||
target = singubeacon
|
||||
@@ -45,6 +46,7 @@
|
||||
|
||||
/obj/singularity/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
poi_list.Remove(src)
|
||||
singularities -= src
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
|
||||
/obj/machinery/power/supermatter_shard/New()
|
||||
. = ..()
|
||||
poi_list |= src
|
||||
radio = new(src)
|
||||
radio.listening = 0
|
||||
investigate_log("has been created.", "supermatter")
|
||||
@@ -71,8 +72,10 @@
|
||||
|
||||
/obj/machinery/power/supermatter_shard/Destroy()
|
||||
investigate_log("has been destroyed.", "supermatter")
|
||||
if(radio)
|
||||
qdel(radio)
|
||||
radio = null
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/supermatter_shard/proc/explode()
|
||||
|
||||
@@ -35,6 +35,8 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
|
||||
var/energy_to_raise = 32
|
||||
var/energy_to_lower = -20
|
||||
|
||||
|
||||
|
||||
/obj/singularity/energy_ball/Destroy()
|
||||
if(orbiting && istype(orbiting, /obj/singularity/energy_ball))
|
||||
var/obj/singularity/energy_ball/EB = orbiting
|
||||
@@ -45,6 +47,8 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
|
||||
var/obj/singularity/energy_ball/EB = ball
|
||||
qdel(EB)
|
||||
|
||||
poi_list.Remove(src)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/singularity/energy_ball/process()
|
||||
@@ -125,6 +129,7 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
|
||||
/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target)
|
||||
if(istype(target))
|
||||
target.orbiting_balls += src
|
||||
poi_list.Remove(src)
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
ammo_type = /obj/item/ammo_casing/magic/change
|
||||
icon_state = "staffofchange"
|
||||
item_state = "staffofchange"
|
||||
fire_sound = "sound/magic/Staff_Change.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/animate
|
||||
name = "staff of animation"
|
||||
@@ -15,6 +16,7 @@
|
||||
ammo_type = /obj/item/ammo_casing/magic/animate
|
||||
icon_state = "staffofanimation"
|
||||
item_state = "staffofanimation"
|
||||
fire_sound = "sound/magic/Staff_animation.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/healing
|
||||
name = "staff of healing"
|
||||
@@ -22,6 +24,7 @@
|
||||
ammo_type = /obj/item/ammo_casing/magic/heal
|
||||
icon_state = "staffofhealing"
|
||||
item_state = "staffofhealing"
|
||||
fire_sound = "sound/magic/Staff_Healing.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/healing/handle_suicide() //Stops people trying to commit suicide to heal themselves
|
||||
return
|
||||
@@ -35,6 +38,7 @@
|
||||
max_charges = 10
|
||||
recharge_rate = 2
|
||||
no_den_usage = 1
|
||||
fire_sound = "sound/magic/Staff_Chaos.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/door
|
||||
name = "staff of door creation"
|
||||
@@ -45,16 +49,17 @@
|
||||
max_charges = 10
|
||||
recharge_rate = 2
|
||||
no_den_usage = 1
|
||||
fire_sound = "sound/magic/Staff_Door.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/honk
|
||||
name = "staff of the honkmother"
|
||||
desc = "Honk"
|
||||
fire_sound = "sound/items/airhorn.ogg"
|
||||
ammo_type = /obj/item/ammo_casing/magic/honk
|
||||
icon_state = "honker"
|
||||
item_state = "honker"
|
||||
max_charges = 4
|
||||
recharge_rate = 8
|
||||
fire_sound = "sound/items/airhorn.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/staff/focus
|
||||
name = "mental focus"
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
/obj/item/weapon/gun/magic/wand/death
|
||||
name = "wand of death"
|
||||
desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail."
|
||||
fire_sound = "sound/magic/WandoDeath.ogg"
|
||||
ammo_type = /obj/item/ammo_casing/magic/death
|
||||
icon_state = "deathwand"
|
||||
max_charges = 3 //3, 2, 2, 1
|
||||
@@ -79,6 +80,7 @@
|
||||
name = "wand of resurrection"
|
||||
desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason."
|
||||
ammo_type = /obj/item/ammo_casing/magic/heal
|
||||
fire_sound = "sound/magic/Staff_Healing.ogg"
|
||||
icon_state = "revivewand"
|
||||
max_charges = 3 //3, 2, 2, 1
|
||||
|
||||
@@ -96,6 +98,7 @@
|
||||
name = "wand of polymorph"
|
||||
desc = "This wand is attuned to chaos and will radically alter the victim's form."
|
||||
ammo_type = /obj/item/ammo_casing/magic/change
|
||||
fire_sound = "sound/magic/Staff_Change.ogg"
|
||||
icon_state = "polywand"
|
||||
max_charges = 10 //10, 5, 5, 4
|
||||
|
||||
@@ -115,6 +118,7 @@
|
||||
icon_state = "telewand"
|
||||
max_charges = 10 //10, 5, 5, 4
|
||||
no_den_usage = 1
|
||||
fire_sound = "sound/magic/Wand_Teleport.ogg"
|
||||
|
||||
/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user)
|
||||
do_teleport(user, user, 10)
|
||||
@@ -132,6 +136,7 @@
|
||||
name = "wand of door creation"
|
||||
desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics."
|
||||
ammo_type = /obj/item/ammo_casing/magic/door
|
||||
fire_sound = "sound/magic/Staff_Door.ogg"
|
||||
icon_state = "doorwand"
|
||||
max_charges = 20 //20, 10, 10, 7
|
||||
|
||||
@@ -147,6 +152,7 @@
|
||||
/obj/item/weapon/gun/magic/wand/fireball
|
||||
name = "wand of fireball"
|
||||
desc = "This wand shoots scorching balls of fire that explode into destructive flames."
|
||||
fire_sound = "sound/magic/Fireball.ogg"
|
||||
ammo_type = /obj/item/ammo_casing/magic/fireball
|
||||
icon_state = "firewand"
|
||||
max_charges = 8 //8, 4, 4, 3
|
||||
|
||||
@@ -9,45 +9,39 @@
|
||||
vehicle_move_delay = 1
|
||||
var/static/image/atvcover = null
|
||||
|
||||
|
||||
/obj/vehicle/atv/New()
|
||||
..()
|
||||
if(!atvcover)
|
||||
atvcover = image("icons/vehicles/4wheeler.dmi", "4wheeler_north")
|
||||
atvcover.layer = MOB_LAYER + 0.1
|
||||
|
||||
|
||||
obj/vehicle/atv/post_buckle_mob(mob/living/M)
|
||||
/obj/vehicle/atv/post_buckle_mob(mob/living/M)
|
||||
if(buckled_mob)
|
||||
overlays += atvcover
|
||||
else
|
||||
overlays -= atvcover
|
||||
|
||||
|
||||
/obj/vehicle/atv/handle_vehicle_layer()
|
||||
if(dir == SOUTH)
|
||||
layer = MOB_LAYER+0.1
|
||||
else
|
||||
layer = OBJ_LAYER
|
||||
|
||||
|
||||
//TURRETS!
|
||||
/obj/vehicle/atv/turret
|
||||
var/obj/machinery/gun_turret/vehicle_turret/turret = null
|
||||
var/obj/machinery/porta_turret/syndicate/vehicle_turret/turret = null
|
||||
|
||||
|
||||
/obj/machinery/gun_turret/vehicle_turret
|
||||
/obj/machinery/porta_turret/syndicate/vehicle_turret
|
||||
name = "mounted turret"
|
||||
scan_range = 7
|
||||
emp_vulnerable = 1
|
||||
density = 0
|
||||
|
||||
|
||||
/obj/vehicle/atv/turret/New()
|
||||
..()
|
||||
turret = new(loc)
|
||||
//turret.base = src
|
||||
|
||||
|
||||
/obj/vehicle/atv/turret/handle_vehicle_layer()
|
||||
if(dir == SOUTH)
|
||||
layer = MOB_LAYER+0.1
|
||||
@@ -60,7 +54,6 @@ obj/vehicle/atv/post_buckle_mob(mob/living/M)
|
||||
else
|
||||
turret.layer = OBJ_LAYER
|
||||
|
||||
|
||||
/obj/vehicle/atv/turret/handle_vehicle_offsets()
|
||||
..()
|
||||
if(turret)
|
||||
|
||||
@@ -309,3 +309,10 @@ DISABLE_SPACE_RUINS
|
||||
# and still qualify for re-entering the round. Defaults to 30.
|
||||
# Setting this to 0 will disable the penalty period
|
||||
#ROUND_ABANDON_PENALTY_PERIOD 30
|
||||
|
||||
## Hub address for tracking stats
|
||||
## example: Hubmakerckey.Hubname
|
||||
#MEDAL_HUB_ADDRESS
|
||||
|
||||
## Password for the hub page
|
||||
#MEDAL_HUB_PASSWORD
|
||||
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 173 KiB |
BIN
icons/mob/lavaland/96x96megafauna.dmi
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
icons/mob/lavaland/dragon.dmi
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
icons/mob/lavaland/hierophant.dmi
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
icons/mob/lavaland/lavaland_monsters.dmi
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
icons/mob/lavaland/legion.dmi
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
icons/mob/lavaland/watcher.dmi
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 10 KiB |
BIN
icons/obj/lavaland/ash_flora.dmi
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 59 KiB |
BIN
icons/turf/floors/ash.dmi
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 9.1 KiB |
@@ -539,7 +539,6 @@
|
||||
#include "code\game\machinery\transformer.dm"
|
||||
#include "code\game\machinery\turntable.dm"
|
||||
#include "code\game\machinery\turret_control.dm"
|
||||
#include "code\game\machinery\turrets.dm"
|
||||
#include "code\game\machinery\vending.dm"
|
||||
#include "code\game\machinery\washing_machine.dm"
|
||||
#include "code\game\machinery\wishgranter.dm"
|
||||
@@ -1418,6 +1417,8 @@
|
||||
#include "code\modules\mining\laborcamp\laborminerals.dm"
|
||||
#include "code\modules\mining\laborcamp\laborshuttle.dm"
|
||||
#include "code\modules\mining\laborcamp\laborstacker.dm"
|
||||
#include "code\modules\mining\lavaland\ash_flora.dm"
|
||||
#include "code\modules\mining\lavaland\necropolis_chests.dm"
|
||||
#include "code\modules\mob\abilities.dm"
|
||||
#include "code\modules\mob\death.dm"
|
||||
#include "code\modules\mob\emote.dm"
|
||||
@@ -1654,6 +1655,8 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\winter_mobs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\megafauna\megafauna.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\fish.dm"
|
||||
|
||||