mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into is_tool
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level.
|
#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level.
|
||||||
|
|
||||||
// Invisibility constants.
|
// Invisibility constants. These should only be used for TRUE invisibility, AKA nothing living players touch
|
||||||
#define INVISIBILITY_LIGHTING 20
|
#define INVISIBILITY_LIGHTING 20
|
||||||
#define INVISIBILITY_LEVEL_ONE 35
|
#define INVISIBILITY_LEVEL_ONE 35
|
||||||
#define INVISIBILITY_LEVEL_TWO 45
|
#define INVISIBILITY_LEVEL_TWO 45
|
||||||
@@ -21,6 +21,9 @@
|
|||||||
#define SEE_INVISIBLE_MINIMUM 5
|
#define SEE_INVISIBLE_MINIMUM 5
|
||||||
#define INVISIBILITY_MAXIMUM 100
|
#define INVISIBILITY_MAXIMUM 100
|
||||||
|
|
||||||
|
// Pseudo-Invis, like Ninja, Ling, Etc.
|
||||||
|
#define EFFECTIVE_INVIS 50 // Below this, can't be examined, may as well be invisible to the game
|
||||||
|
|
||||||
// For the client FPS pref and anywhere else
|
// For the client FPS pref and anywhere else
|
||||||
#define MAX_CLIENT_FPS 200
|
#define MAX_CLIENT_FPS 200
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,9 @@
|
|||||||
#define O_LIVER "liver"
|
#define O_LIVER "liver"
|
||||||
#define O_KIDNEYS "kidneys"
|
#define O_KIDNEYS "kidneys"
|
||||||
#define O_APPENDIX "appendix"
|
#define O_APPENDIX "appendix"
|
||||||
|
#define O_VOICE "voicebox"
|
||||||
|
|
||||||
|
// Non-Standard organs
|
||||||
#define O_PLASMA "plasma vessel"
|
#define O_PLASMA "plasma vessel"
|
||||||
#define O_HIVE "hive node"
|
#define O_HIVE "hive node"
|
||||||
#define O_NUTRIENT "nutrient vessel"
|
#define O_NUTRIENT "nutrient vessel"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#define LANGUAGE_MINBUS "Minbus"
|
#define LANGUAGE_MINBUS "Minbus"
|
||||||
#define LANGUAGE_EVENT1 "Occursus"
|
#define LANGUAGE_EVENT1 "Occursus"
|
||||||
#define LANGUAGE_AKHANI "Akhani"
|
#define LANGUAGE_AKHANI "Akhani"
|
||||||
|
#define LANGUAGE_ALAI "Alai"
|
||||||
|
|
||||||
// Language flags.
|
// Language flags.
|
||||||
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
|
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
|||||||
#define INIT_ORDER_DEFAULT 0
|
#define INIT_ORDER_DEFAULT 0
|
||||||
#define INIT_ORDER_LIGHTING 0
|
#define INIT_ORDER_LIGHTING 0
|
||||||
#define INIT_ORDER_AIR -1
|
#define INIT_ORDER_AIR -1
|
||||||
|
#define INIT_ORDER_PLANETS -4
|
||||||
#define INIT_ORDER_OVERLAY -6
|
#define INIT_ORDER_OVERLAY -6
|
||||||
#define INIT_ORDER_XENOARCH -20
|
#define INIT_ORDER_XENOARCH -20
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
|||||||
#define FIRE_PRIORITY_AIRFLOW 30
|
#define FIRE_PRIORITY_AIRFLOW 30
|
||||||
#define FIRE_PRIORITY_AIR 35
|
#define FIRE_PRIORITY_AIR 35
|
||||||
#define FIRE_PRIORITY_DEFAULT 50
|
#define FIRE_PRIORITY_DEFAULT 50
|
||||||
|
#define FIRE_PRIORITY_PLANETS 75
|
||||||
#define FIRE_PRIORITY_MACHINES 100
|
#define FIRE_PRIORITY_MACHINES 100
|
||||||
#define FIRE_PRIORITY_OVERLAYS 500
|
#define FIRE_PRIORITY_OVERLAYS 500
|
||||||
|
|
||||||
|
|||||||
@@ -1073,47 +1073,7 @@ var/global/list/common_tools = list(
|
|||||||
if(istype(I, /obj/item/device/assembly/signaler))
|
if(istype(I, /obj/item/device/assembly/signaler))
|
||||||
return TRUE
|
return TRUE
|
||||||
return
|
return
|
||||||
/*
|
|
||||||
/proc/iswrench(O)
|
|
||||||
if(istype(O, /obj/item/weapon/wrench))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/iswelder(O)
|
|
||||||
if(istype(O, /obj/item/weapon/weldingtool))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/iscoil(O)
|
|
||||||
if(istype(O, /obj/item/stack/cable_coil))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/iswirecutter(O)
|
|
||||||
if(istype(O, /obj/item/weapon/tool/wirecutters))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/isscrewdriver(O)
|
|
||||||
if(istype(O, /obj/item/weapon/tool/screwdriver))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/ismultitool(O)
|
|
||||||
if(istype(O, /obj/item/device/multitool))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/iscrowbar(O)
|
|
||||||
if(istype(O, /obj/item/weapon/tool/crowbar))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/proc/iswire(O)
|
|
||||||
if(istype(O, /obj/item/stack/cable_coil))
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
*/
|
|
||||||
proc/is_hot(obj/item/W as obj)
|
proc/is_hot(obj/item/W as obj)
|
||||||
switch(W.type)
|
switch(W.type)
|
||||||
if(/obj/item/weapon/weldingtool)
|
if(/obj/item/weapon/weldingtool)
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
var/datum/controller/process/planet/planet_controller = null
|
|
||||||
|
|
||||||
/datum/controller/process/planet
|
|
||||||
var/list/planets = list()
|
|
||||||
var/list/z_to_planet = list()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/setup()
|
|
||||||
name = "planet controller"
|
|
||||||
planet_controller = src
|
|
||||||
schedule_interval = 1 MINUTE
|
|
||||||
|
|
||||||
var/list/planet_datums = typesof(/datum/planet) - /datum/planet
|
|
||||||
for(var/P in planet_datums)
|
|
||||||
var/datum/planet/NP = new P()
|
|
||||||
planets.Add(NP)
|
|
||||||
|
|
||||||
allocateTurfs()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/proc/allocateTurfs()
|
|
||||||
for(var/turf/simulated/OT in outdoor_turfs)
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
if(OT.z in P.expected_z_levels)
|
|
||||||
P.planet_floors |= OT
|
|
||||||
OT.vis_contents |= P.weather_holder.visuals
|
|
||||||
break
|
|
||||||
outdoor_turfs.Cut() //Why were you in there INCORRECTLY?
|
|
||||||
|
|
||||||
for(var/turf/unsimulated/wall/planetary/PW in planetary_walls)
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
if(PW.type == P.planetary_wall_type)
|
|
||||||
P.planet_walls |= PW
|
|
||||||
break
|
|
||||||
planetary_walls.Cut()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/proc/unallocateTurf(var/turf/T)
|
|
||||||
for(var/planet in planets)
|
|
||||||
var/datum/planet/P = planet
|
|
||||||
if(T.z in P.expected_z_levels)
|
|
||||||
P.planet_floors -= T
|
|
||||||
T.vis_contents -= P.weather_holder.visuals
|
|
||||||
|
|
||||||
/datum/controller/process/planet/doWork()
|
|
||||||
if(outdoor_turfs.len || planetary_walls.len)
|
|
||||||
allocateTurfs()
|
|
||||||
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
P.process(schedule_interval / 10)
|
|
||||||
SCHECK //Your process() really shouldn't take this long...
|
|
||||||
|
|
||||||
//Sun light needs changing
|
|
||||||
if(P.needs_work & PLANET_PROCESS_SUN)
|
|
||||||
P.needs_work &= ~PLANET_PROCESS_SUN
|
|
||||||
// Remove old value from corners
|
|
||||||
var/list/sunlit_corners = P.sunlit_corners
|
|
||||||
var/old_lum_r = -P.sun["lum_r"]
|
|
||||||
var/old_lum_g = -P.sun["lum_g"]
|
|
||||||
var/old_lum_b = -P.sun["lum_b"]
|
|
||||||
if(old_lum_r || old_lum_g || old_lum_b)
|
|
||||||
for(var/C in P.sunlit_corners)
|
|
||||||
var/datum/lighting_corner/LC = C
|
|
||||||
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
|
|
||||||
SCHECK
|
|
||||||
sunlit_corners.Cut()
|
|
||||||
|
|
||||||
// Calculate new values to apply
|
|
||||||
var/new_brightness = P.sun["brightness"]
|
|
||||||
var/new_color = P.sun["color"]
|
|
||||||
var/lum_r = new_brightness * GetRedPart (new_color) / 255
|
|
||||||
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
|
|
||||||
var/lum_b = new_brightness * GetBluePart (new_color) / 255
|
|
||||||
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
|
|
||||||
for(var/I in P.planet_floors)
|
|
||||||
var/turf/simulated/T = I
|
|
||||||
if(!T.lighting_corners_initialised)
|
|
||||||
T.generate_missing_corners()
|
|
||||||
for(var/C in T.get_corners())
|
|
||||||
var/datum/lighting_corner/LC = C
|
|
||||||
if(LC.update_gen != update_gen && LC.active)
|
|
||||||
sunlit_corners += LC
|
|
||||||
LC.update_gen = update_gen
|
|
||||||
LC.update_lumcount(lum_r, lum_g, lum_b)
|
|
||||||
SCHECK
|
|
||||||
update_gen--
|
|
||||||
P.sun["lum_r"] = lum_r
|
|
||||||
P.sun["lum_g"] = lum_g
|
|
||||||
P.sun["lum_b"] = lum_b
|
|
||||||
|
|
||||||
//Temperature needs updating
|
|
||||||
if(P.needs_work & PLANET_PROCESS_TEMP)
|
|
||||||
P.needs_work &= ~PLANET_PROCESS_TEMP
|
|
||||||
//Set new temperatures
|
|
||||||
for(var/W in P.planet_walls)
|
|
||||||
var/turf/unsimulated/wall/planetary/wall = W
|
|
||||||
wall.set_temperature(P.weather_holder.temperature)
|
|
||||||
SCHECK
|
|
||||||
@@ -1,6 +1,229 @@
|
|||||||
|
//Config stuff
|
||||||
|
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
|
||||||
|
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
|
||||||
|
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
|
||||||
|
#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
|
||||||
|
|
||||||
|
//Supply packs are in /code/datums/supplypacks
|
||||||
|
//Computers are in /code/game/machinery/computer/supply.dm
|
||||||
|
|
||||||
|
/datum/supply_order
|
||||||
|
var/ordernum
|
||||||
|
var/datum/supply_packs/object = null
|
||||||
|
var/orderedby = null
|
||||||
|
var/comment = null
|
||||||
|
|
||||||
|
/datum/exported_crate
|
||||||
|
var/name
|
||||||
|
var/value
|
||||||
|
|
||||||
|
|
||||||
|
var/datum/controller/supply/supply_controller = new()
|
||||||
|
|
||||||
|
/datum/controller/supply
|
||||||
|
//supply points
|
||||||
|
var/points = 50
|
||||||
|
var/points_per_process = 1.5
|
||||||
|
var/points_per_slip = 2
|
||||||
|
var/points_per_platinum = 5 // 5 points per sheet
|
||||||
|
var/points_per_phoron = 5
|
||||||
|
var/points_per_money = 0.02 // 1 point for $50
|
||||||
|
//control
|
||||||
|
var/ordernum
|
||||||
|
var/list/shoppinglist = list()
|
||||||
|
var/list/requestlist = list()
|
||||||
|
var/list/supply_packs = list()
|
||||||
|
var/list/exported_crates = list()
|
||||||
|
//shuttle movement
|
||||||
|
var/movetime = 1200
|
||||||
|
var/datum/shuttle/ferry/supply/shuttle
|
||||||
|
|
||||||
|
/datum/controller/supply/New()
|
||||||
|
ordernum = rand(1,9000)
|
||||||
|
|
||||||
|
for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
|
||||||
|
var/datum/supply_packs/P = new typepath()
|
||||||
|
supply_packs[P.name] = P
|
||||||
|
|
||||||
/datum/controller/process/supply/setup()
|
/datum/controller/process/supply/setup()
|
||||||
name = "supply controller"
|
name = "supply controller"
|
||||||
schedule_interval = 300 // every 30 seconds
|
schedule_interval = 300 // every 30 seconds
|
||||||
|
|
||||||
/datum/controller/process/supply/doWork()
|
/datum/controller/process/supply/doWork()
|
||||||
supply_controller.process()
|
supply_controller.process()
|
||||||
|
|
||||||
|
// Supply shuttle ticker - handles supply point regeneration
|
||||||
|
// This is called by the process scheduler every thirty seconds
|
||||||
|
/datum/controller/supply/proc/process()
|
||||||
|
points += points_per_process
|
||||||
|
|
||||||
|
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
|
||||||
|
/datum/controller/supply/proc/forbidden_atoms_check(atom/A)
|
||||||
|
if(isliving(A))
|
||||||
|
return 1
|
||||||
|
if(istype(A,/obj/item/weapon/disk/nuclear))
|
||||||
|
return 1
|
||||||
|
if(istype(A,/obj/machinery/nuclearbomb))
|
||||||
|
return 1
|
||||||
|
if(istype(A,/obj/item/device/radio/beacon))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
for(var/atom/B in A.contents)
|
||||||
|
if(.(B))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
//Selling
|
||||||
|
/datum/controller/supply/proc/sell()
|
||||||
|
var/area/area_shuttle = shuttle.get_location_area()
|
||||||
|
if(!area_shuttle)
|
||||||
|
return
|
||||||
|
|
||||||
|
callHook("sell_shuttle", list(area_shuttle));
|
||||||
|
|
||||||
|
var/phoron_count = 0
|
||||||
|
var/plat_count = 0
|
||||||
|
var/money_count = 0
|
||||||
|
|
||||||
|
exported_crates = list()
|
||||||
|
|
||||||
|
for(var/atom/movable/MA in area_shuttle)
|
||||||
|
if(MA.anchored)
|
||||||
|
continue
|
||||||
|
|
||||||
|
// Must be in a crate!
|
||||||
|
if(istype(MA,/obj/structure/closet/crate))
|
||||||
|
var/oldpoints = points
|
||||||
|
var/oldphoron = phoron_count
|
||||||
|
var/oldplatinum = plat_count
|
||||||
|
var/oldmoney = money_count
|
||||||
|
|
||||||
|
var/obj/structure/closet/crate/CR = MA
|
||||||
|
callHook("sell_crate", list(CR, area_shuttle))
|
||||||
|
|
||||||
|
points += CR.points_per_crate
|
||||||
|
var/find_slip = 1
|
||||||
|
|
||||||
|
for(var/atom/A in CR)
|
||||||
|
// Sell manifests
|
||||||
|
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
|
||||||
|
var/obj/item/weapon/paper/manifest/slip = A
|
||||||
|
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
|
||||||
|
points += points_per_slip
|
||||||
|
find_slip = 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
// Sell phoron and platinum
|
||||||
|
if(istype(A, /obj/item/stack))
|
||||||
|
var/obj/item/stack/P = A
|
||||||
|
switch(P.get_material_name())
|
||||||
|
if("phoron")
|
||||||
|
phoron_count += P.get_amount()
|
||||||
|
if("platinum")
|
||||||
|
plat_count += P.get_amount()
|
||||||
|
|
||||||
|
//Sell spacebucks
|
||||||
|
if(istype(A, /obj/item/weapon/spacecash))
|
||||||
|
var/obj/item/weapon/spacecash/cashmoney = A
|
||||||
|
money_count += cashmoney.worth
|
||||||
|
|
||||||
|
var/datum/exported_crate/EC = new /datum/exported_crate()
|
||||||
|
EC.name = CR.name
|
||||||
|
EC.value = points - oldpoints
|
||||||
|
EC.value += (phoron_count - oldphoron) * points_per_phoron
|
||||||
|
EC.value += (plat_count - oldplatinum) * points_per_platinum
|
||||||
|
EC.value += (money_count - oldmoney) * points_per_money
|
||||||
|
exported_crates += EC
|
||||||
|
|
||||||
|
qdel(MA)
|
||||||
|
|
||||||
|
points += phoron_count * points_per_phoron
|
||||||
|
points += plat_count * points_per_platinum
|
||||||
|
points += money_count * points_per_money
|
||||||
|
|
||||||
|
//Buying
|
||||||
|
/datum/controller/supply/proc/buy()
|
||||||
|
if(!shoppinglist.len)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/orderedamount = shoppinglist.len
|
||||||
|
|
||||||
|
var/area/area_shuttle = shuttle.get_location_area()
|
||||||
|
if(!area_shuttle)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/clear_turfs = list()
|
||||||
|
|
||||||
|
for(var/turf/T in area_shuttle)
|
||||||
|
if(T.density)
|
||||||
|
continue
|
||||||
|
var/contcount
|
||||||
|
for(var/atom/A in T.contents)
|
||||||
|
if(!A.simulated)
|
||||||
|
continue
|
||||||
|
contcount++
|
||||||
|
if(contcount)
|
||||||
|
continue
|
||||||
|
clear_turfs += T
|
||||||
|
|
||||||
|
for(var/S in shoppinglist)
|
||||||
|
if(!clear_turfs.len)
|
||||||
|
break
|
||||||
|
|
||||||
|
var/i = rand(1,clear_turfs.len)
|
||||||
|
var/turf/pickedloc = clear_turfs[i]
|
||||||
|
clear_turfs.Cut(i,i+1)
|
||||||
|
shoppinglist -= S
|
||||||
|
|
||||||
|
var/datum/supply_order/SO = S
|
||||||
|
var/datum/supply_packs/SP = SO.object
|
||||||
|
|
||||||
|
var/obj/A = new SP.containertype(pickedloc)
|
||||||
|
A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
|
||||||
|
|
||||||
|
//supply manifest generation begin
|
||||||
|
var/obj/item/weapon/paper/manifest/slip
|
||||||
|
if(!SP.contraband)
|
||||||
|
slip = new /obj/item/weapon/paper/manifest(A)
|
||||||
|
slip.is_copy = 0
|
||||||
|
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
|
||||||
|
slip.info +="Order #[SO.ordernum]<br>"
|
||||||
|
slip.info +="Destination: [station_name()]<br>"
|
||||||
|
slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT<br>"
|
||||||
|
slip.info +="CONTENTS:<br><ul>"
|
||||||
|
|
||||||
|
//spawn the stuff, finish generating the manifest while you're at it
|
||||||
|
if(SP.access)
|
||||||
|
if(isnum(SP.access))
|
||||||
|
A.req_access = list(SP.access)
|
||||||
|
else if(islist(SP.access))
|
||||||
|
var/list/L = SP.access // access var is a plain var, we need a list
|
||||||
|
A.req_access = L.Copy()
|
||||||
|
else
|
||||||
|
log_debug("<span class='danger'>Supply pack with invalid access restriction [SP.access] encountered!</span>")
|
||||||
|
|
||||||
|
var/list/contains
|
||||||
|
if(istype(SP,/datum/supply_packs/randomised))
|
||||||
|
var/datum/supply_packs/randomised/SPR = SP
|
||||||
|
contains = list()
|
||||||
|
if(SPR.contains.len)
|
||||||
|
for(var/j=1,j<=SPR.num_contained,j++)
|
||||||
|
contains += pick(SPR.contains)
|
||||||
|
else
|
||||||
|
contains = SP.contains
|
||||||
|
|
||||||
|
for(var/typepath in contains)
|
||||||
|
if(!typepath)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/number_of_items = max(1, contains[typepath])
|
||||||
|
for(var/j = 1 to number_of_items)
|
||||||
|
var/atom/B2 = new typepath(A)
|
||||||
|
if(slip)
|
||||||
|
slip.info += "<li>[B2.name]</li>" //add the item to the manifest
|
||||||
|
|
||||||
|
//manifest finalisation
|
||||||
|
if(slip)
|
||||||
|
slip.info += "</ul><br>"
|
||||||
|
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>"
|
||||||
|
|
||||||
|
return
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ var/list/gamemode_cache = list()
|
|||||||
var/humans_need_surnames = 0
|
var/humans_need_surnames = 0
|
||||||
var/allow_random_events = 0 // enables random events mid-round when set to 1
|
var/allow_random_events = 0 // enables random events mid-round when set to 1
|
||||||
var/allow_ai = 1 // allow ai job
|
var/allow_ai = 1 // allow ai job
|
||||||
|
var/allow_ai_drones = 0 // allow ai controlled drones
|
||||||
var/hostedby = null
|
var/hostedby = null
|
||||||
var/respawn = 1
|
var/respawn = 1
|
||||||
var/guest_jobban = 1
|
var/guest_jobban = 1
|
||||||
@@ -400,6 +401,9 @@ var/list/gamemode_cache = list()
|
|||||||
if ("allow_ai")
|
if ("allow_ai")
|
||||||
config.allow_ai = 1
|
config.allow_ai = 1
|
||||||
|
|
||||||
|
if ("allow_ai_drones")
|
||||||
|
config.allow_ai_drones = 1
|
||||||
|
|
||||||
// if ("authentication")
|
// if ("authentication")
|
||||||
// config.enable_authentication = 1
|
// config.enable_authentication = 1
|
||||||
|
|
||||||
|
|||||||
187
code/controllers/subsystems/planets.dm
Normal file
187
code/controllers/subsystems/planets.dm
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
SUBSYSTEM_DEF(planets)
|
||||||
|
name = "Planets"
|
||||||
|
init_order = INIT_ORDER_PLANETS
|
||||||
|
priority = FIRE_PRIORITY_PLANETS
|
||||||
|
wait = 2 SECONDS
|
||||||
|
flags = SS_BACKGROUND
|
||||||
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||||
|
|
||||||
|
var/list/new_outdoor_turfs = list()
|
||||||
|
var/list/new_outdoor_walls = list()
|
||||||
|
|
||||||
|
var/list/planets = list()
|
||||||
|
var/list/z_to_planet = list()
|
||||||
|
|
||||||
|
var/list/currentrun = list()
|
||||||
|
|
||||||
|
var/list/needs_sun_update = list()
|
||||||
|
var/list/needs_temp_update = list()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/Initialize(timeofday)
|
||||||
|
admin_notice("<span class='danger'>Initializing planetary weather.</span>", R_DEBUG)
|
||||||
|
createPlanets()
|
||||||
|
allocateTurfs(TRUE)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/createPlanets()
|
||||||
|
var/list/planet_datums = subtypesof(/datum/planet)
|
||||||
|
for(var/P in planet_datums)
|
||||||
|
var/datum/planet/NP = new P()
|
||||||
|
planets.Add(NP)
|
||||||
|
for(var/Z in NP.expected_z_levels)
|
||||||
|
if(Z > z_to_planet.len)
|
||||||
|
z_to_planet.len = Z
|
||||||
|
if(z_to_planet[Z])
|
||||||
|
admin_notice("<span class='danger'>Z[Z] is shared by more than one planet!</span>", R_DEBUG)
|
||||||
|
continue
|
||||||
|
z_to_planet[Z] = NP
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/addTurf(var/turf/T,var/is_edge)
|
||||||
|
if(is_edge)
|
||||||
|
new_outdoor_walls |= T
|
||||||
|
else
|
||||||
|
new_outdoor_turfs |= T
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge)
|
||||||
|
if(is_edge)
|
||||||
|
new_outdoor_walls -= T
|
||||||
|
else
|
||||||
|
new_outdoor_turfs -= T
|
||||||
|
|
||||||
|
if(z_to_planet.len >= T.z)
|
||||||
|
var/datum/planet/P = z_to_planet[T.z]
|
||||||
|
if(!P)
|
||||||
|
return
|
||||||
|
if(is_edge)
|
||||||
|
P.planet_floors -= T
|
||||||
|
else
|
||||||
|
P.planet_walls -= T
|
||||||
|
T.vis_contents -= P.weather_holder.visuals
|
||||||
|
T.vis_contents -= P.weather_holder.special_visuals
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/allocateTurfs(var/initial = FALSE)
|
||||||
|
var/list/currentlist = new_outdoor_turfs
|
||||||
|
while(currentlist.len)
|
||||||
|
var/turf/simulated/OT = currentlist[currentlist.len]
|
||||||
|
currentlist.len--
|
||||||
|
if(istype(OT) && OT.outdoors && z_to_planet.len >= OT.z && z_to_planet[OT.z])
|
||||||
|
var/datum/planet/P = z_to_planet[OT.z]
|
||||||
|
P.planet_floors |= OT
|
||||||
|
OT.vis_contents |= P.weather_holder.visuals
|
||||||
|
OT.vis_contents |= P.weather_holder.special_visuals
|
||||||
|
if(!initial && MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
currentlist = new_outdoor_walls
|
||||||
|
while(currentlist.len)
|
||||||
|
var/turf/unsimulated/wall/planetary/PW = currentlist[currentlist.len]
|
||||||
|
currentlist.len--
|
||||||
|
if(istype(PW) && z_to_planet.len >= PW.z && z_to_planet[PW.z])
|
||||||
|
var/datum/planet/P = z_to_planet[PW.z]
|
||||||
|
P.planet_walls |= PW
|
||||||
|
if(!initial && MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/unallocateTurf(var/turf/simulated/T)
|
||||||
|
if(istype(T) && z_to_planet[T.z])
|
||||||
|
var/datum/planet/P = z_to_planet[T.z]
|
||||||
|
P.planet_floors -= T
|
||||||
|
T.vis_contents -= P.weather_holder.visuals
|
||||||
|
T.vis_contents -= P.weather_holder.special_visuals
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/fire(resumed = 0)
|
||||||
|
if(new_outdoor_turfs.len || new_outdoor_walls.len)
|
||||||
|
allocateTurfs()
|
||||||
|
|
||||||
|
if(!resumed)
|
||||||
|
src.currentrun = planets.Copy()
|
||||||
|
|
||||||
|
var/list/needs_sun_update = src.needs_sun_update
|
||||||
|
while(needs_sun_update.len)
|
||||||
|
var/datum/planet/P = needs_sun_update[needs_sun_update.len]
|
||||||
|
needs_sun_update.len--
|
||||||
|
updateSunlight(P)
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/needs_temp_update = src.needs_temp_update
|
||||||
|
while(needs_temp_update.len)
|
||||||
|
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
|
||||||
|
needs_temp_update.len--
|
||||||
|
updateTemp(P)
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/currentrun = src.currentrun
|
||||||
|
while(currentrun.len)
|
||||||
|
var/datum/planet/P = currentrun[currentrun.len]
|
||||||
|
currentrun.len--
|
||||||
|
|
||||||
|
P.process(last_fire)
|
||||||
|
|
||||||
|
//Sun light needs changing
|
||||||
|
if(P.needs_work & PLANET_PROCESS_SUN)
|
||||||
|
P.needs_work &= ~PLANET_PROCESS_SUN
|
||||||
|
needs_sun_update |= P
|
||||||
|
|
||||||
|
//Temperature needs updating
|
||||||
|
if(P.needs_work & PLANET_PROCESS_TEMP)
|
||||||
|
P.needs_work &= ~PLANET_PROCESS_TEMP
|
||||||
|
needs_temp_update |= P
|
||||||
|
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P)
|
||||||
|
// Remove old value from corners
|
||||||
|
var/list/sunlit_corners = P.sunlit_corners
|
||||||
|
var/old_lum_r = -P.sun["lum_r"]
|
||||||
|
var/old_lum_g = -P.sun["lum_g"]
|
||||||
|
var/old_lum_b = -P.sun["lum_b"]
|
||||||
|
if(old_lum_r || old_lum_g || old_lum_b)
|
||||||
|
for(var/C in sunlit_corners)
|
||||||
|
var/datum/lighting_corner/LC = C
|
||||||
|
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
|
||||||
|
CHECK_TICK
|
||||||
|
sunlit_corners.Cut()
|
||||||
|
|
||||||
|
// Calculate new values to apply
|
||||||
|
var/new_brightness = P.sun["brightness"]
|
||||||
|
var/new_color = P.sun["color"]
|
||||||
|
var/lum_r = new_brightness * GetRedPart (new_color) / 255
|
||||||
|
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
|
||||||
|
var/lum_b = new_brightness * GetBluePart (new_color) / 255
|
||||||
|
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
|
||||||
|
for(var/I in P.planet_floors)
|
||||||
|
var/turf/simulated/T = I
|
||||||
|
if(!T.lighting_corners_initialised)
|
||||||
|
T.generate_missing_corners()
|
||||||
|
for(var/C in T.get_corners())
|
||||||
|
var/datum/lighting_corner/LC = C
|
||||||
|
if(LC.update_gen != update_gen && LC.active)
|
||||||
|
sunlit_corners += LC
|
||||||
|
LC.update_gen = update_gen
|
||||||
|
LC.update_lumcount(lum_r, lum_g, lum_b)
|
||||||
|
CHECK_TICK
|
||||||
|
update_gen--
|
||||||
|
P.sun["lum_r"] = lum_r
|
||||||
|
P.sun["lum_g"] = lum_g
|
||||||
|
P.sun["lum_b"] = lum_b
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P)
|
||||||
|
//Set new temperatures
|
||||||
|
for(var/W in P.planet_walls)
|
||||||
|
var/turf/unsimulated/wall/planetary/wall = W
|
||||||
|
wall.set_temperature(P.weather_holder.temperature)
|
||||||
|
CHECK_TICK
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/weatherDisco()
|
||||||
|
var/count = 100000
|
||||||
|
while(count > 0)
|
||||||
|
count--
|
||||||
|
for(var/planet in planets)
|
||||||
|
var/datum/planet/P = planet
|
||||||
|
if(P.weather_holder)
|
||||||
|
P.weather_holder.change_weather(pick(P.weather_holder.allowed_weather_types))
|
||||||
|
sleep(3)
|
||||||
@@ -133,8 +133,5 @@
|
|||||||
if("Vote")
|
if("Vote")
|
||||||
debug_variables(vote)
|
debug_variables(vote)
|
||||||
feedback_add_details("admin_verb", "DVote")
|
feedback_add_details("admin_verb", "DVote")
|
||||||
if("Planets")
|
|
||||||
debug_variables(planet_controller)
|
|
||||||
feedback_add_details("admin_verb", "DPlanets")
|
|
||||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -84,10 +84,8 @@
|
|||||||
|
|
||||||
for(var/mob/living/silicon/robot/robot in mob_list)
|
for(var/mob/living/silicon/robot/robot in mob_list)
|
||||||
// No combat/syndicate cyborgs, no drones.
|
// No combat/syndicate cyborgs, no drones.
|
||||||
if(robot.module && robot.module.hide_on_manifest)
|
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
|
||||||
continue
|
bot[robot.name] = "[robot.modtype] [robot.braintype]"
|
||||||
|
|
||||||
bot[robot.name] = "[robot.modtype] [robot.braintype]"
|
|
||||||
|
|
||||||
|
|
||||||
if(heads.len > 0)
|
if(heads.len > 0)
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ var/decl/observ/turf_changed/turf_changed_event = new()
|
|||||||
* Turf Changed Handling *
|
* Turf Changed Handling *
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
/turf/ChangeTurf()
|
/turf/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
|
||||||
var/old_density = density
|
var/old_density = density
|
||||||
var/old_opacity = opacity
|
var/old_opacity = opacity
|
||||||
. = ..()
|
. = ..(N, tell_universe, force_lighting_update, preserve_outdoors)
|
||||||
if(.)
|
if(.)
|
||||||
turf_changed_event.raise_event(src, old_density, density, old_opacity, opacity)
|
turf_changed_event.raise_event(src, old_density, density, old_opacity, opacity)
|
||||||
@@ -144,7 +144,7 @@ var/global/list/PDA_Manifest = list()
|
|||||||
|
|
||||||
for(var/mob/living/silicon/robot/robot in mob_list)
|
for(var/mob/living/silicon/robot/robot in mob_list)
|
||||||
// No combat/syndicate cyborgs, no drones.
|
// No combat/syndicate cyborgs, no drones.
|
||||||
if(robot.module && robot.module.hide_on_manifest)
|
if(!robot.scrambledcodes && !(robot.module && robot.module.hide_on_manifest))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
|
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
|
||||||
|
|||||||
@@ -79,7 +79,9 @@
|
|||||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||||
rules aside from those without explicit exceptions apply to antagonists.</b>"
|
rules aside from those without explicit exceptions apply to antagonists.</b>"
|
||||||
|
|
||||||
var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
|
// var/can_use_aooc = TRUE // If true, will be given the AOOC verb, along with the ability to use it.
|
||||||
|
var/can_hear_aooc = TRUE // If FALSE, the antag can neither speak nor hear AOOC. If TRUE, they can at least hear it.
|
||||||
|
var/can_speak_aooc = TRUE // If TRUE, the antag can freely spean in AOOC.
|
||||||
|
|
||||||
/datum/antagonist/New()
|
/datum/antagonist/New()
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
and it otherwise has no bearing on your round.</span>"
|
and it otherwise has no bearing on your round.</span>"
|
||||||
player.current.verbs |= /mob/living/proc/write_ambition
|
player.current.verbs |= /mob/living/proc/write_ambition
|
||||||
|
|
||||||
if(can_use_aooc)
|
if(can_speak_aooc)
|
||||||
player.current.client.verbs += /client/proc/aooc
|
player.current.client.verbs += /client/proc/aooc
|
||||||
|
|
||||||
// Handle only adding a mind and not bothering with gear etc.
|
// Handle only adding a mind and not bothering with gear etc.
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ var/datum/antagonist/ert/ert
|
|||||||
initial_spawn_req = 5
|
initial_spawn_req = 5
|
||||||
initial_spawn_target = 7
|
initial_spawn_target = 7
|
||||||
|
|
||||||
can_use_aooc = FALSE // They're the good guys.
|
can_hear_aooc = FALSE // They're the good guys.
|
||||||
|
can_speak_aooc = FALSE // Just in case the above var bugs, or gets touched.
|
||||||
|
|
||||||
/datum/antagonist/ert/create_default(var/mob/source)
|
/datum/antagonist/ert/create_default(var/mob/source)
|
||||||
var/mob/living/carbon/human/M = ..()
|
var/mob/living/carbon/human/M = ..()
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ var/datum/antagonist/trader/traders
|
|||||||
initial_spawn_req = 5
|
initial_spawn_req = 5
|
||||||
initial_spawn_target = 7
|
initial_spawn_target = 7
|
||||||
|
|
||||||
can_use_aooc = FALSE // They're not real antags.
|
can_speak_aooc = FALSE // They're not real antags.
|
||||||
|
|
||||||
/datum/antagonist/trader/create_default(var/mob/source)
|
/datum/antagonist/trader/create_default(var/mob/source)
|
||||||
var/mob/living/carbon/human/M = ..()
|
var/mob/living/carbon/human/M = ..()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ var/datum/antagonist/traitor/infiltrator/infiltrators
|
|||||||
welcome_text = "To speak on your team's private channel, use :t."
|
welcome_text = "To speak on your team's private channel, use :t."
|
||||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||||
|
can_speak_aooc = TRUE
|
||||||
|
|
||||||
/datum/antagonist/traitor/infiltrator/New()
|
/datum/antagonist/traitor/infiltrator/New()
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ var/datum/antagonist/renegade/renegades
|
|||||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||||
rules aside from those without explicit exceptions apply to antagonists.</b>"
|
rules aside from those without explicit exceptions apply to antagonists.</b>"
|
||||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||||
can_use_aooc = FALSE
|
can_speak_aooc = FALSE // They aren't 'true' antags, but they still need to hear blanket antag instructions
|
||||||
|
|
||||||
hard_cap = 8
|
hard_cap = 8
|
||||||
hard_cap_round = 12
|
hard_cap_round = 12
|
||||||
@@ -61,8 +61,6 @@ var/datum/antagonist/renegade/renegades
|
|||||||
list(/obj/item/weapon/gun/projectile/luger,/obj/item/weapon/gun/projectile/luger/brown)
|
list(/obj/item/weapon/gun/projectile/luger,/obj/item/weapon/gun/projectile/luger/brown)
|
||||||
)
|
)
|
||||||
|
|
||||||
can_use_aooc = FALSE // They aren't 'true' antags.
|
|
||||||
|
|
||||||
/datum/antagonist/renegade/New()
|
/datum/antagonist/renegade/New()
|
||||||
..()
|
..()
|
||||||
renegades = src
|
renegades = src
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ var/datum/antagonist/thug/thugs
|
|||||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||||
rules aside from those with explicit exceptions apply to antagonists.</b>"
|
rules aside from those with explicit exceptions apply to antagonists.</b>"
|
||||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||||
can_use_aooc = FALSE
|
can_speak_aooc = FALSE
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ var/datum/antagonist/traitor/traitors
|
|||||||
id = MODE_TRAITOR
|
id = MODE_TRAITOR
|
||||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||||
can_use_aooc = FALSE
|
can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly.
|
||||||
|
|
||||||
/datum/antagonist/traitor/auto
|
/datum/antagonist/traitor/auto
|
||||||
id = MODE_AUTOTRAITOR
|
id = MODE_AUTOTRAITOR
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
|||||||
ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg','sound/ambience/serspaceamb1.ogg')
|
ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg','sound/ambience/serspaceamb1.ogg')
|
||||||
base_turf = /turf/space
|
base_turf = /turf/space
|
||||||
|
|
||||||
area/space/atmosalert()
|
/area/space/atmosalert()
|
||||||
return
|
return
|
||||||
|
|
||||||
/area/space/fire_alert()
|
/area/space/fire_alert()
|
||||||
@@ -451,20 +451,6 @@ area/space/atmosalert()
|
|||||||
icon_state = "cave"
|
icon_state = "cave"
|
||||||
sound_env = SMALL_ENCLOSED
|
sound_env = SMALL_ENCLOSED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/area/planet/clown
|
/area/planet/clown
|
||||||
name = "\improper Clown Planet"
|
name = "\improper Clown Planet"
|
||||||
icon_state = "honk"
|
icon_state = "honk"
|
||||||
@@ -906,9 +892,6 @@ area/space/atmosalert()
|
|||||||
/area/maintenance/substation/security // Security, Brig, Permabrig, etc.
|
/area/maintenance/substation/security // Security, Brig, Permabrig, etc.
|
||||||
name = "Security Substation"
|
name = "Security Substation"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Hallway
|
//Hallway
|
||||||
|
|
||||||
/area/hallway/primary/
|
/area/hallway/primary/
|
||||||
@@ -1115,7 +1098,7 @@ area/space/atmosalert()
|
|||||||
name = "\improper Research Server Room"
|
name = "\improper Research Server Room"
|
||||||
icon_state = "server"
|
icon_state = "server"
|
||||||
|
|
||||||
//Crew
|
//Civilian
|
||||||
|
|
||||||
/area/crew_quarters
|
/area/crew_quarters
|
||||||
name = "\improper Dormitories"
|
name = "\improper Dormitories"
|
||||||
@@ -1978,6 +1961,24 @@ area/space/atmosalert()
|
|||||||
name = "\improper Vacant Office"
|
name = "\improper Vacant Office"
|
||||||
icon_state = "security"
|
icon_state = "security"
|
||||||
|
|
||||||
|
/area/janitor/
|
||||||
|
name = "\improper Custodial Closet"
|
||||||
|
icon_state = "janitor"
|
||||||
|
|
||||||
|
/area/hydroponics
|
||||||
|
name = "\improper Hydroponics"
|
||||||
|
icon_state = "hydro"
|
||||||
|
|
||||||
|
/area/hydroponics/cafegarden
|
||||||
|
name = "\improper Cafeteria Garden"
|
||||||
|
icon_state = "cafe_garden"
|
||||||
|
|
||||||
|
/area/hydroponics/garden
|
||||||
|
name = "\improper Garden"
|
||||||
|
icon_state = "garden"
|
||||||
|
|
||||||
|
// SUPPLY
|
||||||
|
|
||||||
/area/quartermaster
|
/area/quartermaster
|
||||||
name = "\improper Quartermasters"
|
name = "\improper Quartermasters"
|
||||||
icon_state = "quart"
|
icon_state = "quart"
|
||||||
@@ -2011,23 +2012,20 @@ area/space/atmosalert()
|
|||||||
name = "\improper Cargo Mining Dock"
|
name = "\improper Cargo Mining Dock"
|
||||||
icon_state = "mining"
|
icon_state = "mining"
|
||||||
|
|
||||||
/area/janitor/
|
/area/supply/station
|
||||||
name = "\improper Custodial Closet"
|
name = "Supply Shuttle"
|
||||||
icon_state = "janitor"
|
icon_state = "shuttle3"
|
||||||
|
requires_power = 0
|
||||||
|
base_turf = /turf/space
|
||||||
|
|
||||||
/area/hydroponics
|
/area/supply/dock
|
||||||
name = "\improper Hydroponics"
|
name = "Supply Shuttle"
|
||||||
icon_state = "hydro"
|
icon_state = "shuttle3"
|
||||||
|
requires_power = 0
|
||||||
|
base_turf = /turf/space
|
||||||
|
|
||||||
/area/hydroponics/cafegarden
|
// SCIENCE
|
||||||
name = "\improper Cafeteria Garden"
|
|
||||||
icon_state = "cafe_garden"
|
|
||||||
|
|
||||||
/area/hydroponics/garden
|
|
||||||
name = "\improper Garden"
|
|
||||||
icon_state = "garden"
|
|
||||||
|
|
||||||
//rnd (Research and Development
|
|
||||||
/area/rnd/research
|
/area/rnd/research
|
||||||
name = "\improper Research and Development"
|
name = "\improper Research and Development"
|
||||||
icon_state = "research"
|
icon_state = "research"
|
||||||
|
|||||||
@@ -5,12 +5,14 @@
|
|||||||
var/list/languages
|
var/list/languages
|
||||||
var/identifying_gender
|
var/identifying_gender
|
||||||
var/list/flavour_texts
|
var/list/flavour_texts
|
||||||
|
var/list/genMods
|
||||||
|
|
||||||
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour)
|
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages, var/newIdentifying_Gender, var/list/newFlavour, var/list/newGenMods)
|
||||||
..()
|
..()
|
||||||
name = newName
|
name = newName
|
||||||
dna = newDNA
|
dna = newDNA
|
||||||
speciesName = newSpecies
|
speciesName = newSpecies
|
||||||
languages = newLanguages
|
languages = newLanguages
|
||||||
identifying_gender = newIdentifying_Gender
|
identifying_gender = newIdentifying_Gender
|
||||||
flavour_texts = newFlavour ? newFlavour.Copy() : null
|
flavour_texts = newFlavour ? newFlavour.Copy() : null
|
||||||
|
genMods = newGenMods ? newGenMods.Copy() : null
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
|
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
|
||||||
|
|
||||||
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts)
|
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts, T.modifiers)
|
||||||
absorbDNA(newDNA)
|
absorbDNA(newDNA)
|
||||||
|
|
||||||
if(T.mind && T.mind.changeling)
|
if(T.mind && T.mind.changeling)
|
||||||
|
|||||||
@@ -48,6 +48,13 @@
|
|||||||
src.UpdateAppearance()
|
src.UpdateAppearance()
|
||||||
domutcheck(src, null)
|
domutcheck(src, null)
|
||||||
changeling_update_languages(changeling.absorbed_languages)
|
changeling_update_languages(changeling.absorbed_languages)
|
||||||
|
if(chosen_dna.genMods)
|
||||||
|
var/mob/living/carbon/human/self = src
|
||||||
|
for(var/datum/modifier/mod in self.modifiers)
|
||||||
|
self.modifiers.Remove(mod.type)
|
||||||
|
|
||||||
|
for(var/datum/modifier/mod in chosen_dna.genMods)
|
||||||
|
self.modifiers.Add(mod.type)
|
||||||
|
|
||||||
src.verbs -= /mob/proc/changeling_transform
|
src.verbs -= /mob/proc/changeling_transform
|
||||||
spawn(10)
|
spawn(10)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/obj/item/weapon/spell/proc/within_range(var/atom/target, var/max_range = 7) // Beyond 7 is off the screen.
|
/obj/item/weapon/spell/proc/within_range(var/atom/target, var/max_range = 7) // Beyond 7 is off the screen.
|
||||||
if(range(get_dist(owner, target) <= max_range))
|
if(target in view(max_range, owner))
|
||||||
return TRUE
|
return TRUE
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,13 @@
|
|||||||
if(!AM.loc) //Don't teleport HUD telements to us.
|
if(!AM.loc) //Don't teleport HUD telements to us.
|
||||||
return
|
return
|
||||||
if(AM.anchored)
|
if(AM.anchored)
|
||||||
user << "<span class='warning'>\The [hit_atom] is firmly secured and anchored, you can't move it!</span>"
|
to_chat(user, "<span class='warning'>\The [hit_atom] is firmly secured and anchored, you can't move it!</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
if(!within_range(hit_atom) && !check_for_scepter())
|
if(!within_range(hit_atom) && !check_for_scepter())
|
||||||
user << "<span class='warning'>\The [hit_atom] is too far away.</span>"
|
to_chat(user, "<span class='warning'>\The [hit_atom] is too far away.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
//Teleporting an item.
|
//Teleporting an item.
|
||||||
if(istype(hit_atom, /obj/item))
|
if(istype(hit_atom, /obj/item))
|
||||||
var/obj/item/I = hit_atom
|
var/obj/item/I = hit_atom
|
||||||
@@ -47,7 +49,7 @@
|
|||||||
//Now let's try to teleport a living mob.
|
//Now let's try to teleport a living mob.
|
||||||
else if(istype(hit_atom, /mob/living))
|
else if(istype(hit_atom, /mob/living))
|
||||||
var/mob/living/L = hit_atom
|
var/mob/living/L = hit_atom
|
||||||
L << "<span class='danger'>You are teleported towards \the [user].</span>"
|
to_chat(L, "<span class='danger'>You are teleported towards \the [user].</span>")
|
||||||
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
|
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
|
||||||
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
|
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
|
||||||
s1.set_up(2, 1, user)
|
s1.set_up(2, 1, user)
|
||||||
@@ -60,7 +62,7 @@
|
|||||||
|
|
||||||
spawn(1 SECOND)
|
spawn(1 SECOND)
|
||||||
if(!user.Adjacent(L))
|
if(!user.Adjacent(L))
|
||||||
user << "<span class='warning'>\The [L] is out of your reach.</span>"
|
to_chat(user, "<span class='warning'>\The [L] is out of your reach.</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -149,5 +149,7 @@
|
|||||||
feedback_set_details("religion_book","[new_book_style]")
|
feedback_set_details("religion_book","[new_book_style]")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/* If you uncomment this, every time the mob preview updates it makes a new PDA. It seems to work just fine and display without it, so why this exists, haven't a clue. -Hawk
|
||||||
/datum/job/chaplain/equip_preview(var/mob/living/carbon/human/H, var/alt_title)
|
/datum/job/chaplain/equip_preview(var/mob/living/carbon/human/H, var/alt_title)
|
||||||
return equip(H, alt_title, FALSE)
|
return equip(H, alt_title, FALSE)
|
||||||
|
*/
|
||||||
|
|||||||
@@ -378,7 +378,8 @@ var/global/datum/controller/occupations/job_master
|
|||||||
H.amend_exploitable(G.path)
|
H.amend_exploitable(G.path)
|
||||||
|
|
||||||
if(G.slot == "implant")
|
if(G.slot == "implant")
|
||||||
H.implant_loadout(G)
|
var/obj/item/weapon/implant/I = G.spawn_item(H)
|
||||||
|
I.implant_loadout(H)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if(G.slot && !(G.slot in custom_equip_slots))
|
if(G.slot && !(G.slot in custom_equip_slots))
|
||||||
|
|||||||
@@ -13,27 +13,29 @@
|
|||||||
idle_power_usage = 40
|
idle_power_usage = 40
|
||||||
active_power_usage = 300
|
active_power_usage = 300
|
||||||
|
|
||||||
var/stored_matter = 0
|
var/obj/item/weapon/reagent_containers/container = null // This is the beaker that holds all of the biomass
|
||||||
var/max_stored_matter = 0
|
|
||||||
var/print_delay = 100
|
var/print_delay = 100
|
||||||
|
var/base_print_delay = 100 // For Adminbus reasons
|
||||||
var/printing
|
var/printing
|
||||||
var/loaded_dna //Blood sample for DNA hashing.
|
var/loaded_dna //Blood sample for DNA hashing.
|
||||||
|
|
||||||
// These should be subtypes of /obj/item/organ
|
// These should be subtypes of /obj/item/organ
|
||||||
|
// Costs roughly 20u Phoron (1 sheet) per internal organ, limbs are 60u for limb and extremity
|
||||||
var/list/products = list(
|
var/list/products = list(
|
||||||
"Heart" = list(/obj/item/organ/internal/heart, 25),
|
"Heart" = list(/obj/item/organ/internal/heart, 20),
|
||||||
"Lungs" = list(/obj/item/organ/internal/lungs, 25),
|
"Lungs" = list(/obj/item/organ/internal/lungs, 20),
|
||||||
"Kidneys" = list(/obj/item/organ/internal/kidneys,20),
|
"Kidneys" = list(/obj/item/organ/internal/kidneys,20),
|
||||||
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
|
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
|
||||||
"Liver" = list(/obj/item/organ/internal/liver, 25),
|
"Liver" = list(/obj/item/organ/internal/liver, 20),
|
||||||
"Arm, Left" = list(/obj/item/organ/external/arm, 65),
|
"Arm, Left" = list(/obj/item/organ/external/arm, 40),
|
||||||
"Arm, Right" = list(/obj/item/organ/external/arm/right, 65),
|
"Arm, Right" = list(/obj/item/organ/external/arm/right, 40),
|
||||||
"Leg, Left" = list(/obj/item/organ/external/leg, 65),
|
"Leg, Left" = list(/obj/item/organ/external/leg, 40),
|
||||||
"Leg, Right" = list(/obj/item/organ/external/leg/right, 65),
|
"Leg, Right" = list(/obj/item/organ/external/leg/right, 40),
|
||||||
"Foot, Left" = list(/obj/item/organ/external/foot, 40),
|
"Foot, Left" = list(/obj/item/organ/external/foot, 20),
|
||||||
"Foot, Right" = list(/obj/item/organ/external/foot/right, 40),
|
"Foot, Right" = list(/obj/item/organ/external/foot/right, 20),
|
||||||
"Hand, Left" = list(/obj/item/organ/external/hand, 40),
|
"Hand, Left" = list(/obj/item/organ/external/hand, 20),
|
||||||
"Hand, Right" = list(/obj/item/organ/external/hand/right, 40)
|
"Hand, Right" = list(/obj/item/organ/external/hand/right, 20)
|
||||||
)
|
)
|
||||||
|
|
||||||
/obj/machinery/organ_printer/attackby(var/obj/item/O, var/mob/user)
|
/obj/machinery/organ_printer/attackby(var/obj/item/O, var/mob/user)
|
||||||
@@ -57,25 +59,27 @@
|
|||||||
|
|
||||||
/obj/machinery/organ_printer/New()
|
/obj/machinery/organ_printer/New()
|
||||||
..()
|
..()
|
||||||
|
|
||||||
component_parts = list()
|
component_parts = list()
|
||||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
||||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
||||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||||
RefreshParts()
|
RefreshParts()
|
||||||
|
|
||||||
/obj/machinery/organ_printer/examine(var/mob/user)
|
/obj/machinery/organ_printer/examine(var/mob/user)
|
||||||
. = ..()
|
. = ..()
|
||||||
to_chat(user, "<span class='notice'>It is loaded with [stored_matter]/[max_stored_matter] matter units.</span>")
|
var/biomass = get_biomass_volume()
|
||||||
|
if(biomass)
|
||||||
|
to_chat(user, "<span class='notice'>It is loaded with [biomass] units of biomass.</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>It is not loaded with any biomass.</span>")
|
||||||
|
|
||||||
/obj/machinery/organ_printer/RefreshParts()
|
/obj/machinery/organ_printer/RefreshParts()
|
||||||
print_delay = initial(print_delay)
|
// Print Delay updating
|
||||||
max_stored_matter = 0
|
print_delay = base_print_delay
|
||||||
for(var/obj/item/weapon/stock_parts/matter_bin/bin in component_parts)
|
|
||||||
max_stored_matter += bin.rating * 100
|
|
||||||
for(var/obj/item/weapon/stock_parts/manipulator/manip in component_parts)
|
for(var/obj/item/weapon/stock_parts/manipulator/manip in component_parts)
|
||||||
print_delay -= (manip.rating-1)*10
|
print_delay -= (manip.rating-1)*10
|
||||||
print_delay = max(0,print_delay)
|
print_delay = max(0,print_delay)
|
||||||
|
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|
||||||
/obj/machinery/organ_printer/attack_hand(mob/user)
|
/obj/machinery/organ_printer/attack_hand(mob/user)
|
||||||
@@ -91,6 +95,14 @@
|
|||||||
to_chat(user, "<span class='notice'>\The [src] is busy!</span>")
|
to_chat(user, "<span class='notice'>\The [src] is busy!</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(container)
|
||||||
|
var/response = alert(user, "What do you want to do?", "Bioprinter Menu", "Print Limbs", "Cancel")
|
||||||
|
if(response == "Print Limbs")
|
||||||
|
printing_menu(user)
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] can't operate without a reagent reservoir!</span>")
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/proc/printing_menu(mob/user)
|
||||||
var/choice = input("What would you like to print?") as null|anything in products
|
var/choice = input("What would you like to print?") as null|anything in products
|
||||||
|
|
||||||
if(!choice || printing || (stat & (BROKEN|NOPOWER)))
|
if(!choice || printing || (stat & (BROKEN|NOPOWER)))
|
||||||
@@ -99,7 +111,7 @@
|
|||||||
if(!can_print(choice))
|
if(!can_print(choice))
|
||||||
return
|
return
|
||||||
|
|
||||||
stored_matter -= products[choice][2]
|
container.reagents.remove_reagent("biomass", products[choice][2])
|
||||||
|
|
||||||
use_power = 2
|
use_power = 2
|
||||||
printing = 1
|
printing = 1
|
||||||
@@ -118,9 +130,42 @@
|
|||||||
|
|
||||||
print_organ(choice)
|
print_organ(choice)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/verb/eject_beaker()
|
||||||
|
set name = "Eject Beaker"
|
||||||
|
set category = "Object"
|
||||||
|
set src in oview(1)
|
||||||
|
|
||||||
|
if(usr.stat != 0)
|
||||||
|
return
|
||||||
|
add_fingerprint(usr)
|
||||||
|
remove_beaker()
|
||||||
|
return
|
||||||
|
|
||||||
|
// Does exactly what it says it does
|
||||||
|
// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user.
|
||||||
|
/obj/machinery/organ_printer/proc/remove_beaker()
|
||||||
|
if(container)
|
||||||
|
container.forceMove(get_turf(src))
|
||||||
|
container = null
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
// Checks for reagents, then reports how much biomass it has in it
|
||||||
|
/obj/machinery/organ_printer/proc/get_biomass_volume()
|
||||||
|
var/biomass_count = 0
|
||||||
|
if(container && container.reagents)
|
||||||
|
for(var/datum/reagent/R in container.reagents.reagent_list)
|
||||||
|
if(R.id == "biomass")
|
||||||
|
biomass_count += R.volume
|
||||||
|
|
||||||
|
return biomass_count
|
||||||
|
|
||||||
/obj/machinery/organ_printer/proc/can_print(var/choice)
|
/obj/machinery/organ_printer/proc/can_print(var/choice)
|
||||||
if(stored_matter < products[choice][2])
|
var/biomass = get_biomass_volume()
|
||||||
visible_message("<span class='notice'>\The [src] displays a warning: 'Not enough matter. [stored_matter] stored and [products[choice][2]] needed.'</span>")
|
if(biomass < products[choice][2])
|
||||||
|
visible_message("<span class='notice'>\The [src] displays a warning: 'Not enough biomass. [biomass] stored and [products[choice][2]] needed.'</span>")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(!loaded_dna || !loaded_dna["donor"])
|
if(!loaded_dna || !loaded_dna["donor"])
|
||||||
@@ -162,6 +207,59 @@
|
|||||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||||
/obj/item/weapon/stock_parts/manipulator = 2)
|
/obj/item/weapon/stock_parts/manipulator = 2)
|
||||||
|
|
||||||
|
// FLESH ORGAN PRINTER
|
||||||
|
/obj/machinery/organ_printer/flesh
|
||||||
|
name = "bioprinter"
|
||||||
|
desc = "It's a machine that prints replacement organs."
|
||||||
|
icon_state = "bioprinter"
|
||||||
|
circuit = /obj/item/weapon/circuitboard/bioprinter
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/flesh/full/New()
|
||||||
|
. = ..()
|
||||||
|
container = new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src)
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/flesh/dismantle()
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
if(T)
|
||||||
|
if(container)
|
||||||
|
container.forceMove(T)
|
||||||
|
container = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/flesh/print_organ(var/choice)
|
||||||
|
var/obj/item/organ/O = ..()
|
||||||
|
|
||||||
|
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||||
|
visible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
|
||||||
|
return O
|
||||||
|
|
||||||
|
/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user)
|
||||||
|
// DNA sample from syringe.
|
||||||
|
if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe
|
||||||
|
var/obj/item/weapon/reagent_containers/syringe/S = W
|
||||||
|
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
|
||||||
|
if(injected && injected.data)
|
||||||
|
loaded_dna = injected.data
|
||||||
|
S.reagents.remove_reagent("blood", injected.volume)
|
||||||
|
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
|
||||||
|
return
|
||||||
|
else if(istype(W,/obj/item/weapon/reagent_containers/glass))
|
||||||
|
var/obj/item/weapon/reagent_containers/glass/G = W
|
||||||
|
if(container)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] already has a container loaded!</span>")
|
||||||
|
return
|
||||||
|
else if(do_after(user, 1 SECOND))
|
||||||
|
user.visible_message("[user] has loaded \the [G] into \the [src].", "You load \the [G] into \the [src].")
|
||||||
|
container = G
|
||||||
|
user.drop_item()
|
||||||
|
G.forceMove(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
// END FLESH ORGAN PRINTER
|
||||||
|
|
||||||
|
|
||||||
|
/* Roboprinter is made obsolete by the system already in place and mapped into Robotics
|
||||||
/obj/item/weapon/circuitboard/roboprinter
|
/obj/item/weapon/circuitboard/roboprinter
|
||||||
name = "roboprinter circuit"
|
name = "roboprinter circuit"
|
||||||
build_path = /obj/machinery/organ_printer/robot
|
build_path = /obj/machinery/organ_printer/robot
|
||||||
@@ -224,53 +322,4 @@
|
|||||||
return
|
return
|
||||||
return ..()
|
return ..()
|
||||||
// END ROBOT ORGAN PRINTER
|
// END ROBOT ORGAN PRINTER
|
||||||
|
*/
|
||||||
// FLESH ORGAN PRINTER
|
|
||||||
/obj/machinery/organ_printer/flesh
|
|
||||||
name = "bioprinter"
|
|
||||||
desc = "It's a machine that prints replacement organs."
|
|
||||||
icon_state = "bioprinter"
|
|
||||||
circuit = /obj/item/weapon/circuitboard/bioprinter
|
|
||||||
|
|
||||||
var/amount_per_slab = 50
|
|
||||||
|
|
||||||
/obj/machinery/organ_printer/flesh/full/New()
|
|
||||||
. = ..()
|
|
||||||
stored_matter = max_stored_matter
|
|
||||||
|
|
||||||
/obj/machinery/organ_printer/flesh/dismantle()
|
|
||||||
var/turf/T = get_turf(src)
|
|
||||||
if(T)
|
|
||||||
while(stored_matter >= amount_per_slab)
|
|
||||||
stored_matter -= amount_per_slab
|
|
||||||
new /obj/item/weapon/reagent_containers/food/snacks/meat(T)
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/obj/machinery/organ_printer/flesh/print_organ(var/choice)
|
|
||||||
var/obj/item/organ/O = ..()
|
|
||||||
|
|
||||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
|
||||||
visible_message("<span class='info'>\The [src] dings, then spits out \a [O].</span>")
|
|
||||||
return O
|
|
||||||
|
|
||||||
/obj/machinery/organ_printer/flesh/attackby(obj/item/weapon/W, mob/user)
|
|
||||||
// Load with matter for printing.
|
|
||||||
if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
|
|
||||||
if((max_stored_matter - stored_matter) < amount_per_slab)
|
|
||||||
to_chat(user, "<span class='warning'>\The [src] is too full.</span>")
|
|
||||||
return
|
|
||||||
stored_matter += amount_per_slab
|
|
||||||
user.drop_item()
|
|
||||||
to_chat(user, "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>")
|
|
||||||
qdel(W)
|
|
||||||
return
|
|
||||||
// DNA sample from syringe.
|
|
||||||
else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) //TODO: Make this actually empty the syringe
|
|
||||||
var/obj/item/weapon/reagent_containers/syringe/S = W
|
|
||||||
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
|
|
||||||
if(injected && injected.data)
|
|
||||||
loaded_dna = injected.data
|
|
||||||
to_chat(user, "<span class='info'>You scan the blood sample into the bioprinter.</span>")
|
|
||||||
return
|
|
||||||
return ..()
|
|
||||||
// END FLESH ORGAN PRINTER
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
break
|
break
|
||||||
return selected
|
return selected
|
||||||
|
|
||||||
#define CLONE_BIOMASS 150
|
#define CLONE_BIOMASS 60
|
||||||
|
|
||||||
/obj/machinery/clonepod
|
/obj/machinery/clonepod
|
||||||
name = "cloning pod"
|
name = "cloning pod"
|
||||||
@@ -33,17 +33,18 @@
|
|||||||
circuit = /obj/item/weapon/circuitboard/clonepod
|
circuit = /obj/item/weapon/circuitboard/clonepod
|
||||||
icon = 'icons/obj/cloning.dmi'
|
icon = 'icons/obj/cloning.dmi'
|
||||||
icon_state = "pod_0"
|
icon_state = "pod_0"
|
||||||
req_access = list(access_genetics) //For premature unlocking.
|
req_access = list(access_genetics) // For premature unlocking.
|
||||||
var/mob/living/occupant
|
var/mob/living/occupant
|
||||||
var/heal_level = 20 //The clone is released once its health reaches this level.
|
var/heal_level = 20 // The clone is released once its health reaches this level.
|
||||||
var/heal_rate = 1
|
var/heal_rate = 1
|
||||||
var/notoxin = 0
|
|
||||||
var/locked = 0
|
var/locked = 0
|
||||||
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
|
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
|
||||||
var/mess = 0 //Need to clean out it if it's full of exploded clone.
|
var/mess = 0 // Need to clean out it if it's full of exploded clone.
|
||||||
var/attempting = 0 //One clone attempt at a time thanks
|
var/attempting = 0 // One clone attempt at a time thanks
|
||||||
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
|
var/eject_wait = 0 // Don't eject them as soon as they are created fuckkk
|
||||||
var/biomass = CLONE_BIOMASS * 3
|
|
||||||
|
var/list/containers = list() // Beakers for our liquid biomass
|
||||||
|
var/container_limit = 3 // How many beakers can the machine hold?
|
||||||
|
|
||||||
/obj/machinery/clonepod/New()
|
/obj/machinery/clonepod/New()
|
||||||
..()
|
..()
|
||||||
@@ -71,8 +72,6 @@
|
|||||||
to_chat(user, "Current clone cycle is [round(completion)]% complete.")
|
to_chat(user, "Current clone cycle is [round(completion)]% complete.")
|
||||||
return
|
return
|
||||||
|
|
||||||
//Clonepod
|
|
||||||
|
|
||||||
//Start growing a human clone in the pod!
|
//Start growing a human clone in the pod!
|
||||||
/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
|
/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R)
|
||||||
if(mess || attempting)
|
if(mess || attempting)
|
||||||
@@ -98,6 +97,9 @@
|
|||||||
if(istype(modifier_type, /datum/modifier/no_clone))
|
if(istype(modifier_type, /datum/modifier/no_clone))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
// Remove biomass when the cloning is started, rather than when the guy pops out
|
||||||
|
remove_biomass(CLONE_BIOMASS)
|
||||||
|
|
||||||
attempting = 1 //One at a time!!
|
attempting = 1 //One at a time!!
|
||||||
locked = 1
|
locked = 1
|
||||||
|
|
||||||
@@ -164,6 +166,7 @@
|
|||||||
|
|
||||||
for(var/datum/language/L in R.languages)
|
for(var/datum/language/L in R.languages)
|
||||||
H.add_language(L.name)
|
H.add_language(L.name)
|
||||||
|
|
||||||
H.flavor_texts = R.flavor.Copy()
|
H.flavor_texts = R.flavor.Copy()
|
||||||
H.suiciding = 0
|
H.suiciding = 0
|
||||||
attempting = 0
|
attempting = 0
|
||||||
@@ -171,16 +174,6 @@
|
|||||||
|
|
||||||
//Grow clones to maturity then kick them out. FREELOADERS
|
//Grow clones to maturity then kick them out. FREELOADERS
|
||||||
/obj/machinery/clonepod/process()
|
/obj/machinery/clonepod/process()
|
||||||
|
|
||||||
var/visible_message = 0
|
|
||||||
for(var/obj/item/weapon/reagent_containers/food/snacks/meat/meat in range(1, src))
|
|
||||||
qdel(meat)
|
|
||||||
biomass += 50
|
|
||||||
visible_message = 1 // Prevent chatspam when multiple meat are near
|
|
||||||
|
|
||||||
if(visible_message)
|
|
||||||
visible_message("<span class = 'notice'>[src] sucks in and processes the nearby biomass.</span>")
|
|
||||||
|
|
||||||
if(stat & NOPOWER) //Autoeject if power is lost
|
if(stat & NOPOWER) //Autoeject if power is lost
|
||||||
if(occupant)
|
if(occupant)
|
||||||
locked = 0
|
locked = 0
|
||||||
@@ -250,11 +243,14 @@
|
|||||||
else
|
else
|
||||||
locked = 0
|
locked = 0
|
||||||
to_chat(user, "System unlocked.")
|
to_chat(user, "System unlocked.")
|
||||||
else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
|
else if(istype(W,/obj/item/weapon/reagent_containers/glass))
|
||||||
to_chat(user, "<span class='notice'>\The [src] processes \the [W].</span>")
|
if(LAZYLEN(containers) >= container_limit)
|
||||||
biomass += 50
|
to_chat(user, "<span class='warning'>\The [src] has too many containers loaded!</span>")
|
||||||
user.drop_item()
|
else if(do_after(user, 1 SECOND))
|
||||||
qdel(W)
|
user.visible_message("[user] has loaded \the [W] into \the [src].", "You load \the [W] into \the [src].")
|
||||||
|
containers += W
|
||||||
|
user.drop_item()
|
||||||
|
W.forceMove(src)
|
||||||
return
|
return
|
||||||
else if(W.is_wrench())
|
else if(W.is_wrench())
|
||||||
if(locked && (anchored || occupant))
|
if(locked && (anchored || occupant))
|
||||||
@@ -271,7 +267,7 @@
|
|||||||
user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
|
user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
|
||||||
else
|
else
|
||||||
user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
|
user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
|
||||||
else if(W.is_multitool())
|
else if(istype(W, /obj/item/device/multitool))
|
||||||
var/obj/item/device/multitool/M = W
|
var/obj/item/device/multitool/M = W
|
||||||
M.connecting = src
|
M.connecting = src
|
||||||
to_chat(user, "<span class='notice'>You load connection data from [src] to [M].</span>")
|
to_chat(user, "<span class='notice'>You load connection data from [src] to [M].</span>")
|
||||||
@@ -308,10 +304,6 @@
|
|||||||
|
|
||||||
heal_level = rating * 10 - 20
|
heal_level = rating * 10 - 20
|
||||||
heal_rate = round(rating / 4)
|
heal_rate = round(rating / 4)
|
||||||
if(rating >= 8)
|
|
||||||
notoxin = 1
|
|
||||||
else
|
|
||||||
notoxin = 0
|
|
||||||
|
|
||||||
/obj/machinery/clonepod/verb/eject()
|
/obj/machinery/clonepod/verb/eject()
|
||||||
set name = "Eject Cloner"
|
set name = "Eject Cloner"
|
||||||
@@ -348,10 +340,66 @@
|
|||||||
domutcheck(occupant) //Waiting until they're out before possible transforming.
|
domutcheck(occupant) //Waiting until they're out before possible transforming.
|
||||||
occupant = null
|
occupant = null
|
||||||
|
|
||||||
biomass -= CLONE_BIOMASS
|
|
||||||
update_icon()
|
update_icon()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// Returns the total amount of biomass reagent in all of the pod's stored containers
|
||||||
|
/obj/machinery/clonepod/proc/get_biomass()
|
||||||
|
var/biomass_count = 0
|
||||||
|
if(LAZYLEN(containers))
|
||||||
|
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
|
||||||
|
for(var/datum/reagent/R in G.reagents.reagent_list)
|
||||||
|
if(R.id == "biomass")
|
||||||
|
biomass_count += R.volume
|
||||||
|
|
||||||
|
return biomass_count
|
||||||
|
|
||||||
|
// Removes [amount] biomass, spread across all containers. Doesn't have any check that you actually HAVE enough biomass, though.
|
||||||
|
/obj/machinery/clonepod/proc/remove_biomass(var/amount = CLONE_BIOMASS) //Just in case it doesn't get passed a new amount, assume one clone
|
||||||
|
var/to_remove = 0 // Tracks how much biomass has been found so far
|
||||||
|
if(LAZYLEN(containers))
|
||||||
|
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
|
||||||
|
if(to_remove < amount) //If we have what we need, we can stop. Checked every time we switch beakers
|
||||||
|
for(var/datum/reagent/R in G.reagents.reagent_list)
|
||||||
|
if(R.id == "biomass") // Finds Biomass
|
||||||
|
var/need_remove = max(0, amount - to_remove) //Figures out how much biomass is in this container
|
||||||
|
if(R.volume >= need_remove) //If we have more than enough in this beaker, only take what we need
|
||||||
|
R.remove_self(need_remove)
|
||||||
|
to_remove = amount
|
||||||
|
else //Otherwise, take everything and move on
|
||||||
|
to_remove += R.volume
|
||||||
|
R.remove_self(R.volume)
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
// Empties all of the beakers from the cloning pod, used to refill it
|
||||||
|
/obj/machinery/clonepod/verb/empty_beakers()
|
||||||
|
set name = "Eject Beakers"
|
||||||
|
set category = "Object"
|
||||||
|
set src in oview(1)
|
||||||
|
|
||||||
|
if(usr.stat != 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
add_fingerprint(usr)
|
||||||
|
drop_beakers()
|
||||||
|
return
|
||||||
|
|
||||||
|
// Actually does all of the beaker dropping
|
||||||
|
// Returns 1 if it succeeds, 0 if it fails. Added in case someone wants to add messages to the user.
|
||||||
|
/obj/machinery/clonepod/proc/drop_beakers()
|
||||||
|
if(LAZYLEN(containers))
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
if(T)
|
||||||
|
for(var/obj/item/weapon/reagent_containers/glass/G in containers)
|
||||||
|
G.forceMove(T)
|
||||||
|
containers -= G
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
/obj/machinery/clonepod/proc/malfunction()
|
/obj/machinery/clonepod/proc/malfunction()
|
||||||
if(occupant)
|
if(occupant)
|
||||||
connected_message("Critical Error!")
|
connected_message("Critical Error!")
|
||||||
@@ -406,6 +454,12 @@
|
|||||||
else if(mess)
|
else if(mess)
|
||||||
icon_state = "pod_g"
|
icon_state = "pod_g"
|
||||||
|
|
||||||
|
|
||||||
|
/obj/machinery/clonepod/full/New()
|
||||||
|
..()
|
||||||
|
for(var/i = 1 to container_limit)
|
||||||
|
containers += new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src)
|
||||||
|
|
||||||
//Health Tracker Implant
|
//Health Tracker Implant
|
||||||
|
|
||||||
/obj/item/weapon/implant/health
|
/obj/item/weapon/implant/health
|
||||||
@@ -479,7 +533,7 @@
|
|||||||
|
|
||||||
/obj/item/weapon/disk/data/examine(mob/user)
|
/obj/item/weapon/disk/data/examine(mob/user)
|
||||||
..(user)
|
..(user)
|
||||||
to_chat(user, "The write-protect tab is set to [read_only ? "protected" : "unprotected"].")
|
to_chat(user, text("The write-protect tab is set to [read_only ? "protected" : "unprotected"]."))
|
||||||
return
|
return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -200,6 +200,8 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva
|
|||||||
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
|
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(transfer.controlling_drone)
|
||||||
|
transfer.controlling_drone.release_ai_control("Unit control lost. Core transfer completed.")
|
||||||
transfer.aiRestorePowerRoutine = 0
|
transfer.aiRestorePowerRoutine = 0
|
||||||
transfer.control_disabled = 0
|
transfer.control_disabled = 0
|
||||||
transfer.aiRadio.disabledAi = 0
|
transfer.aiRadio.disabledAi = 0
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
user.drop_item()
|
user.drop_item()
|
||||||
W.loc = src
|
W.loc = src
|
||||||
diskette = W
|
diskette = W
|
||||||
user << "You insert [W]."
|
to_chat(user, "You insert [W].")
|
||||||
updateUsrDialog()
|
updateUsrDialog()
|
||||||
return
|
return
|
||||||
else if(istype(W, /obj/item/device/multitool))
|
else if(istype(W, /obj/item/device/multitool))
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
pods += P
|
pods += P
|
||||||
P.connected = src
|
P.connected = src
|
||||||
P.name = "[initial(P.name)] #[pods.len]"
|
P.name = "[initial(P.name)] #[pods.len]"
|
||||||
user << "<span class='notice'>You connect [P] to [src].</span>"
|
to_chat(user, "<span class='notice'>You connect [P] to [src].</span>")
|
||||||
|
|
||||||
else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)))
|
else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)))
|
||||||
if(check_access(W))
|
if(check_access(W))
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
var/pods_list_ui[0]
|
var/pods_list_ui[0]
|
||||||
for(var/obj/machinery/clonepod/pod in pods)
|
for(var/obj/machinery/clonepod/pod in pods)
|
||||||
pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass)
|
pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.get_biomass())
|
||||||
|
|
||||||
if(pods)
|
if(pods)
|
||||||
data["pods"] = pods_list_ui
|
data["pods"] = pods_list_ui
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
//Look for that player! They better be dead!
|
//Look for that player! They better be dead!
|
||||||
if(istype(C))
|
if(istype(C))
|
||||||
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
||||||
if(!pods.len)
|
if(!LAZYLEN(pods))
|
||||||
temp = "Error: No clone pods detected."
|
temp = "Error: No clone pods detected."
|
||||||
else
|
else
|
||||||
var/obj/machinery/clonepod/pod = pods[1]
|
var/obj/machinery/clonepod/pod = pods[1]
|
||||||
@@ -252,13 +252,12 @@
|
|||||||
pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods
|
pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods
|
||||||
if(pod.occupant)
|
if(pod.occupant)
|
||||||
temp = "Error: Clonepod is currently occupied."
|
temp = "Error: Clonepod is currently occupied."
|
||||||
else if(pod.biomass < CLONE_BIOMASS)
|
else if(pod.get_biomass() < CLONE_BIOMASS)
|
||||||
temp = "Error: Not enough biomass."
|
temp = "Error: Not enough biomass."
|
||||||
else if(pod.mess)
|
else if(pod.mess)
|
||||||
temp = "Error: Clonepod malfunction."
|
temp = "Error: Clonepod malfunction."
|
||||||
else if(!config.revival_cloning)
|
else if(!config.revival_cloning)
|
||||||
temp = "Error: Unable to initiate cloning cycle."
|
temp = "Error: Unable to initiate cloning cycle."
|
||||||
|
|
||||||
else if(pod.growclone(C))
|
else if(pod.growclone(C))
|
||||||
temp = "Initiating cloning cycle..."
|
temp = "Initiating cloning cycle..."
|
||||||
records.Remove(C)
|
records.Remove(C)
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
var/obj/machinery/computer3/laptop/stored_computer = null
|
var/obj/machinery/computer3/laptop/stored_computer = null
|
||||||
|
|
||||||
|
/obj/item/device/laptop/get_cell()
|
||||||
|
return stored_computer.battery
|
||||||
|
|
||||||
/obj/item/device/laptop/verb/open_computer()
|
/obj/item/device/laptop/verb/open_computer()
|
||||||
set name = "Open Laptop"
|
set name = "Open Laptop"
|
||||||
set category = "Object"
|
set category = "Object"
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
|
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
|
||||||
var/check_all = 0 //If active, will fire on anything, including synthetics.
|
var/check_all = 0 //If active, will fire on anything, including synthetics.
|
||||||
var/ailock = 0 // AI cannot use this
|
var/ailock = 0 // AI cannot use this
|
||||||
|
var/faction = null //if set, will not fire at people in the same faction for any reason.
|
||||||
|
|
||||||
var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
|
var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
|
||||||
|
|
||||||
@@ -80,6 +81,11 @@
|
|||||||
lethal = 1
|
lethal = 1
|
||||||
installation = /obj/item/weapon/gun/energy/laser
|
installation = /obj/item/weapon/gun/energy/laser
|
||||||
|
|
||||||
|
/obj/machinery/porta_turret/stationary/syndie // Generic turrets for POIs that need to not shoot their buddies.
|
||||||
|
enabled = TRUE
|
||||||
|
check_all = TRUE
|
||||||
|
faction = "syndicate" // Make sure this equals the faction that the mobs in the POI have or they will fight each other.
|
||||||
|
|
||||||
/obj/machinery/porta_turret/ai_defense
|
/obj/machinery/porta_turret/ai_defense
|
||||||
name = "defense turret"
|
name = "defense turret"
|
||||||
desc = "This variant appears to be much more durable."
|
desc = "This variant appears to be much more durable."
|
||||||
@@ -552,6 +558,9 @@ var/list/turret_icons
|
|||||||
if(!L)
|
if(!L)
|
||||||
return TURRET_NOT_TARGET
|
return TURRET_NOT_TARGET
|
||||||
|
|
||||||
|
if(faction && L.faction == faction)
|
||||||
|
return TURRET_NOT_TARGET
|
||||||
|
|
||||||
if(!emagged && issilicon(L) && check_all == 0) // Don't target silica, unless told to neutralize everything.
|
if(!emagged && issilicon(L) && check_all == 0) // Don't target silica, unless told to neutralize everything.
|
||||||
return TURRET_NOT_TARGET
|
return TURRET_NOT_TARGET
|
||||||
|
|
||||||
|
|||||||
@@ -41,35 +41,12 @@ obj/machinery/recharger
|
|||||||
return
|
return
|
||||||
if(istype(G, /obj/item/weapon/gun/energy))
|
if(istype(G, /obj/item/weapon/gun/energy))
|
||||||
var/obj/item/weapon/gun/energy/E = G
|
var/obj/item/weapon/gun/energy/E = G
|
||||||
if(!E.power_supply)
|
|
||||||
to_chat(user, "<span class='notice'>Your gun has no power cell.</span>")
|
|
||||||
return
|
|
||||||
if(E.self_recharge)
|
if(E.self_recharge)
|
||||||
to_chat(user, "<span class='notice'>Your gun has no recharge port.</span>")
|
to_chat(user, "<span class='notice'>Your gun has no recharge port.</span>")
|
||||||
return
|
return
|
||||||
if(istype(G, /obj/item/weapon/gun/energy/staff))
|
if(!G.get_cell())
|
||||||
|
to_chat(user, "This device does not have a battery installed.")
|
||||||
return
|
return
|
||||||
if(istype(G, /obj/item/device/flashlight))
|
|
||||||
var/obj/item/device/flashlight/F = G
|
|
||||||
if(!F.power_use)
|
|
||||||
return
|
|
||||||
if(!F.cell)
|
|
||||||
return
|
|
||||||
if(istype(G, /obj/item/device/laptop))
|
|
||||||
var/obj/item/device/laptop/L = G
|
|
||||||
if(!L.stored_computer.battery)
|
|
||||||
user << "There's no battery in it!"
|
|
||||||
return
|
|
||||||
if(istype(G, /obj/item/device/electronic_assembly))
|
|
||||||
var/obj/item/device/electronic_assembly/assembly = G
|
|
||||||
if(!assembly.battery)
|
|
||||||
to_chat(user, "<span class='warning'>The assembly doesn't have a power cell.</span>")
|
|
||||||
return
|
|
||||||
if(istype(G, /obj/item/weapon/weldingtool/electric))
|
|
||||||
var/obj/item/weapon/weldingtool/electric/welder = G
|
|
||||||
if(!welder.power_supply)
|
|
||||||
to_chat(user, "<span class='notice'>Your welder has no power cell.</span>")
|
|
||||||
return
|
|
||||||
|
|
||||||
user.drop_item()
|
user.drop_item()
|
||||||
G.loc = src
|
G.loc = src
|
||||||
@@ -109,71 +86,8 @@ obj/machinery/recharger
|
|||||||
update_use_power(1)
|
update_use_power(1)
|
||||||
icon_state = icon_state_idle
|
icon_state = icon_state_idle
|
||||||
else
|
else
|
||||||
if(istype(charging, /obj/item/weapon/gun/energy))
|
var/obj/item/weapon/cell/C = charging.get_cell()
|
||||||
var/obj/item/weapon/gun/energy/E = charging
|
if(istype(C))
|
||||||
if(!E.power_supply.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
E.power_supply.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/weapon/gun/magnetic))
|
|
||||||
var/obj/item/weapon/gun/magnetic/M = charging
|
|
||||||
if(!M.cell.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
M.cell.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/weapon/melee/baton))
|
|
||||||
var/obj/item/weapon/melee/baton/B = charging
|
|
||||||
if(B.bcell)
|
|
||||||
if(!B.bcell.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
B.bcell.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_idle
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/device/laptop))
|
|
||||||
var/obj/item/device/laptop/L = charging
|
|
||||||
if(!L.stored_computer.battery.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
L.stored_computer.battery.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/device/flashlight))
|
|
||||||
var/obj/item/device/flashlight/F = charging
|
|
||||||
if(F.cell)
|
|
||||||
if(!F.cell.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
F.cell.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_idle
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/weapon/cell))
|
|
||||||
var/obj/item/weapon/cell/C = charging
|
|
||||||
if(!C.fully_charged())
|
if(!C.fully_charged())
|
||||||
icon_state = icon_state_charging
|
icon_state = icon_state_charging
|
||||||
C.give(active_power_usage*CELLRATE)
|
C.give(active_power_usage*CELLRATE)
|
||||||
@@ -181,48 +95,17 @@ obj/machinery/recharger
|
|||||||
else
|
else
|
||||||
icon_state = icon_state_charged
|
icon_state = icon_state_charged
|
||||||
update_use_power(1)
|
update_use_power(1)
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/device/electronic_assembly))
|
|
||||||
var/obj/item/device/electronic_assembly/assembly = charging
|
|
||||||
if(assembly.battery)
|
|
||||||
if(!assembly.battery.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
assembly.battery.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_idle
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(istype(charging, /obj/item/weapon/weldingtool/electric))
|
|
||||||
var/obj/item/weapon/weldingtool/electric/C = charging
|
|
||||||
if(!C.power_supply.fully_charged())
|
|
||||||
icon_state = icon_state_charging
|
|
||||||
C.power_supply.give(active_power_usage*CELLRATE)
|
|
||||||
update_use_power(2)
|
|
||||||
else
|
|
||||||
icon_state = icon_state_charged
|
|
||||||
update_use_power(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/machinery/recharger/emp_act(severity)
|
/obj/machinery/recharger/emp_act(severity)
|
||||||
if(stat & (NOPOWER|BROKEN) || !anchored)
|
if(stat & (NOPOWER|BROKEN) || !anchored)
|
||||||
..(severity)
|
..(severity)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(istype(charging, /obj/item/weapon/gun/energy))
|
if(charging)
|
||||||
var/obj/item/weapon/gun/energy/E = charging
|
var/obj/item/weapon/cell/C = charging.get_cell()
|
||||||
if(E.power_supply)
|
if(istype(C))
|
||||||
E.power_supply.emp_act(severity)
|
C.emp_act(severity)
|
||||||
|
|
||||||
else if(istype(charging, /obj/item/weapon/melee/baton))
|
|
||||||
var/obj/item/weapon/melee/baton/B = charging
|
|
||||||
if(B.bcell)
|
|
||||||
B.bcell.charge = 0
|
|
||||||
..(severity)
|
..(severity)
|
||||||
|
|
||||||
/obj/machinery/recharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
|
/obj/machinery/recharger/update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
|
||||||
@@ -231,7 +114,6 @@ obj/machinery/recharger
|
|||||||
else
|
else
|
||||||
icon_state = icon_state_idle
|
icon_state = icon_state_idle
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/recharger/wallcharger
|
/obj/machinery/recharger/wallcharger
|
||||||
name = "wall recharger"
|
name = "wall recharger"
|
||||||
icon = 'icons/obj/stationobjs.dmi'
|
icon = 'icons/obj/stationobjs.dmi'
|
||||||
|
|||||||
@@ -248,6 +248,6 @@ var/global/list/image/splatter_cache=list()
|
|||||||
|
|
||||||
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
|
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
|
||||||
/obj/effect/decal/cleanable/mucus/mapped/New()
|
/obj/effect/decal/cleanable/mucus/mapped/New()
|
||||||
...()
|
..()
|
||||||
virus2 = new /datum/disease2/disease
|
virus2 = new /datum/disease2/disease
|
||||||
virus2.makerandom()
|
virus2.makerandom()
|
||||||
|
|||||||
@@ -46,4 +46,21 @@
|
|||||||
|
|
||||||
/obj/effect/temporary_effect/shuttle_landing/initialize()
|
/obj/effect/temporary_effect/shuttle_landing/initialize()
|
||||||
flick("shuttle_warning", src) // flick() forces the animation to always begin at the start.
|
flick("shuttle_warning", src) // flick() forces the animation to always begin at the start.
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
// The manifestation of Zeus's might. Or just a really unlucky day.
|
||||||
|
// This is purely a visual effect, this isn't the part of the code that hurts things.
|
||||||
|
/obj/effect/temporary_effect/lightning_strike
|
||||||
|
name = "lightning"
|
||||||
|
desc = "How <i>shocked</i> you must be, to see this text. You must have <i>lightning</i> reflexes. \
|
||||||
|
The humor in this description is just so <i>electrifying</i>."
|
||||||
|
icon = 'icons/effects/96x256.dmi'
|
||||||
|
icon_state = "lightning_strike"
|
||||||
|
plane = PLANE_LIGHTING_ABOVE
|
||||||
|
time_to_die = 1 SECOND
|
||||||
|
pixel_x = -32
|
||||||
|
|
||||||
|
/obj/effect/temporary_effect/lightning_strike/initialize()
|
||||||
|
icon_state += "[rand(1,2)]" // To have two variants of lightning sprites.
|
||||||
|
animate(src, alpha = 0, time = time_to_die - 1)
|
||||||
. = ..()
|
. = ..()
|
||||||
@@ -31,6 +31,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
|
|||||||
return
|
return
|
||||||
|
|
||||||
/obj/effect/portal/New()
|
/obj/effect/portal/New()
|
||||||
|
..() // Necessary for the list boilerplate to work
|
||||||
spawn(300)
|
spawn(300)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1254,7 +1254,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
|
|
||||||
if(isnull(cartridge))
|
if(isnull(cartridge))
|
||||||
to_chat(usr, "<span class='notice'>There's no cartridge to eject.</span>")
|
to_chat(usr, "<span class='notice'>There's no cartridge to eject.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
cartridge.forceMove(get_turf(src))
|
cartridge.forceMove(get_turf(src))
|
||||||
if(ismob(loc))
|
if(ismob(loc))
|
||||||
@@ -1382,7 +1382,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
|||||||
to_chat(user, "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>")
|
to_chat(user, "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>")
|
||||||
|
|
||||||
if(4)
|
if(4)
|
||||||
user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", 1)
|
user.visible_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", "<span class='notice'>You have analyzed [C]'s radiation levels!</span>")
|
||||||
to_chat(user, "<span class='notice'>Analyzing Results for [C]:</span>")
|
to_chat(user, "<span class='notice'>Analyzing Results for [C]:</span>")
|
||||||
if(C.radiation)
|
if(C.radiation)
|
||||||
to_chat(user, "<span class='notice'>Radiation Level: [C.radiation]</span>")
|
to_chat(user, "<span class='notice'>Radiation Level: [C.radiation]</span>")
|
||||||
|
|||||||
@@ -64,20 +64,24 @@
|
|||||||
add_attack_logs(user,carded_ai,"Purged from AI Card")
|
add_attack_logs(user,carded_ai,"Purged from AI Card")
|
||||||
flush = 1
|
flush = 1
|
||||||
carded_ai.suiciding = 1
|
carded_ai.suiciding = 1
|
||||||
carded_ai << "Your power has been disabled!"
|
to_chat(carded_ai, "Your power has been disabled!")
|
||||||
while (carded_ai && carded_ai.stat != 2)
|
while (carded_ai && carded_ai.stat != 2)
|
||||||
|
if(carded_ai.controlling_drone && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
|
||||||
|
carded_ai.controlling_drone.release_ai_control("Unit lost. Integrity too low to maintain connection.")
|
||||||
carded_ai.adjustOxyLoss(2)
|
carded_ai.adjustOxyLoss(2)
|
||||||
carded_ai.updatehealth()
|
carded_ai.updatehealth()
|
||||||
sleep(10)
|
sleep(10)
|
||||||
flush = 0
|
flush = 0
|
||||||
if (href_list["radio"])
|
if (href_list["radio"])
|
||||||
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
|
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
|
||||||
carded_ai << "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>"
|
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
|
||||||
user << "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>"
|
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
|
||||||
if (href_list["wireless"])
|
if (href_list["wireless"])
|
||||||
carded_ai.control_disabled = text2num(href_list["wireless"])
|
carded_ai.control_disabled = text2num(href_list["wireless"])
|
||||||
carded_ai << "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>"
|
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
|
||||||
user << "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>"
|
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
|
||||||
|
if(carded_ai.control_disabled && carded_ai.controlling_drone)
|
||||||
|
carded_ai.controlling_drone.release_ai_control("Unit control terminated at intellicore port.")
|
||||||
update_icon()
|
update_icon()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -94,12 +98,12 @@
|
|||||||
icon_state = "aicard"
|
icon_state = "aicard"
|
||||||
|
|
||||||
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
|
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
|
||||||
if(!ai.client)
|
if(!ai.client && !ai.controlling_drone)
|
||||||
user << "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer."
|
to_chat(user, "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(carded_ai)
|
if(carded_ai)
|
||||||
user << "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one."
|
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(!user.IsAdvancedToolUser() && isanimal(user))
|
if(!user.IsAdvancedToolUser() && isanimal(user))
|
||||||
@@ -108,7 +112,9 @@
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
|
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
|
||||||
ai << "<span class='danger'>\The [user] is transferring you into \the [src]!</span>"
|
to_chat(ai, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
|
||||||
|
if(ai.controlling_drone)
|
||||||
|
to_chat(ai.controlling_drone, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
|
||||||
|
|
||||||
if(do_after(user, 100))
|
if(do_after(user, 100))
|
||||||
if(istype(ai.loc, /turf/))
|
if(istype(ai.loc, /turf/))
|
||||||
@@ -124,11 +130,13 @@
|
|||||||
ai.control_disabled = 1
|
ai.control_disabled = 1
|
||||||
ai.aiRestorePowerRoutine = 0
|
ai.aiRestorePowerRoutine = 0
|
||||||
carded_ai = ai
|
carded_ai = ai
|
||||||
|
if(ai.controlling_drone)
|
||||||
|
ai.controlling_drone.release_ai_control("Unit control lost.")
|
||||||
|
|
||||||
if(ai.client)
|
if(ai.client)
|
||||||
ai << "You have been transferred into a mobile core. Remote access lost."
|
to_chat(ai, "You have been transferred into a mobile core. Remote access lost.")
|
||||||
if(user.client)
|
if(user.client)
|
||||||
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core."
|
to_chat(ai, "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core.")
|
||||||
|
|
||||||
ai.canmove = 1
|
ai.canmove = 1
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|||||||
@@ -69,17 +69,16 @@
|
|||||||
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
|
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
|
||||||
|
|
||||||
//Weather reports.
|
//Weather reports.
|
||||||
if(planet_controller)
|
for(var/datum/planet/planet in SSplanets.planets)
|
||||||
for(var/datum/planet/planet in planet_controller.planets)
|
if(planet.weather_holder && planet.weather_holder.current_weather)
|
||||||
if(planet.weather_holder && planet.weather_holder.current_weather)
|
var/list/W = list(
|
||||||
var/list/W = list(
|
"Planet" = planet.name,
|
||||||
"Planet" = planet.name,
|
"Time" = planet.current_time.show_time("hh:mm"),
|
||||||
"Time" = planet.current_time.show_time("hh:mm"),
|
"Weather" = planet.weather_holder.current_weather.name,
|
||||||
"Weather" = planet.weather_holder.current_weather.name,
|
"Temperature" = planet.weather_holder.temperature - T0C,
|
||||||
"Temperature" = planet.weather_holder.temperature - T0C,
|
"High" = planet.weather_holder.current_weather.temp_high - T0C,
|
||||||
"High" = planet.weather_holder.current_weather.temp_high - T0C,
|
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
|
||||||
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
|
weather[++weather.len] = W
|
||||||
weather[++weather.len] = W
|
|
||||||
|
|
||||||
injection = "<div>Test</div>"
|
injection = "<div>Test</div>"
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,9 @@
|
|||||||
processing_objects -= src
|
processing_objects -= src
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
/obj/item/device/flashlight/get_cell()
|
||||||
|
return cell
|
||||||
|
|
||||||
/obj/item/device/flashlight/verb/toggle()
|
/obj/item/device/flashlight/verb/toggle()
|
||||||
set name = "Toggle Flashlight Brightness"
|
set name = "Toggle Flashlight Brightness"
|
||||||
set category = "Object"
|
set category = "Object"
|
||||||
|
|||||||
@@ -10,44 +10,162 @@
|
|||||||
var/insults = 0
|
var/insults = 0
|
||||||
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!")
|
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!")
|
||||||
|
|
||||||
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
|
/obj/item/device/megaphone/proc/can_broadcast(var/mob/living/user)
|
||||||
if (user.client)
|
if (user.client)
|
||||||
if(user.client.prefs.muted & MUTE_IC)
|
if(user.client.prefs.muted & MUTE_IC)
|
||||||
src << "<span class='warning'>You cannot speak in IC (muted).</span>"
|
to_chat(user, "<span class='warning'>You cannot speak in IC (muted).</span>")
|
||||||
return
|
return 0
|
||||||
if(!ishuman(user))
|
if(!(ishuman(user) || user.isSynthetic()))
|
||||||
user << "<span class='warning'>You don't know how to use this!</span>"
|
to_chat(user, "<span class='warning'>You don't know how to use this!</span>")
|
||||||
return
|
return 0
|
||||||
if(user.silent)
|
if(user.silent)
|
||||||
return
|
return 0
|
||||||
if(spamcheck)
|
if(spamcheck)
|
||||||
user << "<span class='warning'>\The [src] needs to recharge!</span>"
|
to_chat(user, "<span class='warning'>\The [src] needs to recharge!</span>")
|
||||||
return
|
return 0
|
||||||
|
return 1
|
||||||
|
|
||||||
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
|
/obj/item/device/megaphone/proc/do_broadcast(var/mob/living/user, var/message)
|
||||||
if(!message)
|
|
||||||
return
|
|
||||||
message = capitalize(message)
|
|
||||||
if ((src.loc == user && usr.stat == 0))
|
if ((src.loc == user && usr.stat == 0))
|
||||||
if(emagged)
|
if(emagged)
|
||||||
if(insults)
|
if(insults)
|
||||||
for(var/mob/O in (viewers(user)))
|
user.audible_message("<B>[user]</B> broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>")
|
||||||
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>",2) // 2 stands for hearable message
|
|
||||||
insults--
|
insults--
|
||||||
else
|
else
|
||||||
user << "<span class='warning'>*BZZZZzzzzzt*</span>"
|
to_chat(user, "<span class='warning'>*BZZZZzzzzzt*</span>")
|
||||||
else
|
else
|
||||||
for(var/mob/O in (viewers(user)))
|
user.audible_message("<B>[user]</B> broadcasts, <FONT size=3>\"[message]\"</FONT>")
|
||||||
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[message]\"</FONT>",2) // 2 stands for hearable message
|
|
||||||
|
|
||||||
spamcheck = 1
|
spamcheck = 1
|
||||||
spawn(20)
|
spawn(20)
|
||||||
spamcheck = 0
|
spamcheck = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
|
||||||
|
if(!can_broadcast(user))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
|
||||||
|
if(!message)
|
||||||
|
return
|
||||||
|
message = capitalize(message)
|
||||||
|
|
||||||
|
do_broadcast(user, message)
|
||||||
|
|
||||||
/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
|
/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
|
||||||
if(!emagged)
|
if(!emagged)
|
||||||
user << "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>"
|
to_chat(user, "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>")
|
||||||
emagged = 1
|
emagged = 1
|
||||||
insults = rand(1, 3)//to prevent dickflooding
|
insults = rand(1, 3)//to prevent caps spam.
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super
|
||||||
|
name = "gigaphone"
|
||||||
|
desc = "A device used to project your voice. Loudly-er."
|
||||||
|
icon_state = "gigaphone"
|
||||||
|
|
||||||
|
var/broadcast_font = "verdana"
|
||||||
|
var/broadcast_size = 3
|
||||||
|
var/broadcast_color = "#000000" //Black by default.
|
||||||
|
var/list/volume_options = list(2, 3, 4)
|
||||||
|
var/list/font_options = list("times new roman", "times", "verdana", "sans-serif", "serif", "georgia")
|
||||||
|
var/list/color_options= list("#000000", "#ff0000", "#00ff00", "#0000ff")
|
||||||
|
|
||||||
|
insultmsg = list("HONK?!", "HONK!", "HOOOOOOOONK!", "...!", "HUNK.", "Honk?")
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/emag_act(var/remaining_charges, var/mob/user)
|
||||||
|
..()
|
||||||
|
if(emagged)
|
||||||
|
if(!(11 in volume_options))
|
||||||
|
volume_options = list(11)
|
||||||
|
broadcast_size = 11
|
||||||
|
if(!("comic sans ms" in font_options))
|
||||||
|
font_options = list("comic sans ms")
|
||||||
|
broadcast_font = "comic sans ms"
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] emits a <font face='comic sans ms' color='#ff69b4'>silly</font> sound.</span>")
|
||||||
|
if(!("#ff69b4" in color_options))
|
||||||
|
color_options = list("#ff69b4")
|
||||||
|
broadcast_color = "#ff69b4"
|
||||||
|
if(insults <= 0)
|
||||||
|
insults = rand(1,3)
|
||||||
|
to_chat(user, "<span class='warning'>You re-scramble \the [src]'s voice synthesizer.</span>")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/verb/turn_volume_dial()
|
||||||
|
set name = "Change Volume"
|
||||||
|
set desc = "Allows you to change the megaphone's volume."
|
||||||
|
set category = "Object"
|
||||||
|
|
||||||
|
adjust_volume(usr)
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/proc/adjust_volume(var/mob/living/user)
|
||||||
|
var/new_volume = input(user, "Set Volume") as null|anything in volume_options
|
||||||
|
|
||||||
|
if(new_volume && Adjacent(user))
|
||||||
|
broadcast_size = new_volume
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/verb/change_font()
|
||||||
|
set name = "Change... Pronunciation?"
|
||||||
|
set desc = "Allows you to change the megaphone's font."
|
||||||
|
set category = "Object"
|
||||||
|
|
||||||
|
adjust_font(usr)
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/proc/adjust_font(var/mob/living/user)
|
||||||
|
var/new_font = input(user, "Set Volume") as null|anything in font_options
|
||||||
|
|
||||||
|
if(new_font && Adjacent(user))
|
||||||
|
broadcast_font = new_font
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/verb/change_color()
|
||||||
|
set name = "Change... Tune?"
|
||||||
|
set desc = "Allows you to change the megaphone's color."
|
||||||
|
set category = "Object"
|
||||||
|
|
||||||
|
adjust_color(usr)
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/proc/adjust_color(var/mob/living/user)
|
||||||
|
var/new_color = input(user, "Set Volume") as null|anything in color_options
|
||||||
|
|
||||||
|
if(new_color && Adjacent(user))
|
||||||
|
broadcast_color = new_color
|
||||||
|
|
||||||
|
/obj/item/device/megaphone/super/do_broadcast(var/mob/living/user, var/message)
|
||||||
|
if ((src.loc == user && usr.stat == 0))
|
||||||
|
if(emagged)
|
||||||
|
if(insults)
|
||||||
|
user.audible_message("<B>[user]</B> broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[pick(insultmsg)]\"</FONT>")
|
||||||
|
if(broadcast_size >= 11)
|
||||||
|
var/turf/T = get_turf(user)
|
||||||
|
playsound(T, 'sound/items/AirHorn.ogg', 100, 1)
|
||||||
|
for(var/mob/living/carbon/M in oviewers(4, T))
|
||||||
|
if(M.get_ear_protection() >= 2)
|
||||||
|
continue
|
||||||
|
M.sleeping = 0
|
||||||
|
M.stuttering += 20
|
||||||
|
M.ear_deaf += 30
|
||||||
|
M.Weaken(3)
|
||||||
|
if(prob(30))
|
||||||
|
M.Stun(10)
|
||||||
|
M.Paralyse(4)
|
||||||
|
else
|
||||||
|
M.make_jittery(50)
|
||||||
|
insults--
|
||||||
|
else
|
||||||
|
user.audible_message("<span class='critical'>*BZZZZzzzzzt*</span>")
|
||||||
|
if(prob(40) && insults <= 0)
|
||||||
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||||
|
s.set_up(2, 1, get_turf(user))
|
||||||
|
s.start()
|
||||||
|
user.visible_message("<span class='warning'>\The [src] sparks violently!</span>")
|
||||||
|
spawn(30)
|
||||||
|
explosion(get_turf(src), -1, -1, 1, 3, adminlog = 1)
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
user.audible_message("<B>[user]</B> broadcasts, <FONT size=[broadcast_size] face='[broadcast_font]' color='[broadcast_color]'>\"[message]\"</FONT>")
|
||||||
|
|
||||||
|
spamcheck = 1
|
||||||
|
spawn(20)
|
||||||
|
spamcheck = 0
|
||||||
|
return
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ var/global/list/active_radio_jammers = list()
|
|||||||
qdel_null(power_source)
|
qdel_null(power_source)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
/obj/item/device/radio_jammer/get_cell()
|
||||||
|
return power_source
|
||||||
|
|
||||||
/obj/item/device/radio_jammer/proc/turn_off(mob/user)
|
/obj/item/device/radio_jammer/proc/turn_off(mob/user)
|
||||||
if(user)
|
if(user)
|
||||||
to_chat(user,"<span class='warning'>\The [src] deactivates.</span>")
|
to_chat(user,"<span class='warning'>\The [src] deactivates.</span>")
|
||||||
|
|||||||
@@ -52,8 +52,9 @@
|
|||||||
|
|
||||||
/obj/structure/largecrate/animal/crashedshuttle
|
/obj/structure/largecrate/animal/crashedshuttle
|
||||||
name = "SCP"
|
name = "SCP"
|
||||||
|
|
||||||
/obj/structure/largecrate/animal/crashedshuttle/initialize()
|
/obj/structure/largecrate/animal/crashedshuttle/initialize()
|
||||||
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble)
|
starts_with = pick(/mob/living/simple_animal/hostile/statue, /obj/item/cursed_marble, /obj/item/weapon/deadringer)
|
||||||
name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)")
|
name = pick("Spicy Crust Pizzeria", "Soap and Care Products", "Sally's Computer Parts", "Steve's Chocolate Pastries", "Smith & Christian's Plastics","Standard Containers & Packaging Co.", "Sanitary Chemical Purgation (LTD)")
|
||||||
name += " delivery crate"
|
name += " delivery crate"
|
||||||
return ..()
|
return ..()
|
||||||
|
|||||||
@@ -199,3 +199,9 @@
|
|||||||
throw_range = 20
|
throw_range = 20
|
||||||
flags = 0
|
flags = 0
|
||||||
no_variants = FALSE
|
no_variants = FALSE
|
||||||
|
|
||||||
|
/obj/item/stack/tile/roofing
|
||||||
|
name = "roofing"
|
||||||
|
singular_name = "roofing"
|
||||||
|
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
|
||||||
|
icon_state = "techtile_grid"
|
||||||
@@ -1042,6 +1042,50 @@
|
|||||||
name = "tuxedo cat plushie"
|
name = "tuxedo cat plushie"
|
||||||
icon_state = "tuxedocat"
|
icon_state = "tuxedocat"
|
||||||
|
|
||||||
|
// nah, squids are better than foxes :>
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/green
|
||||||
|
name = "green squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is green."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "greensquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/mint
|
||||||
|
name = "mint squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is mint coloured."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "mintsquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/blue
|
||||||
|
name = "blue squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is blue."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "bluesquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/orange
|
||||||
|
name = "orange squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is orange."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "orangesquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/yellow
|
||||||
|
name = "yellow squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is yellow."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "yellowsquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
|
/obj/item/toy/plushie/squid/pink
|
||||||
|
name = "pink squid plushie"
|
||||||
|
desc = "A small, cute and loveable squid friend. This one is pink."
|
||||||
|
icon = 'icons/obj/toy.dmi'
|
||||||
|
icon_state = "pinksquid"
|
||||||
|
slot_flags = SLOT_HEAD
|
||||||
|
|
||||||
/obj/item/toy/plushie/therapy/red
|
/obj/item/toy/plushie/therapy/red
|
||||||
name = "red therapy doll"
|
name = "red therapy doll"
|
||||||
desc = "A toy for therapeutic and recreational purposes. This one is red."
|
desc = "A toy for therapeutic and recreational purposes. This one is red."
|
||||||
|
|||||||
@@ -153,7 +153,7 @@
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(build_turf)
|
if(build_turf)
|
||||||
T.ChangeTurf(build_turf)
|
T.ChangeTurf(build_turf, preserve_outdoors = TRUE)
|
||||||
else if(build_other)
|
else if(build_other)
|
||||||
new build_other(T)
|
new build_other(T)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -167,21 +167,24 @@
|
|||||||
if(!istype(M))
|
if(!istype(M))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
if (user.a_intent == I_HELP)
|
||||||
|
return ..()
|
||||||
|
|
||||||
if(target_name != M.name)
|
if(target_name != M.name)
|
||||||
target_name = M.name
|
target_name = M.name
|
||||||
src.wdata = list()
|
src.wdata = list()
|
||||||
src.chemtraces = list()
|
src.chemtraces = list()
|
||||||
src.timeofdeath = null
|
src.timeofdeath = null
|
||||||
user << "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>"
|
to_chat(user, "<span class='notice'>A new patient has been registered. Purging data for previous patient.</span>")
|
||||||
|
|
||||||
src.timeofdeath = M.timeofdeath
|
src.timeofdeath = M.timeofdeath
|
||||||
|
|
||||||
var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting)
|
var/obj/item/organ/external/S = M.get_organ(user.zone_sel.selecting)
|
||||||
if(!S)
|
if(!S)
|
||||||
usr << "<span class='warning'>You can't scan this body part.</span>"
|
to_chat(user, "<span class='warning'>You can't scan this body part.</span>")
|
||||||
return
|
return
|
||||||
if(!S.open)
|
if(!S.open)
|
||||||
usr << "<span class='warning'>You have to cut [S] open first!</span>"
|
to_chat(user, "<span class='warning'>You have to cut [S] open first!</span>")
|
||||||
return
|
return
|
||||||
M.visible_message("<span class='notice'>\The [user] scans the wounds on [M]'s [S.name] with [src]</span>")
|
M.visible_message("<span class='notice'>\The [user] scans the wounds on [M]'s [S.name] with [src]</span>")
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,26 @@
|
|||||||
/obj/item/weapon/implant/proc/activate()
|
/obj/item/weapon/implant/proc/activate()
|
||||||
return
|
return
|
||||||
|
|
||||||
// What does the implant do upon injection?
|
// Moves the implant where it needs to go, and tells it if there's more to be done in post_implant
|
||||||
// return 0 if the implant fails (ex. Revhead and loyalty implant.)
|
/obj/item/weapon/implant/proc/handle_implant(var/mob/source, var/target_zone = BP_TORSO)
|
||||||
// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
|
. = TRUE
|
||||||
/obj/item/weapon/implant/proc/implanted(var/mob/source)
|
imp_in = source
|
||||||
|
implanted = TRUE
|
||||||
|
if(ishuman(source))
|
||||||
|
var/mob/living/carbon/human/H = source
|
||||||
|
var/obj/item/organ/external/affected = H.get_organ(target_zone)
|
||||||
|
if(affected)
|
||||||
|
affected.implants += src
|
||||||
|
part = affected
|
||||||
|
if(part)
|
||||||
|
forceMove(part)
|
||||||
|
else
|
||||||
|
forceMove(source)
|
||||||
|
|
||||||
listening_objects |= src
|
listening_objects |= src
|
||||||
return 1
|
|
||||||
|
// Takes place after handle_implant, if that returns TRUE
|
||||||
|
/obj/item/weapon/implant/proc/post_implant(var/mob/source)
|
||||||
|
|
||||||
/obj/item/weapon/implant/proc/get_data()
|
/obj/item/weapon/implant/proc/get_data()
|
||||||
return "No information available"
|
return "No information available"
|
||||||
@@ -49,6 +63,12 @@
|
|||||||
icon_state = "implant_melted"
|
icon_state = "implant_melted"
|
||||||
malfunction = MALFUNCTION_PERMANENT
|
malfunction = MALFUNCTION_PERMANENT
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H)
|
||||||
|
if(H)
|
||||||
|
var/obj/item/organ/external/affected = H.organs_by_name[BP_HEAD]
|
||||||
|
if(handle_implant(H, affected))
|
||||||
|
post_implant(H)
|
||||||
|
|
||||||
/obj/item/weapon/implant/Destroy()
|
/obj/item/weapon/implant/Destroy()
|
||||||
if(part)
|
if(part)
|
||||||
part.implants.Remove(src)
|
part.implants.Remove(src)
|
||||||
@@ -69,6 +89,11 @@
|
|||||||
else
|
else
|
||||||
..()
|
..()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Tracking Implant
|
||||||
|
//////////////////////////////
|
||||||
GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking)
|
GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking)
|
||||||
|
|
||||||
/obj/item/weapon/implant/tracking
|
/obj/item/weapon/implant/tracking
|
||||||
@@ -84,9 +109,8 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
|
|||||||
id = rand(1, 1000)
|
id = rand(1, 1000)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/obj/item/weapon/implant/tracking/implanted(var/mob/source)
|
/obj/item/weapon/implant/tracking/post_implant(var/mob/source)
|
||||||
processing_objects.Add(src)
|
processing_objects.Add(src)
|
||||||
return 1
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/tracking/Destroy()
|
/obj/item/weapon/implant/tracking/Destroy()
|
||||||
processing_objects.Remove(src)
|
processing_objects.Remove(src)
|
||||||
@@ -142,7 +166,9 @@ Implant Specifics:<BR>"}
|
|||||||
spawn(delay)
|
spawn(delay)
|
||||||
malfunction--
|
malfunction--
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Death Explosive Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/dexplosive
|
/obj/item/weapon/implant/dexplosive
|
||||||
name = "explosive"
|
name = "explosive"
|
||||||
desc = "And boom goes the weasel."
|
desc = "And boom goes the weasel."
|
||||||
@@ -177,7 +203,9 @@ Implant Specifics:<BR>"}
|
|||||||
/obj/item/weapon/implant/dexplosive/islegal()
|
/obj/item/weapon/implant/dexplosive/islegal()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
//BS12 Explosive
|
//////////////////////////////
|
||||||
|
// Explosive Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/explosive
|
/obj/item/weapon/implant/explosive
|
||||||
name = "explosive implant"
|
name = "explosive implant"
|
||||||
desc = "A military grade micro bio-explosive. Highly dangerous."
|
desc = "A military grade micro bio-explosive. Highly dangerous."
|
||||||
@@ -249,15 +277,13 @@ Implant Specifics:<BR>"}
|
|||||||
if(t)
|
if(t)
|
||||||
t.hotspot_expose(3500,125)
|
t.hotspot_expose(3500,125)
|
||||||
|
|
||||||
/obj/item/weapon/implant/explosive/implanted(mob/source as mob)
|
/obj/item/weapon/implant/explosive/post_implant(mob/source as mob)
|
||||||
elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
|
elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
|
||||||
phrase = input("Choose activation phrase:") as text
|
phrase = input("Choose activation phrase:") as text
|
||||||
var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
|
var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
|
||||||
phrase = replace_characters(phrase, replacechars)
|
phrase = replace_characters(phrase, replacechars)
|
||||||
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate.", 0, 0)
|
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate.", 0, 0)
|
||||||
usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate."
|
usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', <B>say [src.phrase]</B> to attempt to activate."
|
||||||
listening_objects |= src
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/explosive/emp_act(severity)
|
/obj/item/weapon/implant/explosive/emp_act(severity)
|
||||||
if (malfunction)
|
if (malfunction)
|
||||||
@@ -311,6 +337,9 @@ Implant Specifics:<BR>"}
|
|||||||
explosion(get_turf(imp_in), -1, -1, 1, 3)
|
explosion(get_turf(imp_in), -1, -1, 1, 3)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Chemical Implant
|
||||||
|
//////////////////////////////
|
||||||
GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem)
|
GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem)
|
||||||
|
|
||||||
/obj/item/weapon/implant/chem
|
/obj/item/weapon/implant/chem
|
||||||
@@ -336,20 +365,17 @@ Can only be loaded while still in its original case.<BR>
|
|||||||
the implant may become unstable and either pre-maturely inject the subject or simply break."}
|
the implant may become unstable and either pre-maturely inject the subject or simply break."}
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/chem/New()
|
/obj/item/weapon/implant/chem/New()
|
||||||
..()
|
..()
|
||||||
var/datum/reagents/R = new/datum/reagents(50)
|
var/datum/reagents/R = new/datum/reagents(50)
|
||||||
reagents = R
|
reagents = R
|
||||||
R.my_atom = src
|
R.my_atom = src
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/chem/trigger(emote, source as mob)
|
/obj/item/weapon/implant/chem/trigger(emote, source as mob)
|
||||||
if(emote == "deathgasp")
|
if(emote == "deathgasp")
|
||||||
src.activate(src.reagents.total_volume)
|
src.activate(src.reagents.total_volume)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/chem/activate(var/cause)
|
/obj/item/weapon/implant/chem/activate(var/cause)
|
||||||
if((!cause) || (!src.imp_in)) return 0
|
if((!cause) || (!src.imp_in)) return 0
|
||||||
var/mob/living/carbon/R = src.imp_in
|
var/mob/living/carbon/R = src.imp_in
|
||||||
@@ -384,6 +410,9 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
|||||||
spawn(20)
|
spawn(20)
|
||||||
malfunction--
|
malfunction--
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Loyalty Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/loyalty
|
/obj/item/weapon/implant/loyalty
|
||||||
name = "loyalty implant"
|
name = "loyalty implant"
|
||||||
desc = "Makes you loyal or such."
|
desc = "Makes you loyal or such."
|
||||||
@@ -401,20 +430,24 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
|||||||
<b>Integrity:</b> Implant will last so long as the nanobots are inside the bloodstream."}
|
<b>Integrity:</b> Implant will last so long as the nanobots are inside the bloodstream."}
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/loyalty/handle_implant(mob/M, target_zone = BP_TORSO)
|
||||||
/obj/item/weapon/implant/loyalty/implanted(mob/M)
|
. = ..(M, target_zone)
|
||||||
if(!istype(M, /mob/living/carbon/human)) return 0
|
if(!istype(M, /mob/living/carbon/human))
|
||||||
|
. = FALSE
|
||||||
var/mob/living/carbon/human/H = M
|
var/mob/living/carbon/human/H = M
|
||||||
var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
|
var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
|
||||||
if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
|
if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
|
||||||
H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [using_map.company_name] try to invade your mind!")
|
H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [using_map.company_name] try to invade your mind!")
|
||||||
return 0
|
. = FALSE
|
||||||
else
|
|
||||||
clear_antag_roles(H.mind, 1)
|
|
||||||
H << "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>"
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/loyalty/post_implant(mob/M)
|
||||||
|
var/mob/living/carbon/human/H = M
|
||||||
|
clear_antag_roles(H.mind, 1)
|
||||||
|
to_chat(H, "<span class='notice'>You feel a surge of loyalty towards [using_map.company_name].</span>")
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Adrenaline Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/adrenalin
|
/obj/item/weapon/implant/adrenalin
|
||||||
name = "adrenalin"
|
name = "adrenalin"
|
||||||
desc = "Removes all stuns and knockdowns."
|
desc = "Removes all stuns and knockdowns."
|
||||||
@@ -445,14 +478,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/adrenalin/post_implant(mob/source)
|
||||||
/obj/item/weapon/implant/adrenalin/implanted(mob/source)
|
|
||||||
source.mind.store_memory("A implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate.", 0, 0)
|
source.mind.store_memory("A implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate.", 0, 0)
|
||||||
source << "The implanted freedom implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate."
|
source << "The implanted freedom implant can be activated by using the pale emote, <B>say *pale</B> to attempt to activate."
|
||||||
listening_objects |= src
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Death Alarm Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/death_alarm
|
/obj/item/weapon/implant/death_alarm
|
||||||
name = "death alarm implant"
|
name = "death alarm implant"
|
||||||
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
|
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
|
||||||
@@ -529,11 +561,13 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
|||||||
spawn(20)
|
spawn(20)
|
||||||
malfunction--
|
malfunction--
|
||||||
|
|
||||||
/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob)
|
/obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob)
|
||||||
mobname = source.real_name
|
mobname = source.real_name
|
||||||
processing_objects.Add(src)
|
processing_objects.Add(src)
|
||||||
return 1
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Compressed Matter Implant
|
||||||
|
//////////////////////////////
|
||||||
/obj/item/weapon/implant/compressed
|
/obj/item/weapon/implant/compressed
|
||||||
name = "compressed matter implant"
|
name = "compressed matter implant"
|
||||||
desc = "Based on compressed matter technology, can store a single item."
|
desc = "Based on compressed matter technology, can store a single item."
|
||||||
@@ -571,13 +605,12 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
|||||||
scanned.loc = t
|
scanned.loc = t
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/item/weapon/implant/compressed/implanted(mob/source as mob)
|
/obj/item/weapon/implant/compressed/post_implant(mob/source)
|
||||||
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
|
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
|
||||||
if (source.mind)
|
if (source.mind)
|
||||||
source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
||||||
source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
||||||
listening_objects |= src
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/compressed/islegal()
|
/obj/item/weapon/implant/compressed/islegal()
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -135,10 +135,9 @@
|
|||||||
for (var/mob/O in viewers(M, null))
|
for (var/mob/O in viewers(M, null))
|
||||||
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
|
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
|
||||||
|
|
||||||
if(imp.implanted(M))
|
if(imp.handle_implant(M, BP_TORSO))
|
||||||
imp.loc = M
|
imp.post_implant(M)
|
||||||
imp.imp_in = M
|
|
||||||
imp.implanted = 1
|
|
||||||
implant_list -= imp
|
implant_list -= imp
|
||||||
break
|
break
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -56,16 +56,11 @@
|
|||||||
|
|
||||||
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
|
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
|
||||||
|
|
||||||
if(src.imp.implanted(M))
|
if(imp.handle_implant(M))
|
||||||
src.imp.loc = M
|
imp.post_implant(M)
|
||||||
src.imp.imp_in = M
|
|
||||||
src.imp.implanted = 1
|
|
||||||
if (ishuman(M))
|
|
||||||
var/mob/living/carbon/human/H = M
|
|
||||||
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
|
|
||||||
affected.implants += src.imp
|
|
||||||
imp.part = affected
|
|
||||||
|
|
||||||
|
if(ishuman(M))
|
||||||
|
var/mob/living/carbon/human/H = M
|
||||||
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
|
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
|
||||||
|
|
||||||
src.imp = null
|
src.imp = null
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
|
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
|
||||||
if (src.uses < 1) return 0
|
if (src.uses < 1)
|
||||||
|
return 0
|
||||||
|
|
||||||
if (emote == src.activation_emote)
|
if (emote == src.activation_emote)
|
||||||
src.uses--
|
src.uses--
|
||||||
source << "You feel a faint click."
|
source << "You feel a faint click."
|
||||||
@@ -46,13 +48,9 @@
|
|||||||
W.layer = initial(W.layer)
|
W.layer = initial(W.layer)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/freedom/post_implant(mob/source)
|
||||||
/obj/item/weapon/implant/freedom/implanted(mob/living/carbon/source)
|
|
||||||
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
||||||
source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
||||||
listening_objects |= src
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/freedom/get_data()
|
/obj/item/weapon/implant/freedom/get_data()
|
||||||
var/dat = {"
|
var/dat = {"
|
||||||
|
|||||||
@@ -4,7 +4,26 @@
|
|||||||
|
|
||||||
/obj/item/weapon/implant/language
|
/obj/item/weapon/implant/language
|
||||||
name = "GalCom language implant"
|
name = "GalCom language implant"
|
||||||
desc = "An implant allowing someone to speak and hear the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
|
desc = "An implant allowing someone to speak the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with producing sounds, not understanding them."
|
||||||
|
var/list/languages = list(LANGUAGE_GALCOM) // List of languages that this assists with
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/language/post_implant(mob/M) // Amends the mob's voice organ, then deletes itself
|
||||||
|
if(ishuman(M))
|
||||||
|
var/mob/living/carbon/human/H = M
|
||||||
|
var/obj/item/organ/internal/voicebox/V = locate() in H.internal_organs
|
||||||
|
if(V)
|
||||||
|
var/list/need_amend = list() // If they've already got all the languages they need, then they don't need this implant to do anything
|
||||||
|
for(var/L in languages)
|
||||||
|
if(L in V.will_assist_languages)
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
need_amend |= L
|
||||||
|
if(LAZYLEN(need_amend))
|
||||||
|
if(V.robotic < ORGAN_ASSISTED)
|
||||||
|
V.mechassist()
|
||||||
|
for(var/L in need_amend)
|
||||||
|
V.add_assistable_langs(L)
|
||||||
|
qdel_null(src)
|
||||||
|
|
||||||
/obj/item/weapon/implant/language/get_data()
|
/obj/item/weapon/implant/language/get_data()
|
||||||
var/dat = {"
|
var/dat = {"
|
||||||
@@ -14,16 +33,19 @@
|
|||||||
<b>Important Notes:</b> Affects hearing and speech.<BR>
|
<b>Important Notes:</b> Affects hearing and speech.<BR>
|
||||||
<HR>
|
<HR>
|
||||||
<b>Implant Details:</b><BR>
|
<b>Implant Details:</b><BR>
|
||||||
<b>Function:</b> Allows a being otherwise incapable to both hear the frequencies Galactic Common is generally spoken at, as well as to produce the phonemes of the language.<BR>
|
<b>Function:</b> Allows a being otherwise incapable of speaking Galactic Common to produce the phonemes of the language.<BR>
|
||||||
<b>Special Features:</b> None.<BR>
|
<b>Special Features:</b> None.<BR>
|
||||||
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
|
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
|
|
||||||
|
// EAL Implant
|
||||||
/obj/item/weapon/implant/language/eal
|
/obj/item/weapon/implant/language/eal
|
||||||
name = "EAL language implant"
|
name = "EAL language implant"
|
||||||
desc = "An implant allowing an organic to both hear and speak Encoded Audio Language accurately. Only helps with hearing and producing sounds, not understanding them."
|
desc = "An implant allowing an organic to speak Encoded Audio Language passably. Only helps with producing sounds, not understanding them."
|
||||||
|
languages = list(LANGUAGE_EAL)
|
||||||
|
|
||||||
/obj/item/weapon/implant/language/get_data()
|
/obj/item/weapon/implant/language/eal/get_data()
|
||||||
var/dat = {"
|
var/dat = {"
|
||||||
<b>Implant Specifications:</b><BR>
|
<b>Implant Specifications:</b><BR>
|
||||||
<b>Name:</b> Vey-Med L-2 Encoded Audio Language Implant<BR>
|
<b>Name:</b> Vey-Med L-2 Encoded Audio Language Implant<BR>
|
||||||
@@ -31,7 +53,25 @@
|
|||||||
<b>Important Notes:</b> Affects hearing and speech.<BR>
|
<b>Important Notes:</b> Affects hearing and speech.<BR>
|
||||||
<HR>
|
<HR>
|
||||||
<b>Implant Details:</b><BR>
|
<b>Implant Details:</b><BR>
|
||||||
<b>Function:</b> Allows an organic to accurately process and speak Encoded Audio Language.<BR>
|
<b>Function:</b> Allows an organic to accurately speak Encoded Audio Language.<BR>
|
||||||
|
<b>Special Features:</b> None.<BR>
|
||||||
|
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
|
||||||
|
return dat
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/language/skrellian
|
||||||
|
name = "Skrellian language implant"
|
||||||
|
desc = "An implant allowing someone to speak the range of frequencies used in Skrellian, as well as produce any phonemes that they usually cannot. Only helps with hearing and producing sounds, not understanding them."
|
||||||
|
languages = list(LANGUAGE_SKRELLIAN)
|
||||||
|
|
||||||
|
/obj/item/weapon/implant/language/skrellian/get_data()
|
||||||
|
var/dat = {"
|
||||||
|
<b>Implant Specifications:</b><BR>
|
||||||
|
<b>Name:</b> Vey-Med L-1 Galactic Common Implant<BR>
|
||||||
|
<b>Life:</b> 5 years<BR>
|
||||||
|
<b>Important Notes:</b> Affects hearing and speech.<BR>
|
||||||
|
<HR>
|
||||||
|
<b>Implant Details:</b><BR>
|
||||||
|
<b>Function:</b> Allows a being otherwise incapable of speaking Skrellian to produce the phonemes of the language.<BR>
|
||||||
<b>Special Features:</b> None.<BR>
|
<b>Special Features:</b> None.<BR>
|
||||||
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
|
<b>Integrity:</b> Implant will function for expected life, barring physical damage."}
|
||||||
return dat
|
return dat
|
||||||
@@ -11,15 +11,13 @@
|
|||||||
..()
|
..()
|
||||||
return
|
return
|
||||||
|
|
||||||
/obj/item/weapon/implant/uplink/implanted(mob/source)
|
/obj/item/weapon/implant/uplink/post_implant(mob/source)
|
||||||
|
listening_objects |= src
|
||||||
activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
|
activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
|
||||||
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
|
||||||
source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate."
|
||||||
listening_objects |= src
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
|
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
|
||||||
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
|
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
|
||||||
hidden_uplink.check_trigger(source, emote, activation_emote)
|
hidden_uplink.check_trigger(source, emote, activation_emote)
|
||||||
return
|
return
|
||||||
@@ -16,6 +16,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/weapon/mop)
|
|||||||
|
|
||||||
/obj/item/weapon/mop/New()
|
/obj/item/weapon/mop/New()
|
||||||
create_reagents(30)
|
create_reagents(30)
|
||||||
|
..()
|
||||||
|
|
||||||
/obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity)
|
/obj/item/weapon/mop/afterattack(atom/A, mob/user, proximity)
|
||||||
if(!proximity) return
|
if(!proximity) return
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
icon = 'icons/policetape.dmi'
|
icon = 'icons/policetape.dmi'
|
||||||
icon_state = "tape"
|
icon_state = "tape"
|
||||||
w_class = ITEMSIZE_SMALL
|
w_class = ITEMSIZE_SMALL
|
||||||
|
|
||||||
|
toolspeed = 3 //You can use it in surgery. It's stupid, but you can.
|
||||||
|
|
||||||
var/turf/start
|
var/turf/start
|
||||||
var/turf/end
|
var/turf/end
|
||||||
var/tape_type = /obj/item/tape
|
var/tape_type = /obj/item/tape
|
||||||
|
|||||||
@@ -86,7 +86,6 @@
|
|||||||
/obj/item/weapon/weldingtool,
|
/obj/item/weapon/weldingtool,
|
||||||
/obj/item/weapon/tool/crowbar,
|
/obj/item/weapon/tool/crowbar,
|
||||||
/obj/item/weapon/tool/wirecutters,
|
/obj/item/weapon/tool/wirecutters,
|
||||||
/obj/item/device/t_scanner
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/obj/item/weapon/storage/belt/utility/chief
|
/obj/item/weapon/storage/belt/utility/chief
|
||||||
|
|||||||
@@ -19,16 +19,19 @@
|
|||||||
var/obj/item/weapon/cell/bcell = null
|
var/obj/item/weapon/cell/bcell = null
|
||||||
var/hitcost = 240
|
var/hitcost = 240
|
||||||
|
|
||||||
/obj/item/weapon/melee/baton/suicide_act(mob/user)
|
|
||||||
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
|
|
||||||
user.visible_message("<span class='suicide'>\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
|
|
||||||
return (FIRELOSS)
|
|
||||||
|
|
||||||
/obj/item/weapon/melee/baton/New()
|
/obj/item/weapon/melee/baton/New()
|
||||||
..()
|
..()
|
||||||
update_icon()
|
update_icon()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/melee/baton/get_cell()
|
||||||
|
return bcell
|
||||||
|
|
||||||
|
/obj/item/weapon/melee/baton/suicide_act(mob/user)
|
||||||
|
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
|
||||||
|
user.visible_message("<span class='suicide'>\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
|
||||||
|
return (FIRELOSS)
|
||||||
|
|
||||||
/obj/item/weapon/melee/baton/MouseDrop(obj/over_object as obj)
|
/obj/item/weapon/melee/baton/MouseDrop(obj/over_object as obj)
|
||||||
if(!canremove)
|
if(!canremove)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
icon_state = "taperoll"
|
icon_state = "taperoll"
|
||||||
w_class = ITEMSIZE_TINY
|
w_class = ITEMSIZE_TINY
|
||||||
|
|
||||||
|
toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed.
|
||||||
|
|
||||||
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
|
/obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user)
|
||||||
if(istype(H))
|
if(istype(H))
|
||||||
|
if(user.a_intent == I_HELP)
|
||||||
|
return
|
||||||
var/can_place = 0
|
var/can_place = 0
|
||||||
if(istype(user, /mob/living/silicon/robot))
|
if(istype(user, /mob/living/silicon/robot))
|
||||||
can_place = 1
|
can_place = 1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define WELDER_FUEL_BURN_INTERVAL 13
|
|
||||||
|
|
||||||
|
#define WELDER_FUEL_BURN_INTERVAL 13
|
||||||
/*
|
/*
|
||||||
* Welding Tool
|
* Welding Tool
|
||||||
*/
|
*/
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob)
|
/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob)
|
||||||
if(W.is_screwdriver())
|
if(istype(W,/obj/item/weapon/tool/screwdriver))
|
||||||
if(welding)
|
if(welding)
|
||||||
to_chat(user, "<span class='danger'>Stop welding first!</span>")
|
to_chat(user, "<span class='danger'>Stop welding first!</span>")
|
||||||
return
|
return
|
||||||
@@ -99,12 +99,15 @@
|
|||||||
..()
|
..()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/process()
|
/obj/item/weapon/weldingtool/process()
|
||||||
if(welding)
|
if(welding)
|
||||||
++burned_fuel_for
|
++burned_fuel_for
|
||||||
if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL)
|
if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL)
|
||||||
remove_fuel(1)
|
remove_fuel(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(get_fuel() < 1)
|
if(get_fuel() < 1)
|
||||||
setWelding(0)
|
setWelding(0)
|
||||||
|
|
||||||
@@ -118,6 +121,7 @@
|
|||||||
if (istype(location, /turf))
|
if (istype(location, /turf))
|
||||||
location.hotspot_expose(700, 5)
|
location.hotspot_expose(700, 5)
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity)
|
/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity)
|
||||||
if(!proximity) return
|
if(!proximity) return
|
||||||
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1)
|
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1)
|
||||||
@@ -146,6 +150,7 @@
|
|||||||
location.hotspot_expose(700, 50, 1)
|
location.hotspot_expose(700, 50, 1)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/attack_self(mob/user as mob)
|
/obj/item/weapon/weldingtool/attack_self(mob/user as mob)
|
||||||
setWelding(!welding, usr)
|
setWelding(!welding, usr)
|
||||||
return
|
return
|
||||||
@@ -209,24 +214,6 @@
|
|||||||
M.update_inv_l_hand()
|
M.update_inv_l_hand()
|
||||||
M.update_inv_r_hand()
|
M.update_inv_r_hand()
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone)
|
|
||||||
if(ishuman(A) && user.a_intent == I_HELP)
|
|
||||||
var/mob/living/carbon/human/H = A
|
|
||||||
var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting]
|
|
||||||
|
|
||||||
if(!S || S.robotic < ORGAN_ROBOT || S.open == 3)
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
if(!welding)
|
|
||||||
to_chat(user, "<span class='warning'>You'll need to turn [src] on to patch the damage on [H]'s [S.name]!</span>")
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(S.robo_repair(15, BRUTE, "some dents", src, user))
|
|
||||||
remove_fuel(1, user)
|
|
||||||
|
|
||||||
else
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/MouseDrop(obj/over_object as obj)
|
/obj/item/weapon/weldingtool/MouseDrop(obj/over_object as obj)
|
||||||
if(!canremove)
|
if(!canremove)
|
||||||
return
|
return
|
||||||
@@ -349,9 +336,6 @@
|
|||||||
/obj/item/weapon/weldingtool/is_hot()
|
/obj/item/weapon/weldingtool/is_hot()
|
||||||
return isOn()
|
return isOn()
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/is_welder()
|
|
||||||
return TRUE
|
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/largetank
|
/obj/item/weapon/weldingtool/largetank
|
||||||
name = "industrial welding tool"
|
name = "industrial welding tool"
|
||||||
desc = "A slightly larger welder with a larger tank."
|
desc = "A slightly larger welder with a larger tank."
|
||||||
@@ -495,6 +479,9 @@
|
|||||||
acti_sound = 'sound/effects/sparks4.ogg'
|
acti_sound = 'sound/effects/sparks4.ogg'
|
||||||
deac_sound = 'sound/effects/sparks4.ogg'
|
deac_sound = 'sound/effects/sparks4.ogg'
|
||||||
|
|
||||||
|
/obj/item/weapon/weldingtool/electric/unloaded/New()
|
||||||
|
cell_type = null
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/electric/New()
|
/obj/item/weapon/weldingtool/electric/New()
|
||||||
..()
|
..()
|
||||||
if(cell_type == null)
|
if(cell_type == null)
|
||||||
@@ -505,17 +492,17 @@
|
|||||||
power_supply = new /obj/item/weapon/cell/device(src)
|
power_supply = new /obj/item/weapon/cell/device(src)
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/electric/unloaded/New()
|
/obj/item/weapon/weldingtool/electric/get_cell()
|
||||||
cell_type = null
|
return power_supply
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/electric/examine(mob/user)
|
/obj/item/weapon/weldingtool/electric/examine(mob/user)
|
||||||
if(get_dist(src, user) > 1)
|
if(get_dist(src, user) > 1)
|
||||||
to_chat(user, desc)
|
to_chat(user, desc)
|
||||||
else // The << need to stay, for some reason
|
else // The << need to stay, for some reason
|
||||||
if(power_supply)
|
if(power_supply)
|
||||||
to_chat(user, text("\icon[] The [] has [] charge left.", src, src.name, get_fuel()))
|
user << text("\icon[] The [] has [] charge left.", src, src.name, get_fuel())
|
||||||
else
|
else
|
||||||
to_chat(user, text("\icon[] The [] has no power cell!", src, src.name))
|
user << text("\icon[] The [] has no power cell!", src, src.name)
|
||||||
|
|
||||||
/obj/item/weapon/weldingtool/electric/get_fuel()
|
/obj/item/weapon/weldingtool/electric/get_fuel()
|
||||||
if(use_external_power)
|
if(use_external_power)
|
||||||
|
|||||||
@@ -163,3 +163,6 @@
|
|||||||
|
|
||||||
/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
|
/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/proc/get_cell()
|
||||||
|
return
|
||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
starts_with = list(/obj/item/weapon/material/twohanded/fireaxe)
|
starts_with = list(/obj/item/weapon/material/twohanded/fireaxe)
|
||||||
|
|
||||||
|
/obj/structure/closet/fireaxecabinet/initialize()
|
||||||
|
..()
|
||||||
|
fireaxe = locate() in contents
|
||||||
|
|
||||||
/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||||
//..() //That's very useful, Erro
|
//..() //That's very useful, Erro
|
||||||
|
|
||||||
@@ -115,6 +119,7 @@
|
|||||||
if(src.locked)
|
if(src.locked)
|
||||||
to_chat(user, "<span class='warning'>The cabinet won't budge!</span>")
|
to_chat(user, "<span class='warning'>The cabinet won't budge!</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
if(localopened)
|
if(localopened)
|
||||||
if(fireaxe)
|
if(fireaxe)
|
||||||
user.put_in_hands(fireaxe)
|
user.put_in_hands(fireaxe)
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
anchored = 1
|
anchored = 1
|
||||||
density = 1
|
density = 1
|
||||||
pixel_x = -16
|
pixel_x = -16
|
||||||
layer = MOB_LAYER // You know what, let's play it safe.
|
plane = MOB_PLANE // You know what, let's play it safe.
|
||||||
|
layer = ABOVE_MOB_LAYER
|
||||||
var/base_state = null // Used for stumps.
|
var/base_state = null // Used for stumps.
|
||||||
var/health = 200 // Used for chopping down trees.
|
var/health = 200 // Used for chopping down trees.
|
||||||
var/max_health = 200
|
var/max_health = 200
|
||||||
@@ -51,12 +52,12 @@
|
|||||||
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
|
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
|
||||||
|
|
||||||
// Used when the tree gets hurt.
|
// Used when the tree gets hurt.
|
||||||
/obj/structure/flora/tree/proc/adjust_health(var/amount, var/is_ranged = FALSE)
|
/obj/structure/flora/tree/proc/adjust_health(var/amount, var/damage_wood = FALSE)
|
||||||
if(is_stump)
|
if(is_stump)
|
||||||
return
|
return
|
||||||
|
|
||||||
// Bullets and lasers ruin some of the wood
|
// Bullets and lasers ruin some of the wood
|
||||||
if(is_ranged && product_amount > 0)
|
if(damage_wood && product_amount > 0)
|
||||||
var/wood = initial(product_amount)
|
var/wood = initial(product_amount)
|
||||||
product_amount -= round(wood * (abs(amount)/max_health))
|
product_amount -= round(wood * (abs(amount)/max_health))
|
||||||
|
|
||||||
@@ -89,12 +90,16 @@
|
|||||||
set_light(0)
|
set_light(0)
|
||||||
|
|
||||||
/obj/structure/flora/tree/ex_act(var/severity)
|
/obj/structure/flora/tree/ex_act(var/severity)
|
||||||
adjust_health(-(max_health / severity))
|
adjust_health(-(max_health / severity), TRUE)
|
||||||
|
|
||||||
/obj/structure/flora/tree/bullet_act(var/obj/item/projectile/Proj)
|
/obj/structure/flora/tree/bullet_act(var/obj/item/projectile/Proj)
|
||||||
if(Proj.get_structure_damage())
|
if(Proj.get_structure_damage())
|
||||||
adjust_health(-Proj.get_structure_damage(), TRUE)
|
adjust_health(-Proj.get_structure_damage(), TRUE)
|
||||||
|
|
||||||
|
/obj/structure/flora/tree/tesla_act(power, explosive)
|
||||||
|
adjust_health(-power / 100, TRUE) // Kills most trees in one lightning strike.
|
||||||
|
..()
|
||||||
|
|
||||||
/obj/structure/flora/tree/get_description_interaction()
|
/obj/structure/flora/tree/get_description_interaction()
|
||||||
var/list/results = list()
|
var/list/results = list()
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
|||||||
|
|
||||||
/obj/structure/janitorialcart/New()
|
/obj/structure/janitorialcart/New()
|
||||||
create_reagents(300)
|
create_reagents(300)
|
||||||
|
..()
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/janitorialcart/examine(mob/user)
|
/obj/structure/janitorialcart/examine(mob/user)
|
||||||
|
|||||||
78
code/game/objects/structures/plasticflaps.dm
Normal file
78
code/game/objects/structures/plasticflaps.dm
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
|
||||||
|
name = "\improper plastic flaps"
|
||||||
|
desc = "Completely impassable - or are they?"
|
||||||
|
icon = 'icons/obj/stationobjs.dmi' //Change this.
|
||||||
|
icon_state = "plasticflaps"
|
||||||
|
density = 0
|
||||||
|
anchored = 1
|
||||||
|
layer = MOB_LAYER
|
||||||
|
plane = MOB_PLANE
|
||||||
|
explosion_resistance = 5
|
||||||
|
var/list/mobs_can_pass = list(
|
||||||
|
/mob/living/bot,
|
||||||
|
/mob/living/simple_animal/slime,
|
||||||
|
/mob/living/simple_animal/mouse,
|
||||||
|
/mob/living/silicon/robot/drone
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/attackby(obj/item/P, mob/user)
|
||||||
|
if(P.is_wirecutter())
|
||||||
|
playsound(src, P.usesound, 50, 1)
|
||||||
|
user << "<span class='notice'>You start to cut the plastic flaps.</span>"
|
||||||
|
if(do_after(user, 10 * P.toolspeed))
|
||||||
|
user << "<span class='notice'>You cut the plastic flaps.</span>"
|
||||||
|
var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc )
|
||||||
|
A.amount = 4
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
|
||||||
|
if(istype(A) && A.checkpass(PASSGLASS))
|
||||||
|
return prob(60)
|
||||||
|
|
||||||
|
var/obj/structure/bed/B = A
|
||||||
|
if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(istype(A, /obj/vehicle)) //no vehicles
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/mob/living/M = A
|
||||||
|
if(istype(M))
|
||||||
|
if(M.lying)
|
||||||
|
return ..()
|
||||||
|
for(var/mob_type in mobs_can_pass)
|
||||||
|
if(istype(A, mob_type))
|
||||||
|
return ..()
|
||||||
|
return issmall(M)
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/ex_act(severity)
|
||||||
|
switch(severity)
|
||||||
|
if (1)
|
||||||
|
qdel(src)
|
||||||
|
if (2)
|
||||||
|
if (prob(50))
|
||||||
|
qdel(src)
|
||||||
|
if (3)
|
||||||
|
if (prob(5))
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
|
||||||
|
name = "airtight plastic flaps"
|
||||||
|
desc = "Heavy duty, airtight, plastic flaps."
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/mining/New() //set the turf below the flaps to block air
|
||||||
|
var/turf/T = get_turf(loc)
|
||||||
|
if(T)
|
||||||
|
T.blocks_air = 1
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/plasticflaps/mining/Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor
|
||||||
|
var/turf/T = get_turf(loc)
|
||||||
|
if(T && istype(T, /turf/simulated/floor))
|
||||||
|
T.blocks_air = 0
|
||||||
|
..()
|
||||||
@@ -6,15 +6,6 @@
|
|||||||
icon = 'icons/obj/abductor.dmi'
|
icon = 'icons/obj/abductor.dmi'
|
||||||
density = TRUE
|
density = TRUE
|
||||||
anchored = TRUE
|
anchored = TRUE
|
||||||
var/interaction_message = null
|
|
||||||
|
|
||||||
/obj/structure/prop/alien/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
|
||||||
if(!istype(user))
|
|
||||||
return FALSE
|
|
||||||
if(!interaction_message)
|
|
||||||
return ..()
|
|
||||||
else
|
|
||||||
to_chat(user, interaction_message)
|
|
||||||
|
|
||||||
/obj/structure/prop/alien/computer
|
/obj/structure/prop/alien/computer
|
||||||
name = "alien console"
|
name = "alien console"
|
||||||
215
code/game/objects/structures/props/beam_prism.dm
Normal file
215
code/game/objects/structures/props/beam_prism.dm
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
//A series(?) of prisms for PoIs. The base one only works for beams.
|
||||||
|
|
||||||
|
/obj/structure/prop/prism
|
||||||
|
name = "prismatic turret"
|
||||||
|
desc = "A raised, externally powered 'turret'. It seems to have a massive crystal ring around its base."
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "prism"
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
|
||||||
|
layer = 3.1 //Layer over projectiles.
|
||||||
|
plane = -10 //Layer over projectiles.
|
||||||
|
|
||||||
|
var/rotation_lock = 0 // Can you rotate the prism at all?
|
||||||
|
var/free_rotate = 1 // Does the prism rotate in any direction, or only in the eight standard compass directions?
|
||||||
|
var/external_control_lock = 0 // Does the prism only rotate from the controls of an external switch?
|
||||||
|
var/degrees_from_north = 0 // How far is it rotated clockwise?
|
||||||
|
var/compass_directions = list("North" = 0, "South" = 180, "East" = 90, "West" = 270, "Northwest" = 315, "Northeast" = 45, "Southeast" = 135, "Southwest" = 225)
|
||||||
|
var/interaction_sound = 'sound/mecha/mechmove04.ogg'
|
||||||
|
|
||||||
|
var/redirect_type = /obj/item/projectile/beam
|
||||||
|
|
||||||
|
var/dialID = null
|
||||||
|
var/obj/structure/prop/prismcontrol/remote_dial = null
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The prismatic turret seems to be able to rotate.</span>"
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/initialize()
|
||||||
|
if(degrees_from_north)
|
||||||
|
animate(src, transform = turn(NORTH, degrees_from_north), time = 3)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/Destroy()
|
||||||
|
if(remote_dial)
|
||||||
|
remote_dial.my_turrets -= src
|
||||||
|
remote_dial = null
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/proc/reset_rotation()
|
||||||
|
var/degrees_to_rotate = -1 * degrees_from_north
|
||||||
|
animate(src, transform = turn(src.transform, degrees_to_rotate), time = 2)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/attack_hand(mob/living/user)
|
||||||
|
..()
|
||||||
|
|
||||||
|
if(rotation_lock)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] is locked at its current bearing.</span>")
|
||||||
|
return
|
||||||
|
if(external_control_lock)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src]'s motors resist your efforts to rotate it. You may need to find some form of controller.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/new_bearing
|
||||||
|
if(free_rotate)
|
||||||
|
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
|
||||||
|
new_bearing = round(new_bearing)
|
||||||
|
if(new_bearing <= -1 || new_bearing > 360)
|
||||||
|
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
|
||||||
|
new_bearing = round(compass_directions[choice])
|
||||||
|
|
||||||
|
var/rotate_degrees = new_bearing - degrees_from_north
|
||||||
|
|
||||||
|
if(new_bearing == 360) // Weird artifact.
|
||||||
|
new_bearing = 0
|
||||||
|
degrees_from_north = new_bearing
|
||||||
|
|
||||||
|
var/two_stage = 0
|
||||||
|
if(rotate_degrees == 180 || rotate_degrees == -180)
|
||||||
|
two_stage = 1
|
||||||
|
var/multiplier = pick(-1, 1)
|
||||||
|
rotate_degrees = multiplier * (rotate_degrees / 2)
|
||||||
|
|
||||||
|
playsound(src, interaction_sound, 50, 1)
|
||||||
|
if(two_stage)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
spawn(3)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
else
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 6) //Can't update transform because it will reset the angle.
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/proc/rotate_auto(var/new_bearing)
|
||||||
|
if(rotation_lock)
|
||||||
|
visible_message("<span class='notice'>\The [src] shudders.</span>")
|
||||||
|
playsound(src, 'sound/effects/clang.ogg', 50, 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
visible_message("<span class='notice'>\The [src] rotates to a bearing of [new_bearing].</span>")
|
||||||
|
|
||||||
|
var/rotate_degrees = new_bearing - degrees_from_north
|
||||||
|
|
||||||
|
if(new_bearing == 360)
|
||||||
|
new_bearing = 0
|
||||||
|
degrees_from_north = new_bearing
|
||||||
|
|
||||||
|
var/two_stage = 0
|
||||||
|
if(rotate_degrees == 180 || rotate_degrees == -180)
|
||||||
|
two_stage = 1
|
||||||
|
var/multiplier = pick(-1, 1)
|
||||||
|
rotate_degrees = multiplier * (rotate_degrees / 2)
|
||||||
|
|
||||||
|
playsound(src, interaction_sound, 50, 1)
|
||||||
|
if(two_stage)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
spawn(3)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
else
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 6)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
if(istype(Proj, redirect_type))
|
||||||
|
visible_message("<span class='danger'>\The [src] redirects \the [Proj]!</span>")
|
||||||
|
flick("[initial(icon_state)]+glow", src)
|
||||||
|
|
||||||
|
var/new_x = (1 * round(10 * cos(degrees_from_north - 90))) + x //Vectors vectors vectors.
|
||||||
|
var/new_y = (-1 * round(10 * sin(degrees_from_north - 90))) + y
|
||||||
|
var/turf/curloc = get_turf(src)
|
||||||
|
|
||||||
|
Proj.penetrating += 1 // Needed for the beam to get out of the turret.
|
||||||
|
|
||||||
|
Proj.redirect(new_x, new_y, curloc, null)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/incremental
|
||||||
|
free_rotate = 0
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but only locks to specific positions in rotation."
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/incremental/externalcont
|
||||||
|
external_control_lock = 1
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by a control dial to specific positions."
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/externalcont
|
||||||
|
external_control_lock = 1
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by an external control dial."
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol
|
||||||
|
name = "prismatic dial"
|
||||||
|
desc = "A large dial with a crystalline ring."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "dial"
|
||||||
|
density = FALSE
|
||||||
|
anchored = TRUE
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The dial pulses as your hand nears it.</span>"
|
||||||
|
var/list/my_turrets = list()
|
||||||
|
var/dialID = null
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/attack_hand(mob/living/user)
|
||||||
|
..()
|
||||||
|
|
||||||
|
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!my_turrets || !my_turrets.len)
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] doesn't seem to do anything.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/free_rotate = 1
|
||||||
|
var/list/compass_directions = list()
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
if(!P.free_rotate) //Doesn't use bearing, it uses compass points.
|
||||||
|
free_rotate = 0
|
||||||
|
compass_directions |= P.compass_directions
|
||||||
|
|
||||||
|
var/new_bearing
|
||||||
|
if(free_rotate)
|
||||||
|
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
|
||||||
|
new_bearing = round(new_bearing)
|
||||||
|
if(new_bearing <= -1 || new_bearing > 360)
|
||||||
|
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
|
||||||
|
new_bearing = round(compass_directions[choice])
|
||||||
|
|
||||||
|
confirm = input("Are you certain you want to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] clicks into place.</span>")
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.rotate_auto(new_bearing)
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/initialize()
|
||||||
|
..()
|
||||||
|
if(my_turrets.len) //Preset controls.
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.remote_dial = src
|
||||||
|
return
|
||||||
|
spawn()
|
||||||
|
for(var/obj/structure/prop/prism/P in orange(src, world.view)) //Don't search a huge area.
|
||||||
|
if(P.dialID == dialID && !P.remote_dial && P.external_control_lock)
|
||||||
|
my_turrets |= P
|
||||||
|
P.remote_dial = src
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/Destroy()
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.remote_dial = null
|
||||||
|
my_turrets = list()
|
||||||
|
..()
|
||||||
53
code/game/objects/structures/props/projectile_lock.dm
Normal file
53
code/game/objects/structures/props/projectile_lock.dm
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//A locking mechanism that pulses when hit by a projectile. The base one responds to high-power lasers.
|
||||||
|
|
||||||
|
/obj/structure/prop/lock
|
||||||
|
name = "weird lock"
|
||||||
|
desc = "An esoteric object that responds to.. something."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "lock"
|
||||||
|
|
||||||
|
var/enabled = 0
|
||||||
|
var/lockID = null
|
||||||
|
|
||||||
|
var/list/linked_objects = list()
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/Destroy()
|
||||||
|
if(linked_objects.len)
|
||||||
|
for(var/obj/O in linked_objects)
|
||||||
|
if(istype(O, /obj/machinery/door/blast/puzzle))
|
||||||
|
var/obj/machinery/door/blast/puzzle/P = O
|
||||||
|
P.locks -= src
|
||||||
|
linked_objects -= P
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/proc/toggle_lock()
|
||||||
|
enabled = !enabled
|
||||||
|
|
||||||
|
if(enabled)
|
||||||
|
icon_state = "[initial(icon_state)]-active"
|
||||||
|
else
|
||||||
|
icon_state = "[initial(icon_state)]"
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/projectile
|
||||||
|
name = "beam lock"
|
||||||
|
desc = "An esoteric object that responds to high intensity light."
|
||||||
|
|
||||||
|
var/projectile_key = /obj/item/projectile/beam
|
||||||
|
var/timed = 0
|
||||||
|
var/timing = 0
|
||||||
|
var/time_limit = 1500 // In ticks. Ten is one second.
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The object remains inert to your touch.</span>"
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/projectile/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
if(!istype(Proj, projectile_key) || timing)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(istype(Proj, /obj/item/projectile/beam/heavylaser/cannon) || istype(Proj, /obj/item/projectile/beam/emitter) || (Proj.damage >= 80 && Proj.damtype == BURN))
|
||||||
|
toggle_lock()
|
||||||
|
visible_message("<span class='notice'>\The [src] [enabled ? "disengages" : "engages"] its locking mechanism.</span>")
|
||||||
|
|
||||||
|
if(timed)
|
||||||
|
timing = 1
|
||||||
|
spawn(time_limit)
|
||||||
|
toggle_lock()
|
||||||
18
code/game/objects/structures/props/prop.dm
Normal file
18
code/game/objects/structures/props/prop.dm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//The base 'prop' for PoIs or other large junk.
|
||||||
|
|
||||||
|
/obj/structure/prop
|
||||||
|
name = "something"
|
||||||
|
desc = "My description is broken, bug a developer."
|
||||||
|
icon = 'icons/obj/structures.dmi'
|
||||||
|
icon_state = "safe"
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
var/interaction_message = null
|
||||||
|
|
||||||
|
/obj/structure/prop/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
||||||
|
if(!istype(user))
|
||||||
|
return FALSE
|
||||||
|
if(!interaction_message)
|
||||||
|
return ..()
|
||||||
|
else
|
||||||
|
to_chat(user, interaction_message)
|
||||||
92
code/game/objects/structures/props/puzzledoor.dm
Normal file
92
code/game/objects/structures/props/puzzledoor.dm
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// An indestructible blast door that can only be opened once its puzzle requirements are completed.
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle
|
||||||
|
name = "puzzle door"
|
||||||
|
desc = "A large, virtually indestructible door that will not open unless certain requirements are met."
|
||||||
|
icon_state_open = "pdoor0"
|
||||||
|
icon_state_opening = "pdoorc0"
|
||||||
|
icon_state_closed = "pdoor1"
|
||||||
|
icon_state_closing = "pdoorc1"
|
||||||
|
icon_state = "pdoor1"
|
||||||
|
|
||||||
|
explosion_resistance = 100
|
||||||
|
|
||||||
|
maxhealth = 9999999 //No.
|
||||||
|
|
||||||
|
var/list/locks = list()
|
||||||
|
var/lockID = null
|
||||||
|
var/checkrange_mult = 1
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/proc/check_locks()
|
||||||
|
for(var/obj/structure/prop/lock/L in locks)
|
||||||
|
if(!L.enabled)
|
||||||
|
return 0
|
||||||
|
return 1
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
visible_message("<span class='cult'>\The [src] is completely unaffected by \the [Proj].</span>")
|
||||||
|
qdel(Proj) //No piercing. No.
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/ex_act(severity)
|
||||||
|
visible_message("<span class='cult'>\The [src] is completely unaffected by the blast.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/initialize()
|
||||||
|
. = ..()
|
||||||
|
implicit_material = get_material_by_name("dungeonium")
|
||||||
|
if(locks.len)
|
||||||
|
return
|
||||||
|
var/check_range = world.view * checkrange_mult
|
||||||
|
for(var/obj/structure/prop/lock/L in orange(src, check_range))
|
||||||
|
if(L.lockID == lockID)
|
||||||
|
L.linked_objects |= src
|
||||||
|
locks |= L
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/Destroy()
|
||||||
|
if(locks.len)
|
||||||
|
for(var/obj/structure/prop/lock/L in locks)
|
||||||
|
L.linked_objects -= src
|
||||||
|
locks -= L
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_hand(mob/user as mob)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] does not respond to your touch.</span>")
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attackby(obj/item/weapon/C as obj, mob/user as mob)
|
||||||
|
if(istype(C, /obj/item/weapon))
|
||||||
|
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN)))
|
||||||
|
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe))
|
||||||
|
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||||
|
if(!F.wielded)
|
||||||
|
to_chat(user, "<span class='warning'>You need to be wielding \the [F] to do that.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>[src]'s arcane workings resist your effort.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
else if(src.density && (user.a_intent == I_HURT))
|
||||||
|
var/obj/item/weapon/W = C
|
||||||
|
user.setClickCooldown(user.get_attack_speed(W))
|
||||||
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||||
|
user.do_attack_animation(src)
|
||||||
|
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
|
||||||
|
|
||||||
|
else if(istype(C, /obj/item/weapon/plastique))
|
||||||
|
to_chat(user, "<span class='danger'>On contacting \the [src], a flash of light envelops \the [C] as it is turned to ash. Oh.</span>")
|
||||||
|
qdel(C)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_generic(var/mob/user, var/damage)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_alien(var/mob/user)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
@@ -130,6 +130,9 @@
|
|||||||
if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg')
|
if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg')
|
||||||
if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg')
|
if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg')
|
||||||
if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg')
|
if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg')
|
||||||
|
if ("thunder") soundin = pick('sound/effects/thunder/thunder1.ogg', 'sound/effects/thunder/thunder2.ogg', 'sound/effects/thunder/thunder3.ogg', 'sound/effects/thunder/thunder4.ogg',
|
||||||
|
'sound/effects/thunder/thunder5.ogg', 'sound/effects/thunder/thunder6.ogg', 'sound/effects/thunder/thunder7.ogg', 'sound/effects/thunder/thunder8.ogg', 'sound/effects/thunder/thunder9.ogg',
|
||||||
|
'sound/effects/thunder/thunder10.ogg')
|
||||||
return soundin
|
return soundin
|
||||||
|
|
||||||
//Are these even used?
|
//Are these even used?
|
||||||
|
|||||||
@@ -1,333 +0,0 @@
|
|||||||
//Config stuff
|
|
||||||
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
|
|
||||||
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
|
|
||||||
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
|
|
||||||
#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
|
|
||||||
|
|
||||||
//Supply packs are in /code/defines/obj/supplypacks.dm
|
|
||||||
//Computers are in /code/game/machinery/computer/supply.dm
|
|
||||||
|
|
||||||
var/datum/controller/supply/supply_controller = new()
|
|
||||||
|
|
||||||
var/list/mechtoys = list(
|
|
||||||
/obj/item/toy/prize/ripley,
|
|
||||||
/obj/item/toy/prize/fireripley,
|
|
||||||
/obj/item/toy/prize/deathripley,
|
|
||||||
/obj/item/toy/prize/gygax,
|
|
||||||
/obj/item/toy/prize/durand,
|
|
||||||
/obj/item/toy/prize/honk,
|
|
||||||
/obj/item/toy/prize/marauder,
|
|
||||||
/obj/item/toy/prize/seraph,
|
|
||||||
/obj/item/toy/prize/mauler,
|
|
||||||
/obj/item/toy/prize/odysseus,
|
|
||||||
/obj/item/toy/prize/phazon
|
|
||||||
)
|
|
||||||
|
|
||||||
/obj/item/weapon/paper/manifest
|
|
||||||
name = "supply manifest"
|
|
||||||
var/is_copy = 1
|
|
||||||
|
|
||||||
/area/supply/station
|
|
||||||
name = "Supply Shuttle"
|
|
||||||
icon_state = "shuttle3"
|
|
||||||
requires_power = 0
|
|
||||||
base_turf = /turf/space
|
|
||||||
|
|
||||||
/area/supply/dock
|
|
||||||
name = "Supply Shuttle"
|
|
||||||
icon_state = "shuttle3"
|
|
||||||
requires_power = 0
|
|
||||||
base_turf = /turf/space
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
|
|
||||||
name = "\improper plastic flaps"
|
|
||||||
desc = "Completely impassable - or are they?"
|
|
||||||
icon = 'icons/obj/stationobjs.dmi' //Change this.
|
|
||||||
icon_state = "plasticflaps"
|
|
||||||
density = 0
|
|
||||||
anchored = 1
|
|
||||||
layer = MOB_LAYER
|
|
||||||
plane = MOB_PLANE
|
|
||||||
explosion_resistance = 5
|
|
||||||
var/list/mobs_can_pass = list(
|
|
||||||
/mob/living/bot,
|
|
||||||
/mob/living/simple_animal/slime,
|
|
||||||
/mob/living/simple_animal/mouse,
|
|
||||||
/mob/living/silicon/robot/drone
|
|
||||||
)
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/attackby(obj/item/P, mob/user)
|
|
||||||
if(P.is_wirecutter())
|
|
||||||
playsound(src, P.usesound, 50, 1)
|
|
||||||
user << "<span class='notice'>You start to cut the plastic flaps.</span>"
|
|
||||||
if(do_after(user, 10 * P.toolspeed))
|
|
||||||
user << "<span class='notice'>You cut the plastic flaps.</span>"
|
|
||||||
var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc )
|
|
||||||
A.amount = 4
|
|
||||||
qdel(src)
|
|
||||||
return
|
|
||||||
else
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
|
|
||||||
if(istype(A) && A.checkpass(PASSGLASS))
|
|
||||||
return prob(60)
|
|
||||||
|
|
||||||
var/obj/structure/bed/B = A
|
|
||||||
if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if(istype(A, /obj/vehicle)) //no vehicles
|
|
||||||
return 0
|
|
||||||
|
|
||||||
var/mob/living/M = A
|
|
||||||
if(istype(M))
|
|
||||||
if(M.lying)
|
|
||||||
return ..()
|
|
||||||
for(var/mob_type in mobs_can_pass)
|
|
||||||
if(istype(A, mob_type))
|
|
||||||
return ..()
|
|
||||||
return issmall(M)
|
|
||||||
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/ex_act(severity)
|
|
||||||
switch(severity)
|
|
||||||
if (1)
|
|
||||||
qdel(src)
|
|
||||||
if (2)
|
|
||||||
if (prob(50))
|
|
||||||
qdel(src)
|
|
||||||
if (3)
|
|
||||||
if (prob(5))
|
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
|
|
||||||
name = "airtight plastic flaps"
|
|
||||||
desc = "Heavy duty, airtight, plastic flaps."
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/mining/New() //set the turf below the flaps to block air
|
|
||||||
var/turf/T = get_turf(loc)
|
|
||||||
if(T)
|
|
||||||
T.blocks_air = 1
|
|
||||||
..()
|
|
||||||
|
|
||||||
/obj/structure/plasticflaps/mining/Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor
|
|
||||||
var/turf/T = get_turf(loc)
|
|
||||||
if(T && istype(T, /turf/simulated/floor))
|
|
||||||
T.blocks_air = 0
|
|
||||||
..()
|
|
||||||
|
|
||||||
/*
|
|
||||||
/obj/effect/marker/supplymarker
|
|
||||||
icon_state = "X"
|
|
||||||
icon = 'icons/misc/mark.dmi'
|
|
||||||
name = "X"
|
|
||||||
invisibility = 101
|
|
||||||
anchored = 1
|
|
||||||
opacity = 0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/datum/supply_order
|
|
||||||
var/ordernum
|
|
||||||
var/datum/supply_packs/object = null
|
|
||||||
var/orderedby = null
|
|
||||||
var/comment = null
|
|
||||||
|
|
||||||
/datum/exported_crate
|
|
||||||
var/name
|
|
||||||
var/value
|
|
||||||
|
|
||||||
/datum/controller/supply
|
|
||||||
//supply points
|
|
||||||
var/points = 50
|
|
||||||
var/points_per_process = 1.5
|
|
||||||
var/points_per_slip = 2
|
|
||||||
var/points_per_platinum = 5 // 5 points per sheet
|
|
||||||
var/points_per_phoron = 5
|
|
||||||
var/points_per_money = 0.02
|
|
||||||
//control
|
|
||||||
var/ordernum
|
|
||||||
var/list/shoppinglist = list()
|
|
||||||
var/list/requestlist = list()
|
|
||||||
var/list/supply_packs = list()
|
|
||||||
var/list/exported_crates = list()
|
|
||||||
//shuttle movement
|
|
||||||
var/movetime = 1200
|
|
||||||
var/datum/shuttle/ferry/supply/shuttle
|
|
||||||
|
|
||||||
/datum/controller/supply/New()
|
|
||||||
ordernum = rand(1,9000)
|
|
||||||
|
|
||||||
for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
|
|
||||||
var/datum/supply_packs/P = new typepath()
|
|
||||||
supply_packs[P.name] = P
|
|
||||||
|
|
||||||
// Supply shuttle ticker - handles supply point regeneration
|
|
||||||
// This is called by the process scheduler every thirty seconds
|
|
||||||
/datum/controller/supply/proc/process()
|
|
||||||
points += points_per_process
|
|
||||||
|
|
||||||
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
|
|
||||||
/datum/controller/supply/proc/forbidden_atoms_check(atom/A)
|
|
||||||
if(isliving(A))
|
|
||||||
return 1
|
|
||||||
if(istype(A,/obj/item/weapon/disk/nuclear))
|
|
||||||
return 1
|
|
||||||
if(istype(A,/obj/machinery/nuclearbomb))
|
|
||||||
return 1
|
|
||||||
if(istype(A,/obj/item/device/radio/beacon))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
for(var/i=1, i<=A.contents.len, i++)
|
|
||||||
var/atom/B = A.contents[i]
|
|
||||||
if(.(B))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
//Sellin
|
|
||||||
/datum/controller/supply/proc/sell()
|
|
||||||
var/area/area_shuttle = shuttle.get_location_area()
|
|
||||||
if(!area_shuttle) return
|
|
||||||
|
|
||||||
callHook("sell_shuttle", list(area_shuttle));
|
|
||||||
|
|
||||||
var/phoron_count = 0
|
|
||||||
var/plat_count = 0
|
|
||||||
var/money_count = 0
|
|
||||||
|
|
||||||
exported_crates = list()
|
|
||||||
|
|
||||||
for(var/atom/movable/MA in area_shuttle)
|
|
||||||
if(MA.anchored) continue
|
|
||||||
|
|
||||||
// Must be in a crate!
|
|
||||||
if(istype(MA,/obj/structure/closet/crate))
|
|
||||||
var/oldpoints = points
|
|
||||||
var/oldphoron = phoron_count
|
|
||||||
var/oldplatinum = plat_count
|
|
||||||
var/oldmoney = money_count
|
|
||||||
|
|
||||||
var/obj/structure/closet/crate/CR = MA
|
|
||||||
callHook("sell_crate", list(CR, area_shuttle))
|
|
||||||
|
|
||||||
points += CR.points_per_crate
|
|
||||||
var/find_slip = 1
|
|
||||||
|
|
||||||
for(var/atom in CR)
|
|
||||||
// Sell manifests
|
|
||||||
var/atom/A = atom
|
|
||||||
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
|
|
||||||
var/obj/item/weapon/paper/manifest/slip = A
|
|
||||||
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
|
|
||||||
points += points_per_slip
|
|
||||||
find_slip = 0
|
|
||||||
continue
|
|
||||||
|
|
||||||
// Sell phoron and platinum
|
|
||||||
if(istype(A, /obj/item/stack))
|
|
||||||
var/obj/item/stack/P = A
|
|
||||||
switch(P.get_material_name())
|
|
||||||
if("phoron") phoron_count += P.get_amount()
|
|
||||||
if("platinum") plat_count += P.get_amount()
|
|
||||||
|
|
||||||
//Sell spacebucks
|
|
||||||
if(istype(A, /obj/item/weapon/spacecash))
|
|
||||||
var/obj/item/weapon/spacecash/cashmoney = A
|
|
||||||
money_count += cashmoney.worth
|
|
||||||
|
|
||||||
var/datum/exported_crate/EC = new /datum/exported_crate()
|
|
||||||
EC.name = CR.name
|
|
||||||
EC.value = points - oldpoints
|
|
||||||
EC.value += (phoron_count - oldphoron) * points_per_phoron
|
|
||||||
EC.value += (plat_count - oldplatinum) * points_per_platinum
|
|
||||||
EC.value += (money_count - oldmoney) * points_per_money
|
|
||||||
exported_crates += EC
|
|
||||||
|
|
||||||
qdel(MA)
|
|
||||||
|
|
||||||
points += phoron_count * points_per_phoron
|
|
||||||
points += plat_count * points_per_platinum
|
|
||||||
points += money_count * points_per_money
|
|
||||||
|
|
||||||
//Buyin
|
|
||||||
/datum/controller/supply/proc/buy()
|
|
||||||
if(!shoppinglist.len)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/orderedamount = shoppinglist.len
|
|
||||||
|
|
||||||
var/area/area_shuttle = shuttle.get_location_area()
|
|
||||||
if(!area_shuttle)
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/clear_turfs = list()
|
|
||||||
|
|
||||||
for(var/turf/T in area_shuttle)
|
|
||||||
if(T.density)
|
|
||||||
continue
|
|
||||||
var/contcount
|
|
||||||
for(var/atom/A in T.contents)
|
|
||||||
if(!A.simulated)
|
|
||||||
continue
|
|
||||||
contcount++
|
|
||||||
if(contcount)
|
|
||||||
continue
|
|
||||||
clear_turfs += T
|
|
||||||
|
|
||||||
for(var/S in shoppinglist)
|
|
||||||
if(!clear_turfs.len) break
|
|
||||||
var/i = rand(1,clear_turfs.len)
|
|
||||||
var/turf/pickedloc = clear_turfs[i]
|
|
||||||
clear_turfs.Cut(i,i+1)
|
|
||||||
shoppinglist -= S
|
|
||||||
|
|
||||||
var/datum/supply_order/SO = S
|
|
||||||
var/datum/supply_packs/SP = SO.object
|
|
||||||
|
|
||||||
var/obj/A = new SP.containertype(pickedloc)
|
|
||||||
A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
|
|
||||||
|
|
||||||
//supply manifest generation begin
|
|
||||||
var/obj/item/weapon/paper/manifest/slip
|
|
||||||
if(!SP.contraband)
|
|
||||||
slip = new /obj/item/weapon/paper/manifest(A)
|
|
||||||
slip.is_copy = 0
|
|
||||||
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
|
|
||||||
slip.info +="Order #[SO.ordernum]<br>"
|
|
||||||
slip.info +="Destination: [station_name()]<br>"
|
|
||||||
slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT<br>"
|
|
||||||
slip.info +="CONTENTS:<br><ul>"
|
|
||||||
|
|
||||||
//spawn the stuff, finish generating the manifest while you're at it
|
|
||||||
if(SP.access)
|
|
||||||
if(isnum(SP.access))
|
|
||||||
A.req_access = list(SP.access)
|
|
||||||
else if(islist(SP.access))
|
|
||||||
var/list/L = SP.access // access var is a plain var, we need a list
|
|
||||||
A.req_access = L.Copy()
|
|
||||||
else
|
|
||||||
log_debug("<span class='danger'>Supply pack with invalid access restriction [SP.access] encountered!</span>")
|
|
||||||
|
|
||||||
var/list/contains
|
|
||||||
if(istype(SP,/datum/supply_packs/randomised))
|
|
||||||
var/datum/supply_packs/randomised/SPR = SP
|
|
||||||
contains = list()
|
|
||||||
if(SPR.contains.len)
|
|
||||||
for(var/j=1,j<=SPR.num_contained,j++)
|
|
||||||
contains += pick(SPR.contains)
|
|
||||||
else
|
|
||||||
contains = SP.contains
|
|
||||||
|
|
||||||
for(var/typepath in contains)
|
|
||||||
if(!typepath) continue
|
|
||||||
var/number_of_items = max(1, contains[typepath])
|
|
||||||
for(var/j = 1 to number_of_items)
|
|
||||||
var/atom/B2 = new typepath(A)
|
|
||||||
if(slip) slip.info += "<li>[B2.name]</li>" //add the item to the manifest
|
|
||||||
|
|
||||||
//manifest finalisation
|
|
||||||
if(slip)
|
|
||||||
slip.info += "</ul><br>"
|
|
||||||
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>"
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
nitrogen = MOLES_N2STANDARD
|
nitrogen = MOLES_N2STANDARD
|
||||||
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
|
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
|
||||||
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
|
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
|
||||||
|
var/can_dirty = TRUE // If false, tile never gets dirty
|
||||||
var/dirt = 0
|
var/dirt = 0
|
||||||
|
|
||||||
// This is not great.
|
// This is not great.
|
||||||
@@ -65,12 +66,13 @@
|
|||||||
tracks.AddTracks(bloodDNA,comingdir,goingdir,bloodcolor)
|
tracks.AddTracks(bloodDNA,comingdir,goingdir,bloodcolor)
|
||||||
|
|
||||||
/turf/simulated/proc/update_dirt()
|
/turf/simulated/proc/update_dirt()
|
||||||
dirt = min(dirt+1, 101)
|
if(can_dirty)
|
||||||
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, src)
|
dirt = min(dirt+1, 101)
|
||||||
if (dirt > 50)
|
var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, src)
|
||||||
if (!dirtoverlay)
|
if (dirt > 50)
|
||||||
dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
|
if (!dirtoverlay)
|
||||||
dirtoverlay.alpha = min((dirt - 50) * 5, 255)
|
dirtoverlay = new/obj/effect/decal/cleanable/dirt(src)
|
||||||
|
dirtoverlay.alpha = min((dirt - 50) * 5, 255)
|
||||||
|
|
||||||
/turf/simulated/Entered(atom/A, atom/OL)
|
/turf/simulated/Entered(atom/A, atom/OL)
|
||||||
if(movement_disabled && usr.ckey != movement_disabled_exception)
|
if(movement_disabled && usr.ckey != movement_disabled_exception)
|
||||||
@@ -82,8 +84,9 @@
|
|||||||
if(M.lying)
|
if(M.lying)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
// Dirt overlays.
|
if(M.dirties_floor())
|
||||||
update_dirt()
|
// Dirt overlays.
|
||||||
|
update_dirt()
|
||||||
|
|
||||||
if(istype(M, /mob/living/carbon/human))
|
if(istype(M, /mob/living/carbon/human))
|
||||||
var/mob/living/carbon/human/H = M
|
var/mob/living/carbon/human/H = M
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
/turf/simulated/wall/dungeon/ex_act()
|
/turf/simulated/wall/dungeon/ex_act()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/turf/simulated/wall/dungeon/take_damage() //These things are suppose to be unbreakable
|
||||||
|
return
|
||||||
|
|
||||||
/turf/simulated/wall/solidrock //for more stylish anti-cheese.
|
/turf/simulated/wall/solidrock //for more stylish anti-cheese.
|
||||||
name = "solid rock"
|
name = "solid rock"
|
||||||
desc = "This rock seems dense, impossible to drill."
|
desc = "This rock seems dense, impossible to drill."
|
||||||
@@ -37,4 +40,7 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/turf/simulated/wall/solidrock/ex_act()
|
/turf/simulated/wall/solidrock/ex_act()
|
||||||
|
return
|
||||||
|
|
||||||
|
/turf/simulated/wall/solidrock/take_damage() //These things are suppose to be unbreakable
|
||||||
return
|
return
|
||||||
@@ -9,6 +9,50 @@
|
|||||||
attack_tile(C, L) // Be on help intent if you want to decon something.
|
attack_tile(C, L) // Be on help intent if you want to decon something.
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(istype(C, /obj/item/stack/tile/roofing))
|
||||||
|
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
|
||||||
|
var/turf/T = GetAbove(src)
|
||||||
|
var/obj/item/stack/tile/roofing/R = C
|
||||||
|
|
||||||
|
// Patch holes in the ceiling
|
||||||
|
if(T)
|
||||||
|
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
|
||||||
|
// Must be build adjacent to an existing floor/wall, no floating floors
|
||||||
|
var/list/cardinalTurfs = list() // Up a Z level
|
||||||
|
for(var/dir in cardinal)
|
||||||
|
var/turf/B = get_step(T, dir)
|
||||||
|
if(B)
|
||||||
|
cardinalTurfs += B
|
||||||
|
|
||||||
|
var/turf/simulated/A = locate(/turf/simulated/floor) in cardinalTurfs
|
||||||
|
if(!A)
|
||||||
|
A = locate(/turf/simulated/wall) in cardinalTurfs
|
||||||
|
if(!A)
|
||||||
|
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
|
||||||
|
T.ReplaceWithLattice()
|
||||||
|
T.ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
|
||||||
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
|
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
|
||||||
|
expended_tile = TRUE
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
// Create a ceiling to shield from the weather
|
||||||
|
if(src.outdoors)
|
||||||
|
for(var/dir in cardinal)
|
||||||
|
var/turf/A = get_step(src, dir)
|
||||||
|
if(A && !A.outdoors)
|
||||||
|
if(expended_tile || R.use(1))
|
||||||
|
make_indoors()
|
||||||
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
|
user.visible_message("<span class='notice'>[user] roofs a tile, shielding it from the elements.</span>", "<span class='notice'>You roof this tile, shielding it from the elements.</span>")
|
||||||
|
break
|
||||||
|
return
|
||||||
|
|
||||||
if(flooring)
|
if(flooring)
|
||||||
if(istype(C, /obj/item/weapon))
|
if(istype(C, /obj/item/weapon))
|
||||||
try_deconstruct_tile(C, user)
|
try_deconstruct_tile(C, user)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
var/list/turf_edge_cache = list()
|
var/list/turf_edge_cache = list()
|
||||||
var/list/outdoor_turfs = list()
|
|
||||||
|
|
||||||
/turf/
|
/turf/
|
||||||
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
|
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
|
||||||
@@ -24,24 +23,21 @@ var/list/outdoor_turfs = list()
|
|||||||
|
|
||||||
/turf/simulated/floor/New()
|
/turf/simulated/floor/New()
|
||||||
if(outdoors)
|
if(outdoors)
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/turf/simulated/floor/Destroy()
|
/turf/simulated/floor/Destroy()
|
||||||
if(outdoors)
|
if(outdoors)
|
||||||
planet_controller.unallocateTurf(src)
|
SSplanets.removeTurf(src)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/turf/simulated/proc/make_outdoors()
|
/turf/simulated/proc/make_outdoors()
|
||||||
outdoors = TRUE
|
outdoors = TRUE
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
|
|
||||||
/turf/simulated/proc/make_indoors()
|
/turf/simulated/proc/make_indoors()
|
||||||
outdoors = FALSE
|
outdoors = FALSE
|
||||||
if(planet_controller)
|
SSplanets.removeTurf(src)
|
||||||
planet_controller.unallocateTurf(src)
|
|
||||||
else // This is happening during map gen, if there's no planet_controller (hopefully).
|
|
||||||
outdoor_turfs -= src
|
|
||||||
|
|
||||||
/turf/simulated/post_change()
|
/turf/simulated/post_change()
|
||||||
..()
|
..()
|
||||||
@@ -58,8 +54,8 @@ var/list/outdoor_turfs = list()
|
|||||||
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
|
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
|
||||||
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
|
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
|
||||||
if(!turf_edge_cache[cache_key])
|
if(!turf_edge_cache[cache_key])
|
||||||
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
|
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir, layer = ABOVE_TURF_LAYER)
|
||||||
I.plane = 0
|
I.plane = TURF_PLANE
|
||||||
turf_edge_cache[cache_key] = I
|
turf_edge_cache[cache_key] = I
|
||||||
add_overlay(turf_edge_cache[cache_key])
|
add_overlay(turf_edge_cache[cache_key])
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
/turf/simulated/sky/initialize()
|
/turf/simulated/sky/initialize()
|
||||||
. = ..()
|
. = ..()
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
set_light(2, 2, "#FFFFFF")
|
set_light(2, 2, "#FFFFFF")
|
||||||
|
|
||||||
/turf/simulated/sky/north
|
/turf/simulated/sky/north
|
||||||
|
|||||||
@@ -142,15 +142,44 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
//get the user's location
|
//get the user's location
|
||||||
if(!istype(user.loc, /turf)) return //can't do this stuff whilst inside objects and such
|
if(!istype(user.loc, /turf))
|
||||||
|
return //can't do this stuff whilst inside objects and such
|
||||||
|
|
||||||
if(W)
|
if(W)
|
||||||
radiate()
|
radiate()
|
||||||
if(is_hot(W))
|
if(is_hot(W))
|
||||||
burn(is_hot(W))
|
burn(is_hot(W))
|
||||||
|
|
||||||
|
if(istype(W, /obj/item/stack/tile/roofing))
|
||||||
|
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
|
||||||
|
var/turf/T = GetAbove(src)
|
||||||
|
var/obj/item/stack/tile/roofing/R = W
|
||||||
|
|
||||||
|
// Place plating over a wall
|
||||||
|
if(T)
|
||||||
|
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
|
||||||
|
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
|
||||||
|
T.ReplaceWithLattice()
|
||||||
|
T.ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
|
||||||
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
|
user.visible_message("<span class='notice'>[user] patches a hole in the ceiling.</span>", "<span class='notice'>You patch a hole in the ceiling.</span>")
|
||||||
|
expended_tile = TRUE
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
// Create a ceiling to shield from the weather
|
||||||
|
if(outdoors)
|
||||||
|
if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one
|
||||||
|
make_indoors()
|
||||||
|
if(!expended_tile) // Would've already played a sound
|
||||||
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
|
user.visible_message("<span class='notice'>[user] roofs \the [src], shielding it from the elements.</span>", "<span class='notice'>You roof \the [src] tile, shielding it from the elements.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
if(locate(/obj/effect/overlay/wallrot) in src)
|
if(locate(/obj/effect/overlay/wallrot) in src)
|
||||||
if(W.is_welder())
|
if(istype(W, /obj/item/weapon/weldingtool) )
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
if( WT.remove_fuel(0,user) )
|
if( WT.remove_fuel(0,user) )
|
||||||
to_chat(user, "<span class='notice'>You burn away the fungi with \the [WT].</span>")
|
to_chat(user, "<span class='notice'>You burn away the fungi with \the [WT].</span>")
|
||||||
@@ -165,7 +194,7 @@
|
|||||||
|
|
||||||
//THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects
|
//THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects
|
||||||
if(thermite)
|
if(thermite)
|
||||||
if(W.is_welder())
|
if( istype(W, /obj/item/weapon/weldingtool) )
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
if( WT.remove_fuel(0,user) )
|
if( WT.remove_fuel(0,user) )
|
||||||
thermitemelt(user)
|
thermitemelt(user)
|
||||||
@@ -188,7 +217,7 @@
|
|||||||
|
|
||||||
var/turf/T = user.loc //get user's location for delay checks
|
var/turf/T = user.loc //get user's location for delay checks
|
||||||
|
|
||||||
if(damage && W.is_welder())
|
if(damage && istype(W, /obj/item/weapon/weldingtool))
|
||||||
|
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
|
|
||||||
@@ -214,7 +243,7 @@
|
|||||||
var/dismantle_verb
|
var/dismantle_verb
|
||||||
var/dismantle_sound
|
var/dismantle_sound
|
||||||
|
|
||||||
if(W.is_welder())
|
if(istype(W,/obj/item/weapon/weldingtool))
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
if(!WT.isOn())
|
if(!WT.isOn())
|
||||||
return
|
return
|
||||||
@@ -282,7 +311,7 @@
|
|||||||
return
|
return
|
||||||
if(4)
|
if(4)
|
||||||
var/cut_cover
|
var/cut_cover
|
||||||
if(W.is_welder())
|
if(istype(W,/obj/item/weapon/weldingtool))
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
if(!WT.isOn())
|
if(!WT.isOn())
|
||||||
return
|
return
|
||||||
@@ -337,7 +366,7 @@
|
|||||||
return
|
return
|
||||||
if(1)
|
if(1)
|
||||||
var/cut_cover
|
var/cut_cover
|
||||||
if(W.is_welder())
|
if(istype(W, /obj/item/weapon/weldingtool))
|
||||||
var/obj/item/weapon/weldingtool/WT = W
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
if( WT.remove_fuel(0,user) )
|
if( WT.remove_fuel(0,user) )
|
||||||
cut_cover=1
|
cut_cover=1
|
||||||
|
|||||||
@@ -115,9 +115,9 @@
|
|||||||
plant.pixel_y = 0
|
plant.pixel_y = 0
|
||||||
plant.update_neighbors()
|
plant.update_neighbors()
|
||||||
|
|
||||||
/turf/simulated/wall/ChangeTurf(var/newtype)
|
/turf/simulated/wall/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
|
||||||
clear_plants()
|
clear_plants()
|
||||||
..(newtype)
|
..(N, tell_universe, force_lighting_update, preserve_outdoors)
|
||||||
|
|
||||||
//Appearance
|
//Appearance
|
||||||
/turf/simulated/wall/examine(mob/user)
|
/turf/simulated/wall/examine(mob/user)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
..() // To get the edges.
|
..() // To get the edges.
|
||||||
icon_state = water_state
|
icon_state = water_state
|
||||||
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
|
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
|
||||||
|
underlays.Cut() // To clear the old underlay, so the list doesn't expand infinitely
|
||||||
underlays.Add(floorbed_sprite)
|
underlays.Add(floorbed_sprite)
|
||||||
update_icon_edge()
|
update_icon_edge()
|
||||||
|
|
||||||
|
|||||||
@@ -33,18 +33,18 @@
|
|||||||
|
|
||||||
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
|
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
|
||||||
|
|
||||||
if (istype(C, /obj/item/stack/rods))
|
if(istype(C, /obj/item/stack/rods))
|
||||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||||
if(L)
|
if(L)
|
||||||
return
|
return
|
||||||
var/obj/item/stack/rods/R = C
|
var/obj/item/stack/rods/R = C
|
||||||
if (R.use(1))
|
if (R.use(1))
|
||||||
user << "<span class='notice'>Constructing support lattice ...</span>"
|
to_chat(user, "<span class='notice'>Constructing support lattice ...</span>")
|
||||||
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
ReplaceWithLattice()
|
ReplaceWithLattice()
|
||||||
return
|
return
|
||||||
|
|
||||||
if (istype(C, /obj/item/stack/tile/floor))
|
if(istype(C, /obj/item/stack/tile/floor))
|
||||||
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
|
||||||
if(L)
|
if(L)
|
||||||
var/obj/item/stack/tile/floor/S = C
|
var/obj/item/stack/tile/floor/S = C
|
||||||
@@ -56,7 +56,33 @@
|
|||||||
ChangeTurf(/turf/simulated/floor/airless)
|
ChangeTurf(/turf/simulated/floor/airless)
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
user << "<span class='warning'>The plating is going to need some support.</span>"
|
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
|
||||||
|
|
||||||
|
if(istype(C, /obj/item/stack/tile/roofing))
|
||||||
|
var/turf/T = GetAbove(src)
|
||||||
|
var/obj/item/stack/tile/roofing/R = C
|
||||||
|
|
||||||
|
// Patch holes in the ceiling
|
||||||
|
if(T)
|
||||||
|
if(istype(T, /turf/simulated/open) || istype(T, /turf/space))
|
||||||
|
// Must be build adjacent to an existing floor/wall, no floating floors
|
||||||
|
var/turf/simulated/A = locate(/turf/simulated/floor) in T.CardinalTurfs()
|
||||||
|
if(!A)
|
||||||
|
A = locate(/turf/simulated/wall) in T.CardinalTurfs()
|
||||||
|
if(!A)
|
||||||
|
to_chat(user, "<span class='warning'>There's nothing to attach the ceiling to!</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating
|
||||||
|
T.ReplaceWithLattice()
|
||||||
|
T.ChangeTurf(/turf/simulated/floor)
|
||||||
|
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||||
|
user.visible_message("<span class='notice'>[user] expands the ceiling.</span>", "<span class='notice'>You expand the ceiling.</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>There aren't any holes in the ceiling to patch here.</span>")
|
||||||
|
return
|
||||||
|
// Space shouldn't have weather of the sort planets with atmospheres do.
|
||||||
|
// If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -64,7 +90,7 @@
|
|||||||
|
|
||||||
/turf/space/Entered(atom/movable/A as mob|obj)
|
/turf/space/Entered(atom/movable/A as mob|obj)
|
||||||
if(movement_disabled)
|
if(movement_disabled)
|
||||||
usr << "<span class='warning'>Movement is admin-disabled.</span>" //This is to identify lag problems
|
to_chat(usr, "<span class='warning'>Movement is admin-disabled.</span>") //This is to identify lag problems
|
||||||
return
|
return
|
||||||
..()
|
..()
|
||||||
if ((!(A) || src != A.loc)) return
|
if ((!(A) || src != A.loc)) return
|
||||||
@@ -187,5 +213,5 @@
|
|||||||
A.loc.Entered(A)
|
A.loc.Entered(A)
|
||||||
return
|
return
|
||||||
|
|
||||||
/turf/space/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0)
|
/turf/space/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors)
|
||||||
return ..(N, tell_universe, 1)
|
return ..(N, tell_universe, 1, preserve_outdoors)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
below.update_icon() // To add or remove the 'ceiling-less' overlay.
|
below.update_icon() // To add or remove the 'ceiling-less' overlay.
|
||||||
|
|
||||||
//Creates a new turf
|
//Creates a new turf
|
||||||
/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0)
|
/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0, var/preserve_outdoors = FALSE)
|
||||||
if (!N)
|
if (!N)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
var/old_affecting_lights = affecting_lights
|
var/old_affecting_lights = affecting_lights
|
||||||
var/old_lighting_overlay = lighting_overlay
|
var/old_lighting_overlay = lighting_overlay
|
||||||
var/old_corners = corners
|
var/old_corners = corners
|
||||||
|
var/old_outdoors = outdoors
|
||||||
|
|
||||||
//world << "Replacing [src.type] with [N]"
|
//world << "Replacing [src.type] with [N]"
|
||||||
|
|
||||||
@@ -106,3 +107,6 @@
|
|||||||
lighting_build_overlay()
|
lighting_build_overlay()
|
||||||
else
|
else
|
||||||
lighting_clear_overlay()
|
lighting_clear_overlay()
|
||||||
|
|
||||||
|
if(preserve_outdoors)
|
||||||
|
outdoors = old_outdoors
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
|
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
|
||||||
// are opened or other strange things occur.
|
// are opened or other strange things occur.
|
||||||
var/list/planetary_walls = list()
|
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary
|
/turf/unsimulated/wall/planetary
|
||||||
name = "railroading"
|
name = "railroading"
|
||||||
desc = "Choo choo!"
|
desc = "Choo choo!"
|
||||||
@@ -21,10 +19,10 @@ var/list/planetary_walls = list()
|
|||||||
|
|
||||||
/turf/unsimulated/wall/planetary/New()
|
/turf/unsimulated/wall/planetary/New()
|
||||||
..()
|
..()
|
||||||
planetary_walls.Add(src)
|
SSplanets.addTurf(src)
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary/Destroy()
|
/turf/unsimulated/wall/planetary/Destroy()
|
||||||
planetary_walls.Remove(src)
|
SSplanets.removeTurf(src)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
|
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ var/list/admin_verbs_fun = list(
|
|||||||
/client/proc/roll_dices,
|
/client/proc/roll_dices,
|
||||||
/datum/admins/proc/call_supply_drop,
|
/datum/admins/proc/call_supply_drop,
|
||||||
/datum/admins/proc/call_drop_pod,
|
/datum/admins/proc/call_drop_pod,
|
||||||
/client/proc/smite
|
/client/proc/smite,
|
||||||
|
/client/proc/admin_lightning_strike
|
||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_spawn = list(
|
var/list/admin_verbs_spawn = list(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC.
|
else if(is_antag && !is_admin) // Is an antag, and not an admin, meaning we need to check if their antag type allows AOOC.
|
||||||
var/datum/antagonist/A = get_antag_data(usr.mind.special_role)
|
var/datum/antagonist/A = get_antag_data(usr.mind.special_role)
|
||||||
if(!A || !A.can_use_aooc)
|
if(!A || !A.can_speak_aooc || !A.can_hear_aooc)
|
||||||
to_chat(usr, "<span class='warning'>Sorry, but your antagonist type is not allowed to speak in AOOC.</span>")
|
to_chat(usr, "<span class='warning'>Sorry, but your antagonist type is not allowed to speak in AOOC.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
var/datum/antagonist/A = null
|
var/datum/antagonist/A = null
|
||||||
if(M.mind) // Observers don't have minds, but they should still see AOOC.
|
if(M.mind) // Observers don't have minds, but they should still see AOOC.
|
||||||
A = get_antag_data(M.mind.special_role)
|
A = get_antag_data(M.mind.special_role)
|
||||||
if((M.mind && M.mind.special_role && A && A.can_use_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
|
if((M.mind && M.mind.special_role && A && A.can_hear_aooc) || isobserver(M)) // Antags must have their type be allowed to AOOC to see AOOC. This prevents, say, ERT from seeing AOOC.
|
||||||
to_chat(M, "<span class='ooc'><span class='aooc'>[create_text_tag("aooc", "Antag-OOC:", M.client)] <EM>[player_display]:</EM> <span class='message'>[msg]</span></span></span>")
|
to_chat(M, "<span class='ooc'><span class='aooc'>[create_text_tag("aooc", "Antag-OOC:", M.client)] <EM>[player_display]:</EM> <span class='message'>[msg]</span></span></span>")
|
||||||
|
|
||||||
log_aooc(msg,src)
|
log_aooc(msg,src)
|
||||||
@@ -637,7 +637,7 @@
|
|||||||
if(!check_rights(R_DEBUG))
|
if(!check_rights(R_DEBUG))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in planet_controller.planets
|
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets
|
||||||
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
||||||
if(new_weather)
|
if(new_weather)
|
||||||
planet.weather_holder.change_weather(new_weather)
|
planet.weather_holder.change_weather(new_weather)
|
||||||
@@ -653,7 +653,7 @@
|
|||||||
if(!check_rights(R_DEBUG))
|
if(!check_rights(R_DEBUG))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in planet_controller.planets
|
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets
|
||||||
|
|
||||||
var/datum/time/current_time_datum = planet.current_time
|
var/datum/time/current_time_datum = planet.current_time
|
||||||
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
||||||
|
|||||||
115
code/modules/admin/verbs/lightning_strike.dm
Normal file
115
code/modules/admin/verbs/lightning_strike.dm
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/client/proc/admin_lightning_strike()
|
||||||
|
set name = "Lightning Stirke"
|
||||||
|
set desc = "Causes lightning to strike on your tile. This will hurt things on or nearby it severely."
|
||||||
|
set category = "Fun"
|
||||||
|
|
||||||
|
if(!check_rights(R_FUN))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/result = alert(src, "Really strike your tile with lightning?", "Confirm Badmin" , "No", "Yes (Cosmetic)", "Yes (Real)")
|
||||||
|
|
||||||
|
if(result == "No")
|
||||||
|
return
|
||||||
|
var/fake_lightning = result == "Yes (Cosmetic)"
|
||||||
|
|
||||||
|
lightning_strike(get_turf(usr), fake_lightning)
|
||||||
|
log_and_message_admins("[key_name(src)] has caused [fake_lightning ? "cosmetic":"harmful"] lightning to strike at their position ([src.mob.x], [src.mob.y], [src.mob.z]). \
|
||||||
|
(<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.mob.x];Y=[src.mob.y];Z=[src.mob.z]'>JMP</a>)")
|
||||||
|
|
||||||
|
#define LIGHTNING_REDIRECT_RANGE 28 // How far in tiles certain things draw lightning from.
|
||||||
|
#define LIGHTNING_ZAP_RANGE 3 // How far the tesla effect zaps, as well as the bad effects from a direct strike.
|
||||||
|
#define LIGHTNING_POWER 20000 // How much 'zap' is in a strike, used for tesla_zap().
|
||||||
|
|
||||||
|
// The real lightning proc.
|
||||||
|
// This is global until I can figure out a better place for it.
|
||||||
|
// T is the turf that is being struck. If cosmetic is true, the lightning won't actually hurt anything.
|
||||||
|
/proc/lightning_strike(turf/T, cosmetic = FALSE)
|
||||||
|
// First, visuals.
|
||||||
|
|
||||||
|
// Do a lightning flash for the whole planet, if the turf belongs to a planet.
|
||||||
|
var/datum/planet/P = null
|
||||||
|
P = SSplanets.z_to_planet[T.z]
|
||||||
|
if(P)
|
||||||
|
var/datum/weather_holder/holder = P.weather_holder
|
||||||
|
flick("lightning_flash", holder.special_visuals)
|
||||||
|
|
||||||
|
// Before we do the other visuals, we need to see if something is going to hijack our intended target.
|
||||||
|
var/obj/machinery/power/grounding_rod/ground = null // Most of the bad effects of lightning will get negated if a grounding rod is nearby.
|
||||||
|
var/obj/machinery/power/tesla_coil/coil = null // However a tesla coil has higher priority and the strike will bounce.
|
||||||
|
|
||||||
|
for(var/obj/machinery/power/thing in range(LIGHTNING_REDIRECT_RANGE, T))
|
||||||
|
if(istype(thing, /obj/machinery/power/tesla_coil))
|
||||||
|
var/turf/simulated/coil_turf = get_turf(thing)
|
||||||
|
if(istype(coil_turf) && thing.anchored && coil_turf.outdoors)
|
||||||
|
coil = thing
|
||||||
|
break
|
||||||
|
|
||||||
|
if(istype(thing, /obj/machinery/power/grounding_rod))
|
||||||
|
var/turf/simulated/rod_turf = get_turf(thing)
|
||||||
|
if(istype(rod_turf) && thing.anchored && rod_turf.outdoors)
|
||||||
|
ground = thing
|
||||||
|
|
||||||
|
if(coil) // Coil gets highest priority.
|
||||||
|
T = coil.loc
|
||||||
|
else if(ground)
|
||||||
|
T = ground.loc
|
||||||
|
|
||||||
|
// Now make the lightning strike sprite. It will fade and delete itself in a second.
|
||||||
|
new /obj/effect/temporary_effect/lightning_strike(T)
|
||||||
|
|
||||||
|
// For those close up.
|
||||||
|
playsound(T, 'sound/effects/lightningbolt.ogg', 100, 1)
|
||||||
|
|
||||||
|
// And for those far away. If the strike happens on a planet, everyone on the planet will hear it.
|
||||||
|
// Otherwise only those on the current z-level will hear it.
|
||||||
|
var/sound = get_sfx("thunder")
|
||||||
|
for(var/mob/M in player_list)
|
||||||
|
if((P && M.z in P.expected_z_levels) || M.z == T.z)
|
||||||
|
M.playsound_local(get_turf(M), soundin = sound, vol = 70, vary = FALSE, is_global = TRUE)
|
||||||
|
|
||||||
|
if(cosmetic) // Everything beyond here involves potentially damaging things. If we don't want to do that, stop now.
|
||||||
|
return
|
||||||
|
|
||||||
|
if(ground) // All is well.
|
||||||
|
ground.tesla_act(LIGHTNING_POWER, FALSE)
|
||||||
|
return
|
||||||
|
|
||||||
|
else if(coil) // Otherwise lets bounce off the tesla coil.
|
||||||
|
coil.tesla_act(LIGHTNING_POWER, TRUE)
|
||||||
|
|
||||||
|
else // Striking the turf directly.
|
||||||
|
tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE)
|
||||||
|
|
||||||
|
// Some extra effects.
|
||||||
|
// Some apply to those within zap range, others if they were a bit farther away.
|
||||||
|
for(var/mob/living/L in view(5, T))
|
||||||
|
if(get_dist(L, T) <= LIGHTNING_ZAP_RANGE) // They probably got zapped.
|
||||||
|
// The actual damage/electrocution is handled by tesla_zap().
|
||||||
|
L.Paralyse(5)
|
||||||
|
L.stuttering += 20
|
||||||
|
L.make_jittery(20)
|
||||||
|
L.emp_act(1)
|
||||||
|
to_chat(L, span("critical", "You've been struck by lightning!"))
|
||||||
|
|
||||||
|
// If a non-player simplemob was struck, inflict huge damage.
|
||||||
|
// If the damage is fatal, the SA is turned to ash.
|
||||||
|
if(istype(L, /mob/living/simple_animal) && !L.key)
|
||||||
|
var/mob/living/simple_animal/SA = L
|
||||||
|
SA.adjustFireLoss(200)
|
||||||
|
SA.updatehealth()
|
||||||
|
if(SA.health <= 0) // Might be best to check/give simple_mobs siemens when this gets ported to new mobs.
|
||||||
|
SA.visible_message(span("critical", "\The [SA] disintegrates into ash!"))
|
||||||
|
SA.ash()
|
||||||
|
continue // No point deafening something that wont exist.
|
||||||
|
|
||||||
|
// Deafen them.
|
||||||
|
if(L.get_ear_protection() < 2)
|
||||||
|
L.AdjustSleeping(-100)
|
||||||
|
if(iscarbon(L))
|
||||||
|
var/mob/living/carbon/C = L
|
||||||
|
C.ear_deaf += 10
|
||||||
|
to_chat(L, span("danger", "Lightning struck nearby, and the thunderclap is deafening!"))
|
||||||
|
|
||||||
|
#undef GROUNDING_ROD_RANGE
|
||||||
|
#undef LIGHTNING_ZAP_RANGE
|
||||||
|
#undef LIGHTNING_POWER
|
||||||
177
code/modules/artifice/deadringer.dm
Normal file
177
code/modules/artifice/deadringer.dm
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
/obj/item/weapon/deadringer
|
||||||
|
name = "silver pocket watch"
|
||||||
|
desc = "A fancy silver-plated digital pocket watch. Looks expensive."
|
||||||
|
icon = 'icons/obj/deadringer.dmi'
|
||||||
|
icon_state = "deadringer"
|
||||||
|
w_class = ITEMSIZE_SMALL
|
||||||
|
slot_flags = SLOT_ID | SLOT_BELT | SLOT_TIE
|
||||||
|
origin_tech = list(TECH_ILLEGAL = 3)
|
||||||
|
var/activated = 0
|
||||||
|
var/timer = 0
|
||||||
|
var/bruteloss_prev = 999999
|
||||||
|
var/fireloss_prev = 999999
|
||||||
|
var/mob/living/carbon/human/corpse = null
|
||||||
|
var/mob/living/carbon/human/watchowner = null
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/New()
|
||||||
|
..()
|
||||||
|
processing_objects |= src
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch
|
||||||
|
uncloak()
|
||||||
|
processing_objects -= src
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/dropped()
|
||||||
|
if(timer > 20)
|
||||||
|
uncloak()
|
||||||
|
watchowner = null
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/attack_self(var/mob/living/user as mob)
|
||||||
|
var/mob/living/H = src.loc
|
||||||
|
if (!istype(H, /mob/living/carbon/human))
|
||||||
|
to_chat(H,"<font color='blue'>You have no clue what to do with this thing.</font>")
|
||||||
|
return
|
||||||
|
if(!activated)
|
||||||
|
if(timer == 0)
|
||||||
|
to_chat(H, "<font color='blue'>You press a small button on [src]'s side. It starts to hum quietly.</font>")
|
||||||
|
bruteloss_prev = H.getBruteLoss()
|
||||||
|
fireloss_prev = H.getFireLoss()
|
||||||
|
activated = 1
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It buzzes a little.</font>")
|
||||||
|
return
|
||||||
|
if(activated)
|
||||||
|
to_chat(H,"<font color='blue'>You press a small button on [src]'s side. It stops humming.</font>")
|
||||||
|
activated = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/process()
|
||||||
|
if(activated)
|
||||||
|
if (ismob(src.loc))
|
||||||
|
var/mob/living/carbon/human/H = src.loc
|
||||||
|
watchowner = H
|
||||||
|
if(H.getBruteLoss() > bruteloss_prev || H.getFireLoss() > fireloss_prev)
|
||||||
|
deathprevent()
|
||||||
|
activated = 0
|
||||||
|
if(watchowner.isSynthetic())
|
||||||
|
to_chat(watchowner, "<font color='blue'>You fade into nothingness! [src]'s screen blinks, being unable to copy your synthetic body!</font>")
|
||||||
|
else
|
||||||
|
to_chat(watchowner, "<font color='blue'>You fade into nothingness, leaving behind a fake body!</font>")
|
||||||
|
icon_state = "deadringer_cd"
|
||||||
|
timer = 50
|
||||||
|
return
|
||||||
|
if(timer > 0)
|
||||||
|
timer--
|
||||||
|
if(timer == 20)
|
||||||
|
uncloak()
|
||||||
|
if(corpse)
|
||||||
|
new /obj/effect/effect/smoke/chem(corpse.loc)
|
||||||
|
qdel(corpse)
|
||||||
|
if(timer == 0)
|
||||||
|
icon_state = "deadringer"
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/proc/deathprevent()
|
||||||
|
for(var/mob/living/simple_animal/D in oviewers(7, src))
|
||||||
|
D.LoseTarget()
|
||||||
|
watchowner.emote("deathgasp")
|
||||||
|
watchowner.alpha = 15
|
||||||
|
makeacorpse(watchowner)
|
||||||
|
for(var/mob/living/simple_animal/D in oviewers(7, src))
|
||||||
|
D.LoseTarget()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/proc/uncloak()
|
||||||
|
if(watchowner)
|
||||||
|
watchowner.alpha = 255
|
||||||
|
playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/item/weapon/deadringer/proc/makeacorpse(var/mob/living/carbon/human/H)
|
||||||
|
if(H.isSynthetic())
|
||||||
|
return
|
||||||
|
corpse = new /mob/living/carbon/human(H.loc)
|
||||||
|
corpse.setDNA(H.dna.Clone())
|
||||||
|
corpse.death(1) //Kills the new mob
|
||||||
|
var/obj/item/clothing/temp = null
|
||||||
|
if(H.get_equipped_item(slot_w_uniform))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/under/chameleon/changeling(corpse), slot_w_uniform)
|
||||||
|
temp = corpse.get_equipped_item(slot_w_uniform)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_w_uniform)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_wear_suit))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/suit/chameleon/changeling(corpse), slot_wear_suit)
|
||||||
|
temp = corpse.get_equipped_item(slot_wear_suit)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_suit)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_shoes))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/shoes/chameleon/changeling(corpse), slot_shoes)
|
||||||
|
temp = corpse.get_equipped_item(slot_shoes)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_shoes)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_gloves))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/gloves/chameleon/changeling(corpse), slot_gloves)
|
||||||
|
temp = corpse.get_equipped_item(slot_gloves)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_gloves)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_l_ear))
|
||||||
|
temp = H.get_equipped_item(slot_l_ear)
|
||||||
|
corpse.equip_to_slot_or_del(new temp.type(corpse), slot_l_ear)
|
||||||
|
temp = corpse.get_equipped_item(slot_l_ear)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_glasses))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/glasses/chameleon/changeling(corpse), slot_glasses)
|
||||||
|
temp = corpse.get_equipped_item(slot_glasses)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_glasses)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_wear_mask))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/mask/chameleon/changeling(corpse), slot_wear_mask)
|
||||||
|
temp = corpse.get_equipped_item(slot_wear_mask)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_wear_mask)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_head))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/clothing/head/chameleon/changeling(corpse), slot_head)
|
||||||
|
temp = corpse.get_equipped_item(slot_head)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_head)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_belt))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/chameleon/changeling(corpse), slot_belt)
|
||||||
|
temp = corpse.get_equipped_item(slot_belt)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_belt)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
if(H.get_equipped_item(slot_back))
|
||||||
|
corpse.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chameleon/changeling(corpse), slot_back)
|
||||||
|
temp = corpse.get_equipped_item(slot_back)
|
||||||
|
var/obj/item/clothing/c_type = H.get_equipped_item(slot_back)
|
||||||
|
temp.disguise(c_type.type)
|
||||||
|
temp.canremove = 0
|
||||||
|
corpse.identifying_gender = H.identifying_gender
|
||||||
|
corpse.flavor_texts = H.flavor_texts.Copy()
|
||||||
|
corpse.real_name = H.real_name
|
||||||
|
corpse.name = H.name
|
||||||
|
corpse.set_species(corpse.dna.species)
|
||||||
|
corpse.change_hair(H.h_style)
|
||||||
|
corpse.change_facial_hair(H.f_style)
|
||||||
|
corpse.change_hair_color(H.r_hair, H.g_hair, H.b_hair)
|
||||||
|
corpse.change_facial_hair_color(H.r_facial, H.g_facial, H.b_facial)
|
||||||
|
corpse.change_skin_color(H.r_skin, H.g_skin, H.b_skin)
|
||||||
|
corpse.adjustFireLoss(H.getFireLoss())
|
||||||
|
corpse.adjustBruteLoss(H.getBruteLoss())
|
||||||
|
corpse.UpdateAppearance()
|
||||||
|
corpse.regenerate_icons()
|
||||||
|
for(var/obj/item/organ/internal/I in corpse.internal_organs)
|
||||||
|
var/obj/item/organ/internal/G = I
|
||||||
|
G.Destroy()
|
||||||
|
return
|
||||||
@@ -250,9 +250,8 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/obj/effect/beam/i_beam/Destroy()
|
/obj/effect/beam/i_beam/Destroy()
|
||||||
|
. = ..()
|
||||||
if(master.first == src)
|
if(master.first == src)
|
||||||
master.first = null
|
master.first = null
|
||||||
if(next)
|
if(next && !next.gc_destroyed)
|
||||||
qdel(next)
|
qdel_null(next)
|
||||||
next = null
|
|
||||||
..()
|
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
|
|||||||
. += "<b>Nickname:</b> "
|
. += "<b>Nickname:</b> "
|
||||||
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
|
. += "<a href='?src=\ref[src];nickname=1'><b>[pref.nickname]</b></a>"
|
||||||
. += "<br>"
|
. += "<br>"
|
||||||
. += "<b>Biological Gender:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
|
. += "<b>Biological Sex:</b> <a href='?src=\ref[src];bio_gender=1'><b>[gender2text(pref.biological_gender)]</b></a><br>"
|
||||||
. += "<b>Gender Identity:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
|
. += "<b>Pronouns:</b> <a href='?src=\ref[src];id_gender=1'><b>[gender2text(pref.identifying_gender)]</b></a><br>"
|
||||||
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
|
. += "<b>Age:</b> <a href='?src=\ref[src];age=1'>[pref.age]</a><br>"
|
||||||
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
|
. += "<b>Spawn Point</b>: <a href='?src=\ref[src];spawnpoint=1'>[pref.spawnpoint]</a><br>"
|
||||||
if(config.allow_Metadata)
|
if(config.allow_Metadata)
|
||||||
@@ -111,13 +111,13 @@ datum/preferences/proc/set_biological_gender(var/gender)
|
|||||||
return TOPIC_NOACTION
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
else if(href_list["bio_gender"])
|
else if(href_list["bio_gender"])
|
||||||
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
|
var/new_gender = input(user, "Choose your character's biological sex:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
|
||||||
if(new_gender && CanUseTopic(user))
|
if(new_gender && CanUseTopic(user))
|
||||||
pref.set_biological_gender(new_gender)
|
pref.set_biological_gender(new_gender)
|
||||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
else if(href_list["id_gender"])
|
else if(href_list["id_gender"])
|
||||||
var/new_gender = input(user, "Choose your character's identifying gender:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
|
var/new_gender = input(user, "Choose your character's pronouns:", "Character Preference", pref.identifying_gender) as null|anything in all_genders_define_list
|
||||||
if(new_gender && CanUseTopic(user))
|
if(new_gender && CanUseTopic(user))
|
||||||
pref.identifying_gender = new_gender
|
pref.identifying_gender = new_gender
|
||||||
return TOPIC_REFRESH
|
return TOPIC_REFRESH
|
||||||
@@ -158,4 +158,4 @@ datum/preferences/proc/set_biological_gender(var/gender)
|
|||||||
return possible_genders
|
return possible_genders
|
||||||
possible_genders = possible_genders.Copy()
|
possible_genders = possible_genders.Copy()
|
||||||
possible_genders |= NEUTER
|
possible_genders |= NEUTER
|
||||||
return possible_genders
|
return possible_genders
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
S["synth_red"] >> pref.r_synth
|
S["synth_red"] >> pref.r_synth
|
||||||
S["synth_green"] >> pref.g_synth
|
S["synth_green"] >> pref.g_synth
|
||||||
S["synth_blue"] >> pref.b_synth
|
S["synth_blue"] >> pref.b_synth
|
||||||
|
S["synth_markings"] >> pref.synth_markings
|
||||||
pref.preview_icon = null
|
pref.preview_icon = null
|
||||||
S["bgstate"] >> pref.bgstate
|
S["bgstate"] >> pref.bgstate
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
S["synth_red"] << pref.r_synth
|
S["synth_red"] << pref.r_synth
|
||||||
S["synth_green"] << pref.g_synth
|
S["synth_green"] << pref.g_synth
|
||||||
S["synth_blue"] << pref.b_synth
|
S["synth_blue"] << pref.b_synth
|
||||||
|
S["synth_markings"] << pref.synth_markings
|
||||||
S["bgstate"] << pref.bgstate
|
S["bgstate"] << pref.bgstate
|
||||||
|
|
||||||
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
|
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
|
||||||
@@ -120,6 +122,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
character.r_synth = pref.r_synth
|
character.r_synth = pref.r_synth
|
||||||
character.g_synth = pref.g_synth
|
character.g_synth = pref.g_synth
|
||||||
character.b_synth = pref.b_synth
|
character.b_synth = pref.b_synth
|
||||||
|
character.synth_markings = pref.synth_markings
|
||||||
|
|
||||||
// Destroy/cyborgize organs and limbs.
|
// Destroy/cyborgize organs and limbs.
|
||||||
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
|
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
|
||||||
@@ -300,11 +303,12 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
|
|
||||||
. += "<br><a href='?src=\ref[src];marking_style=1'>Body Markings +</a><br>"
|
. += "<br><a href='?src=\ref[src];marking_style=1'>Body Markings +</a><br>"
|
||||||
for(var/M in pref.body_markings)
|
for(var/M in pref.body_markings)
|
||||||
. += "[M] <a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
|
. += "[M] [pref.body_markings.len > 1 ? "<a href='?src=\ref[src];marking_up=[M]'>˄</a> <a href='?src=\ref[src];marking_down=[M]'>˅</a> " : ""]<a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
|
||||||
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
|
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
|
||||||
. += "<br>"
|
. += "<br>"
|
||||||
|
|
||||||
. += "<br>"
|
. += "<br>"
|
||||||
|
. += "<b>Allow Synth markings:</b> <a href='?src=\ref[src];synth_markings=1'><b>[pref.synth_markings ? "Yes" : "No"]</b></a><br>"
|
||||||
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
|
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
|
||||||
if(pref.synth_color)
|
if(pref.synth_color)
|
||||||
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><tr><td>__</td></tr></table></font> "
|
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><tr><td>__</td></tr></table></font> "
|
||||||
@@ -493,6 +497,24 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
pref.body_markings[new_marking] = "#000000" //New markings start black
|
pref.body_markings[new_marking] = "#000000" //New markings start black
|
||||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
|
else if(href_list["marking_up"])
|
||||||
|
var/M = href_list["marking_up"]
|
||||||
|
var/start = pref.body_markings.Find(M)
|
||||||
|
if(start != 1) //If we're not the beginning of the list, swap with the previous element.
|
||||||
|
moveElement(pref.body_markings, start, start-1)
|
||||||
|
else //But if we ARE, become the final element -ahead- of everything else.
|
||||||
|
moveElement(pref.body_markings, start, pref.body_markings.len+1)
|
||||||
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
|
else if(href_list["marking_down"])
|
||||||
|
var/M = href_list["marking_down"]
|
||||||
|
var/start = pref.body_markings.Find(M)
|
||||||
|
if(start != pref.body_markings.len) //If we're not the end of the list, swap with the next element.
|
||||||
|
moveElement(pref.body_markings, start, start+2)
|
||||||
|
else //But if we ARE, become the first element -behind- everything else.
|
||||||
|
moveElement(pref.body_markings, start, 1)
|
||||||
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
else if(href_list["marking_remove"])
|
else if(href_list["marking_remove"])
|
||||||
var/M = href_list["marking_remove"]
|
var/M = href_list["marking_remove"]
|
||||||
pref.body_markings -= M
|
pref.body_markings -= M
|
||||||
@@ -702,6 +724,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
|||||||
pref.b_synth = hex2num(copytext(new_color, 6, 8))
|
pref.b_synth = hex2num(copytext(new_color, 6, 8))
|
||||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
|
else if(href_list["synth_markings"])
|
||||||
|
pref.synth_markings = !pref.synth_markings
|
||||||
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|
||||||
else if(href_list["cycle_bg"])
|
else if(href_list["cycle_bg"])
|
||||||
pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
|
pref.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
|
||||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||||
|
|||||||
@@ -241,6 +241,46 @@ datum/gear/suit/duster
|
|||||||
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
|
||||||
allowed_roles = list("Head of Personnel")
|
allowed_roles = list("Head of Personnel")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/cargo
|
||||||
|
display_name = "cloak, cargo"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/cargo
|
||||||
|
allowed_roles = list("Cargo Technician","Quartermaster")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/mining
|
||||||
|
display_name = "cloak, mining"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
|
||||||
|
allowed_roles = list("Quartermaster","Shaft Miner")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/security
|
||||||
|
display_name = "cloak, security"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/security
|
||||||
|
allowed_roles = list("Head of Security","Detective","Warden","Security Officer")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/service
|
||||||
|
display_name = "cloak, service"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/service
|
||||||
|
allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/engineer
|
||||||
|
display_name = "cloak, engineer"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/engineer
|
||||||
|
allowed_roles = list("Chief Engineer","Station Engineer")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/atmos
|
||||||
|
display_name = "cloak, atmos"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/atmos
|
||||||
|
allowed_roles = list("Chief Engineer","Atmospheric Technician")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/research
|
||||||
|
display_name = "cloak, science"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/research
|
||||||
|
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist")
|
||||||
|
|
||||||
|
/datum/gear/suit/roles/poncho/cloak/medical
|
||||||
|
display_name = "cloak, medical"
|
||||||
|
path = /obj/item/clothing/accessory/poncho/roles/cloak/medical
|
||||||
|
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
|
||||||
|
|
||||||
/datum/gear/suit/unathi_robe
|
/datum/gear/suit/unathi_robe
|
||||||
display_name = "roughspun robe"
|
display_name = "roughspun robe"
|
||||||
path = /obj/item/clothing/suit/unathi/robe
|
path = /obj/item/clothing/suit/unathi/robe
|
||||||
|
|||||||
@@ -114,12 +114,6 @@
|
|||||||
path = /obj/item/weapon/cell/device
|
path = /obj/item/weapon/cell/device
|
||||||
|
|
||||||
/datum/gear/utility/implant
|
/datum/gear/utility/implant
|
||||||
exploitable = 1
|
|
||||||
|
|
||||||
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
|
|
||||||
display_name = "implant, language, EAL"
|
|
||||||
path = /obj/item/weapon/implant/language/eal
|
|
||||||
cost = 2
|
|
||||||
slot = "implant"
|
slot = "implant"
|
||||||
exploitable = 1
|
exploitable = 1
|
||||||
|
|
||||||
@@ -127,8 +121,20 @@
|
|||||||
display_name = "implant, tracking"
|
display_name = "implant, tracking"
|
||||||
path = /obj/item/weapon/implant/tracking/weak
|
path = /obj/item/weapon/implant/tracking/weak
|
||||||
cost = 10
|
cost = 10
|
||||||
slot = "implant"
|
|
||||||
exploitable = 1
|
/datum/gear/utility/implant/language
|
||||||
|
cost = 2
|
||||||
|
exploitable = 0
|
||||||
|
|
||||||
|
/datum/gear/utility/implant/language/eal
|
||||||
|
display_name = "vocal synthesizer, EAL"
|
||||||
|
description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it."
|
||||||
|
path = /obj/item/weapon/implant/language/eal
|
||||||
|
|
||||||
|
/datum/gear/utility/implant/language/skrellian
|
||||||
|
display_name = "vocal synthesizer, Skrellian"
|
||||||
|
description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it."
|
||||||
|
path = /obj/item/weapon/implant/language/skrellian
|
||||||
|
|
||||||
/datum/gear/utility/pen
|
/datum/gear/utility/pen
|
||||||
display_name = "Fountain Pen"
|
display_name = "Fountain Pen"
|
||||||
|
|||||||
@@ -92,6 +92,30 @@
|
|||||||
modifier_type = /datum/modifier/trait/larger
|
modifier_type = /datum/modifier/trait/larger
|
||||||
mutually_exclusive = list(/datum/trait/modifier/physical/smaller, /datum/trait/modifier/physical/small, /datum/trait/modifier/physical/large)
|
mutually_exclusive = list(/datum/trait/modifier/physical/smaller, /datum/trait/modifier/physical/small, /datum/trait/modifier/physical/large)
|
||||||
|
|
||||||
|
/datum/trait/modifier/physical/colorblind_protanopia
|
||||||
|
name = "Protanopia"
|
||||||
|
desc = "You have a form of red-green colorblindness. You cannot see reds, and have trouble distinguishing them from yellows and greens."
|
||||||
|
modifier_type = /datum/modifier/trait/colorblind_protanopia
|
||||||
|
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_tritanopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||||
|
|
||||||
|
/datum/trait/modifier/physical/colorblind_deuteranopia
|
||||||
|
name = "Deuteranopia"
|
||||||
|
desc = "You have a form of red-green colorblindness. You cannot see greens, and have trouble distinguishing them from yellows and reds."
|
||||||
|
modifier_type = /datum/modifier/trait/colorblind_deuteranopia
|
||||||
|
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_tritanopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||||
|
|
||||||
|
/datum/trait/modifier/physical/colorblind_tritanopia
|
||||||
|
name = "Tritanopia"
|
||||||
|
desc = "You have a form of blue-yellow colorblindness. You have trouble distinguishing between blues, greens, and yellows, and see blues and violets as dim."
|
||||||
|
modifier_type = /datum/modifier/trait/colorblind_tritanopia
|
||||||
|
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_monochrome)
|
||||||
|
|
||||||
|
/datum/trait/modifier/physical/colorblind_monochrome
|
||||||
|
name = "Monochromacy"
|
||||||
|
desc = "You are fully colorblind. Your condition is rare, but you can see no colors at all."
|
||||||
|
modifier_type = /datum/modifier/trait/colorblind_monochrome
|
||||||
|
mutually_exclusive = list(/datum/trait/modifier/physical/colorblind_protanopia, /datum/trait/modifier/physical/colorblind_deuteranopia, /datum/trait/modifier/physical/colorblind_tritanopia)
|
||||||
|
|
||||||
// These two traits might be borderline, feel free to remove if they get abused.
|
// These two traits might be borderline, feel free to remove if they get abused.
|
||||||
/datum/trait/modifier/physical/high_metabolism
|
/datum/trait/modifier/physical/high_metabolism
|
||||||
name = "High Metabolism"
|
name = "High Metabolism"
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ datum/preferences
|
|||||||
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
|
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
|
||||||
var/g_synth //Same as above
|
var/g_synth //Same as above
|
||||||
var/b_synth //Same as above
|
var/b_synth //Same as above
|
||||||
|
var/synth_markings = 0 //Enable/disable markings on synth parts.
|
||||||
|
|
||||||
//Some faction information.
|
//Some faction information.
|
||||||
var/home_system = "Unset" //System of birth.
|
var/home_system = "Unset" //System of birth.
|
||||||
|
|||||||
@@ -253,7 +253,8 @@
|
|||||||
var/mob/living/carbon/human/H = user
|
var/mob/living/carbon/human/H = user
|
||||||
|
|
||||||
if(slot && slot == slot_gloves)
|
if(slot && slot == slot_gloves)
|
||||||
if(H.gloves)
|
var/obj/item/clothing/gloves/G = H.gloves
|
||||||
|
if(istype(G))
|
||||||
ring = H.gloves
|
ring = H.gloves
|
||||||
if(ring.glove_level >= src.glove_level)
|
if(ring.glove_level >= src.glove_level)
|
||||||
to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.")
|
to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.")
|
||||||
|
|||||||
@@ -128,6 +128,7 @@
|
|||||||
|
|
||||||
/obj/item/clothing/suit/syndicatefake
|
/obj/item/clothing/suit/syndicatefake
|
||||||
name = "red space suit replica"
|
name = "red space suit replica"
|
||||||
|
icon = 'icons/obj/clothing/spacesuits.dmi'
|
||||||
icon_state = "syndicate"
|
icon_state = "syndicate"
|
||||||
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
|
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
|
||||||
w_class = ITEMSIZE_NORMAL
|
w_class = ITEMSIZE_NORMAL
|
||||||
|
|||||||
@@ -121,8 +121,8 @@
|
|||||||
* Cloak
|
* Cloak
|
||||||
*/
|
*/
|
||||||
/obj/item/clothing/accessory/poncho/roles/cloak
|
/obj/item/clothing/accessory/poncho/roles/cloak
|
||||||
name = "brown cloak"
|
name = "quartermaster's cloak"
|
||||||
desc = "An elaborate brown cloak."
|
desc = "An elaborate brown and gold cloak."
|
||||||
icon_state = "qmcloak"
|
icon_state = "qmcloak"
|
||||||
item_state = "qmcloak"
|
item_state = "qmcloak"
|
||||||
body_parts_covered = null
|
body_parts_covered = null
|
||||||
@@ -169,6 +169,54 @@
|
|||||||
icon_state = "capcloak"
|
icon_state = "capcloak"
|
||||||
item_state = "capcloak"
|
item_state = "capcloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/cargo
|
||||||
|
name = "brown cloak"
|
||||||
|
desc = "A simple brown and black cloak."
|
||||||
|
icon_state = "cargocloak"
|
||||||
|
item_state = "cargocloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/mining
|
||||||
|
name = "trimmed purple cloak"
|
||||||
|
desc = "A trimmed purple and brown cloak."
|
||||||
|
icon_state = "miningcloak"
|
||||||
|
item_state = "miningcloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/security
|
||||||
|
name = "red cloak"
|
||||||
|
desc = "A simple red and black cloak."
|
||||||
|
icon_state = "seccloak"
|
||||||
|
item_state = "seccloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/service
|
||||||
|
name = "green cloak"
|
||||||
|
desc = "A simple green and blue cloak."
|
||||||
|
icon_state = "servicecloak"
|
||||||
|
item_state = "servicecloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/engineer
|
||||||
|
name = "gold cloak"
|
||||||
|
desc = "A simple gold and brown cloak."
|
||||||
|
icon_state = "engicloak"
|
||||||
|
item_state = "engicloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/atmos
|
||||||
|
name = "yellow cloak"
|
||||||
|
desc = "A trimmed yellow and blue cloak."
|
||||||
|
icon_state = "atmoscloak"
|
||||||
|
item_state = "atmoscloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/research
|
||||||
|
name = "purple cloak"
|
||||||
|
desc = "A simple purple and white cloak."
|
||||||
|
icon_state = "scicloak"
|
||||||
|
item_state = "scicloak"
|
||||||
|
|
||||||
|
/obj/item/clothing/accessory/poncho/roles/cloak/medical
|
||||||
|
name = "blue cloak"
|
||||||
|
desc = "A simple blue and white cloak."
|
||||||
|
icon_state = "medcloak"
|
||||||
|
item_state = "medcloak"
|
||||||
|
|
||||||
/obj/item/clothing/accessory/hawaii
|
/obj/item/clothing/accessory/hawaii
|
||||||
name = "flower-pattern shirt"
|
name = "flower-pattern shirt"
|
||||||
desc = "You probably need some welder googles to look at this."
|
desc = "You probably need some welder googles to look at this."
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user