mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 19:13:30 +01:00
Merge branch 'master' of https://github.com/ParadiseSS13/Paradise into turfs
# Conflicts: # code/game/objects/items.dm # code/modules/power/cable.dm # icons/mob/inhands/items_lefthand.dmi # icons/mob/inhands/items_righthand.dmi # icons/obj/lighting.dmi # paradise.dme
This commit is contained in:
@@ -78,7 +78,7 @@ var/global/nologevent = 0
|
||||
body += "<a href='?_src_=vars;Vars=[M.UID()]'>VV</a> - "
|
||||
body += "[ADMIN_TP(M,"TP")] - "
|
||||
if(M.client)
|
||||
body += "<a href='?src=[usr.UID()];priv_msg=[M.UID()]'>PM</a> - "
|
||||
body += "<a href='?src=[usr.UID()];priv_msg=[M.client.UID()]'>PM</a> - "
|
||||
body += "[ADMIN_SM(M,"SM")] - "
|
||||
if(ishuman(M) && M.mind)
|
||||
body += "<a href='?_src_=holder;HeadsetMessage=[M.UID()]'>HM</a> -"
|
||||
@@ -950,9 +950,6 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space
|
||||
for(var/obj/machinery/mech_bay_recharge_port/P in toArea)
|
||||
P.update_recharge_turf()
|
||||
|
||||
for(var/obj/machinery/power/apc/A in toArea)
|
||||
A.init()
|
||||
|
||||
if(gamma_ship_location)
|
||||
gamma_ship_location = 0
|
||||
else
|
||||
@@ -1096,7 +1093,7 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space
|
||||
dat += "<tr><td><b>" + id + "</b></td>"
|
||||
dat += "<td>" + ckey + "</td>"
|
||||
dat += "<td><a href='?src=[UID()];force_discord_unlink=[ckey]'>Unlink</td></tr>"
|
||||
|
||||
|
||||
dat += "</table></body></html>"
|
||||
|
||||
usr << browse(dat, "window=duplicates;size=500x480")
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
}
|
||||
|
||||
function expand(id,job,name,real_name,image,key,ip,antagonist,UID,eyeUID){
|
||||
function expand(id,job,name,real_name,image,key,ip,antagonist,mobUID,clientUID,eyeUID){
|
||||
|
||||
clearAll();
|
||||
|
||||
@@ -75,13 +75,13 @@
|
||||
|
||||
body += "</td><td align='center'>";
|
||||
|
||||
body += "<a href='?src=[UID()];adminplayeropts="+UID+"'>PP</a> - "
|
||||
body += "<a href='?src=[UID()];adminplayeropts="+mobUID+"'>PP</a> - "
|
||||
body += "<a href='?src=[UID()];shownoteckey="+key+"'>N</a> - "
|
||||
body += "<a href='?_src_=vars;Vars="+UID+"'>VV</a> - "
|
||||
body += "<a href='?src=[UID()];traitor="+UID+"'>TP</a> - "
|
||||
body += "<a href='?src=[usr.UID()];priv_msg="+UID+"'>PM</a> - "
|
||||
body += "<a href='?src=[UID()];subtlemessage="+UID+"'>SM</a> - "
|
||||
body += "<a href='?src=[UID()];adminplayerobservefollow="+UID+"'>FLW</a>"
|
||||
body += "<a href='?_src_=vars;Vars="+mobUID+"'>VV</a> - "
|
||||
body += "<a href='?src=[UID()];traitor="+mobUID+"'>TP</a> - "
|
||||
body += "<a href='?src=[usr.UID()];priv_msg="+clientUID+"'>PM</a> - "
|
||||
body += "<a href='?src=[UID()];subtlemessage="+mobUID+"'>SM</a> - "
|
||||
body += "<a href='?src=[UID()];adminplayerobservefollow="+mobUID+"'>FLW</a>"
|
||||
if(eyeUID)
|
||||
body += "|<a href='?src=[UID()];adminplayerobservefollow="+eyeUID+"'>EYE</a>"
|
||||
body += "<br>"
|
||||
@@ -293,6 +293,7 @@
|
||||
var/mob/living/silicon/ai/A = M
|
||||
if(A.client && A.eyeobj) // No point following clientless AI eyes
|
||||
M_eyeUID = "[A.eyeobj.UID()]"
|
||||
var/clientUID = M.client ? M.client.UID() : null
|
||||
//output for each mob
|
||||
dat += {"
|
||||
|
||||
@@ -300,7 +301,7 @@
|
||||
<td align='center' bgcolor='[color]'>
|
||||
<span id='notice_span[i]'></span>
|
||||
<a id='link[i]'
|
||||
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"[M.UID()]", "[M_eyeUID]")'
|
||||
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"[M.UID()]","[clientUID]","[M_eyeUID]")'
|
||||
>
|
||||
<b id='search[i]'>[M_name] - [M_rname] - [M_key] ([M_job])</b>
|
||||
</a>
|
||||
@@ -371,7 +372,7 @@
|
||||
|
||||
dat += {"<td>[(M.client ? "[M.client]" : "No client")]</td>
|
||||
<td align=center><A HREF='?src=[UID()];adminplayeropts=[M.UID()]'>X</A></td>
|
||||
<td align=center><A href='?src=[usr.UID()];priv_msg=[M.UID()]'>PM</A></td>
|
||||
<td align=center><A href='?src=[usr.UID()];priv_msg=[M.client ? M.client.UID() : null]'>PM</A></td>
|
||||
"}
|
||||
switch(is_special_character(M))
|
||||
if(0)
|
||||
@@ -398,7 +399,7 @@
|
||||
dname = M
|
||||
|
||||
return {"<tr><td><a href='?src=[UID()];adminplayeropts=[M.UID()]'>[dname]</a><b>[caption]</b>[logout_status][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>
|
||||
<td><A href='?src=[usr.UID()];priv_msg=[M.UID()]'>PM</A></td>[close ? "</tr>" : ""]"}
|
||||
<td><A href='?src=[usr.UID()];priv_msg=[M.client ? M.client.UID() : null]'>PM</A></td>[close ? "</tr>" : ""]"}
|
||||
|
||||
/datum/admins/proc/check_antagonists()
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
@@ -473,7 +474,7 @@
|
||||
var/mob/M = blob.current
|
||||
if(M)
|
||||
dat += "<tr><td>[ADMIN_PP(M,"[M.real_name]")][M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?priv_msg=[M.client ? M.client.UID() : null]'>PM</A></td>"
|
||||
else
|
||||
dat += "<tr><td><i>Blob not found!</i></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
var/received_irc_pm = -99999
|
||||
var/irc_admin //IRC admin that spoke with them last.
|
||||
var/mute_irc = 0
|
||||
|
||||
var/ssd_warning_acknowledged = FALSE
|
||||
|
||||
////////////////////////////////////
|
||||
//things that require the database//
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define MIN_CLIENT_VERSION 0 //Just an ambiguously low version for now, I don't want to suddenly stop people playing.
|
||||
//I would just like the code ready should it ever need to be used.
|
||||
#define SUGGESTED_CLIENT_VERSION 511 // only integers (e.g: 510, 511) useful here. Does not properly handle minor versions (e.g: 510.58, 511.848)
|
||||
#define SSD_WARNING_TIMER 30 // cycles, not seconds, so 30=60s
|
||||
|
||||
/*
|
||||
When somebody clicks a link in game, this Topic is called first.
|
||||
@@ -73,9 +74,7 @@
|
||||
//Admin PM
|
||||
if(href_list["priv_msg"])
|
||||
var/client/C = locate(href_list["priv_msg"])
|
||||
if(ismob(C)) //Old stuff can feed-in mobs instead of clients
|
||||
var/mob/M = C
|
||||
C = M.client
|
||||
|
||||
if(!C) // Might be a stealthmin ID, so pass it in straight
|
||||
C = href_list["priv_msg"]
|
||||
else if(C.UID() != href_list["priv_msg"])
|
||||
@@ -227,6 +226,9 @@
|
||||
vote_on_poll(pollid, optionid, 1)
|
||||
src << browse(null, "window=playerpoll")
|
||||
handle_player_polling()
|
||||
if(href_list["ssdwarning"])
|
||||
ssd_warning_acknowledged = TRUE
|
||||
to_chat(src, "<span class='notice'>SSD warning acknowledged.</span>")
|
||||
|
||||
switch(href_list["action"])
|
||||
if("openLink")
|
||||
@@ -772,3 +774,16 @@
|
||||
winset(src, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
|
||||
else
|
||||
winset(src, "rpane.changelog", "background-color=none;text-color=#000000")
|
||||
|
||||
|
||||
/client/proc/send_ssd_warning(mob/M)
|
||||
if(!config.ssd_warning)
|
||||
return FALSE
|
||||
if(ssd_warning_acknowledged)
|
||||
return FALSE
|
||||
if(M && M.player_logged < SSD_WARNING_TIMER)
|
||||
return FALSE
|
||||
to_chat(src, "Interacting with SSD players is against server rules unless you've ahelped first for permission. If you have, <a href='byond://?src=[UID()];ssdwarning=accepted'>confirm that</A> and proceed.")
|
||||
return TRUE
|
||||
|
||||
#undef SSD_WARNING_TIMER
|
||||
@@ -629,38 +629,6 @@ BLIND // can't see anything
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/attack_hand(mob/user as mob)
|
||||
//only forward to the attached accessory if the clothing is equipped (not in a storage)
|
||||
if(accessories.len && src.loc == user)
|
||||
for(var/obj/item/clothing/accessory/A in accessories)
|
||||
A.attack_hand(user)
|
||||
return
|
||||
|
||||
if(ishuman(usr) && src.loc == user) //make it harder to accidentally undress yourself
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/MouseDrop(obj/over_object as obj)
|
||||
if(ishuman(usr))
|
||||
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
|
||||
if(!(src.loc == usr))
|
||||
return
|
||||
if(!( usr.restrained() ) && !( usr.stat ) && ( over_object ))
|
||||
if(!usr.canUnEquip(src))
|
||||
to_chat(usr, "[src] appears stuck on you!")
|
||||
return
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
usr.unEquip(src)
|
||||
usr.put_in_r_hand(src)
|
||||
if("l_hand")
|
||||
usr.unEquip(src)
|
||||
usr.put_in_l_hand(src)
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/clothing/under/examine(mob/user)
|
||||
..(user)
|
||||
switch(src.sensor_mode)
|
||||
|
||||
@@ -117,8 +117,8 @@
|
||||
/datum/crafting_recipe/floorbot
|
||||
name = "Floorbot"
|
||||
result = /mob/living/simple_animal/bot/floorbot
|
||||
reqs = list(/obj/item/storage/toolbox/mechanical = 1,
|
||||
/obj/item/stack/tile/plasteel = 1,
|
||||
reqs = list(/obj/item/storage/toolbox = 1,
|
||||
/obj/item/stack/tile/plasteel = 10,
|
||||
/obj/item/assembly/prox_sensor = 1,
|
||||
/obj/item/robot_parts/r_arm = 1)
|
||||
time = 40
|
||||
|
||||
@@ -1773,4 +1773,16 @@
|
||||
/obj/item/clothing/gloves/ring/fluff/benjaminfallout //Benjaminfallout: Pretzel Brassheart
|
||||
name = "Pretzel's Ring"
|
||||
desc = "A small platinum ring with a large light blue diamond. Engraved inside the band are the words: 'To my lovely Pristine Princess. Forever yours, Savinien.'"
|
||||
icon_state = "benjaminfallout_ring"
|
||||
icon_state = "benjaminfallout_ring"
|
||||
|
||||
/obj/item/clothing/under/fluff/voxbodysuit //Gangelwaefre: Kikeri
|
||||
name = "Vox Bodysuit"
|
||||
desc = "A shimmering bodysuit custom-fit to a vox. Has shorts sewn in."
|
||||
lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
icon = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
icon_state = "voxbodysuit"
|
||||
item_state = "voxbodysuit"
|
||||
item_color = "voxbodysuit"
|
||||
body_parts_covered = HEAD|UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
species_fit = list("Vox")
|
||||
@@ -6,6 +6,7 @@
|
||||
event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
|
||||
/datum/event/blob/start()
|
||||
processing = FALSE //so it won't fire again in next tick
|
||||
var/turf/T = pick(blobstart)
|
||||
if(!T)
|
||||
return kill()
|
||||
@@ -23,4 +24,5 @@
|
||||
B.key = M.key
|
||||
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
|
||||
var/image/alert_overlay = image('icons/mob/blob.dmi', "blank_blob")
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B, alert_overlay = alert_overlay)
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B, alert_overlay = alert_overlay)
|
||||
processing = TRUE // Let it naturally end, if it runs successfully
|
||||
@@ -15,8 +15,8 @@
|
||||
var/productivity = 0
|
||||
var/max_items = 40
|
||||
var/datum/research/files
|
||||
var/list/show_categories = list("Food", "Botany Chemicals", "Leather and Cloth")
|
||||
var/list/timesFiveCategories = list("Food", "Botany Chemicals")
|
||||
var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials", "Leather and Cloth")
|
||||
var/list/timesFiveCategories = list("Food", "Botany Chemicals", "Organic Materials")
|
||||
|
||||
/obj/machinery/biogenerator/New()
|
||||
..()
|
||||
|
||||
@@ -397,13 +397,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, "Not when you're not dead!")
|
||||
return
|
||||
|
||||
usr.verbs -= /mob/dead/observer/proc/dead_tele
|
||||
spawn(30)
|
||||
usr.verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
var/area/A = input("Area to jump to", "BOOYEA") as null|anything in ghostteleportlocs
|
||||
var/area/thearea = ghostteleportlocs[A]
|
||||
if(!thearea) return
|
||||
|
||||
if(!thearea)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
@@ -411,6 +409,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
|
||||
if(!L || !L.len)
|
||||
to_chat(usr, "<span class='warning'>No area available.</span>")
|
||||
return
|
||||
|
||||
usr.forceMove(pick(L))
|
||||
following = null
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
regenerate_icons() // Make sure the inventory updates
|
||||
|
||||
handle_ghosted()
|
||||
handle_ssd()
|
||||
|
||||
/mob/living/carbon/human/proc/handle_ghosted()
|
||||
if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
|
||||
@@ -48,6 +49,22 @@
|
||||
if(player_ghosted % 150 == 0)
|
||||
force_cryo_human(src)
|
||||
|
||||
/mob/living/carbon/human/proc/handle_ssd()
|
||||
if(player_logged > 0 && stat != DEAD && job)
|
||||
player_logged++
|
||||
if(istype(loc, /obj/machinery/cryopod))
|
||||
return
|
||||
if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!is_station_level(T.z))
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
if(cryo_ssd(src))
|
||||
var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40)
|
||||
P.name = "NT SSD Teleportation Portal"
|
||||
if(A.fast_despawn)
|
||||
force_cryo_human(src)
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
|
||||
..()
|
||||
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
|
||||
|
||||
@@ -42,3 +42,9 @@
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
QDEL_IN(animation, 15)
|
||||
|
||||
/mob/living/silicon/death(gibbed)
|
||||
. = ..()
|
||||
if(!gibbed)
|
||||
if(death_sound)
|
||||
playsound(get_turf(src), death_sound, 200, 1)
|
||||
|
||||
@@ -28,7 +28,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
|
||||
if(candidate)
|
||||
if(!istype(candidate))
|
||||
message_admins("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate is not a pAI)")
|
||||
message_admins("Warning: possible href exploit by [key_name_admin(usr)] (paiController/Topic, candidate is not a pAI)")
|
||||
log_debug("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate is not a pAI)")
|
||||
return
|
||||
|
||||
@@ -55,7 +55,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
|
||||
pai_candidates -= candidate
|
||||
usr << browse(null, "window=findPai")
|
||||
|
||||
return
|
||||
|
||||
if("signup" in href_list)
|
||||
var/mob/dead/observer/O = locate(href_list["signup"])
|
||||
@@ -71,8 +71,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
|
||||
if(candidate)
|
||||
if(candidate.key && usr.key && candidate.key != usr.key)
|
||||
message_admins("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate and usr are different mobs)")
|
||||
log_debug("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate and usr are different mobs)")
|
||||
message_admins("Warning: possible href exploit by [key_name_admin(usr)] (paiController/Topic, candidate and usr have different keys)")
|
||||
log_debug("Warning: possible href exploit by [key_name(usr)] (paiController/Topic, candidate and usr have different keys)")
|
||||
return
|
||||
|
||||
if(href_list["new"])
|
||||
|
||||
@@ -248,9 +248,9 @@
|
||||
death()
|
||||
|
||||
/mob/living/silicon/robot/drone/proc/full_law_reset()
|
||||
clear_supplied_laws()
|
||||
clear_inherent_laws()
|
||||
clear_ion_laws()
|
||||
clear_supplied_laws(TRUE)
|
||||
clear_inherent_laws(TRUE)
|
||||
clear_ion_laws(TRUE)
|
||||
laws = new /datum/ai_laws/drone
|
||||
|
||||
//Reboot procs.
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/speak_exclamation = "declares"
|
||||
var/speak_query = "queries"
|
||||
var/pose //Yes, now AIs can pose too.
|
||||
var/death_sound = 'sound/voice/borg_deathsound.ogg'
|
||||
|
||||
//var/sensor_mode = 0 //Determines the current HUD.
|
||||
|
||||
|
||||
@@ -210,23 +210,29 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/created_name = "Floorbot"
|
||||
var/toolbox = /obj/item/storage/toolbox/mechanical
|
||||
var/toolbox_color = "" //Blank for blue, r for red, y for yellow, etc.
|
||||
|
||||
/obj/item/toolbox_tiles_sensor
|
||||
/obj/item/toolbox_tiles/sensor
|
||||
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
|
||||
name = "tiles, toolbox and sensor arrangement"
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "toolbox_tiles_sensor"
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/created_name = "Floorbot"
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
/obj/item/storage/toolbox/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
|
||||
var/list/allowed_toolbox = list(/obj/item/storage/toolbox/emergency, //which toolboxes can be made into floorbots
|
||||
/obj/item/storage/toolbox/electrical,
|
||||
/obj/item/storage/toolbox/mechanical,
|
||||
/obj/item/storage/toolbox/green,
|
||||
/obj/item/storage/toolbox/syndicate,
|
||||
/obj/item/storage/toolbox/fakesyndi)
|
||||
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
..()
|
||||
return
|
||||
if(!is_type_in_list(src, allowed_toolbox))
|
||||
return
|
||||
if(type == /obj/item/storage/toolbox/green/memetic)
|
||||
return
|
||||
if(contents.len >= 1)
|
||||
to_chat(user, "<span class='warning'>They won't fit in, as there is already stuff inside.</span>")
|
||||
return
|
||||
@@ -234,6 +240,23 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
if(user.s_active)
|
||||
user.s_active.close(user)
|
||||
var/obj/item/toolbox_tiles/B = new /obj/item/toolbox_tiles
|
||||
B.toolbox = type
|
||||
switch(B.toolbox)
|
||||
if(/obj/item/storage/toolbox/mechanical/old)
|
||||
B.toolbox_color = "ob"
|
||||
if(/obj/item/storage/toolbox/emergency)
|
||||
B.toolbox_color = "r"
|
||||
if(/obj/item/storage/toolbox/emergency/old)
|
||||
B.toolbox_color = "or"
|
||||
if(/obj/item/storage/toolbox/electrical)
|
||||
B.toolbox_color = "y"
|
||||
if(/obj/item/storage/toolbox/green)
|
||||
B.toolbox_color = "g"
|
||||
if(/obj/item/storage/toolbox/syndicate)
|
||||
B.toolbox_color = "s"
|
||||
if(/obj/item/storage/toolbox/fakesyndi)
|
||||
B.toolbox_color = "s"
|
||||
B.icon_state = "[B.toolbox_color]toolbox_tiles"
|
||||
user.put_in_hands(B)
|
||||
to_chat(user, "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>")
|
||||
user.unEquip(src, 1)
|
||||
@@ -246,8 +269,10 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
..()
|
||||
if(isprox(W))
|
||||
qdel(W)
|
||||
var/obj/item/toolbox_tiles_sensor/B = new /obj/item/toolbox_tiles_sensor()
|
||||
var/obj/item/toolbox_tiles/sensor/B = new /obj/item/toolbox_tiles/sensor()
|
||||
B.created_name = created_name
|
||||
B.toolbox_color = src.toolbox_color
|
||||
B.icon_state = "[B.toolbox_color]toolbox_tiles_sensor"
|
||||
user.put_in_hands(B)
|
||||
to_chat(user, "<span class='notice'>You add the sensor to the toolbox and tiles.</span>")
|
||||
user.unEquip(src, 1)
|
||||
@@ -263,12 +288,11 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
created_name = t
|
||||
log_game("[key_name(user)] has renamed a robot to [t]")
|
||||
|
||||
/obj/item/toolbox_tiles_sensor/attackby(obj/item/W, mob/user, params)
|
||||
/obj/item/toolbox_tiles/sensor/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
|
||||
qdel(W)
|
||||
var/turf/T = get_turf(user.loc)
|
||||
var/mob/living/simple_animal/bot/floorbot/A = new /mob/living/simple_animal/bot/floorbot(T)
|
||||
var/mob/living/simple_animal/bot/floorbot/A = new(drop_location(), toolbox_color)
|
||||
A.name = created_name
|
||||
A.robot_arm = W.type
|
||||
to_chat(user, "<span class='notice'>You add the robot arm to the odd looking toolbox assembly. Boop beep!</span>")
|
||||
@@ -287,10 +311,9 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
//Medbot Assembly
|
||||
/obj/item/storage/firstaid/attackby(obj/item/I, mob/user, params)
|
||||
if(!istype(I, /obj/item/robot_parts/l_arm) && !istype(I, /obj/item/robot_parts/r_arm))
|
||||
return ..()
|
||||
return ..()
|
||||
else
|
||||
robot_arm = I.type
|
||||
|
||||
|
||||
//Making a medibot!
|
||||
if(contents.len)
|
||||
@@ -298,7 +321,7 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
return
|
||||
|
||||
var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly(loc, med_bot_skin)
|
||||
|
||||
|
||||
A.req_one_access = req_one_access
|
||||
A.syndicate_aligned = syndicate_aligned
|
||||
A.treatment_oxy = treatment_oxy
|
||||
@@ -492,7 +515,7 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
|
||||
//General Griefsky
|
||||
|
||||
else if((istype(I, /obj/item/wrench)) && (build_step == 3))
|
||||
else if((istype(I, /obj/item/wrench)) && (build_step == 3))
|
||||
var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly
|
||||
user.put_in_hands(A)
|
||||
to_chat(user, "<span class='notice'>You adjust the arm slots for extra weapons!.</span>")
|
||||
@@ -516,12 +539,12 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
build_step++
|
||||
to_chat(user, "<span class='notice'>You add an energy sword to [src]!.</span>")
|
||||
qdel(I)
|
||||
|
||||
|
||||
else if((istype(I, /obj/item/melee/energy/sword)) && (build_step == 3))
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You complete General Griefsky!.</span>")
|
||||
var/mob/living/simple_animal/bot/secbot/griefsky/S = new /mob/living/simple_animal/bot/secbot/griefsky
|
||||
var/mob/living/simple_animal/bot/secbot/griefsky/S = new /mob/living/simple_animal/bot/secbot/griefsky
|
||||
S.forceMove(get_turf(src))
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
@@ -537,7 +560,7 @@ var/robot_arm = /obj/item/robot_parts/l_arm
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You complete Genewul Giftskee!.</span>")
|
||||
var/mob/living/simple_animal/bot/secbot/griefsky/toy/S = new /mob/living/simple_animal/bot/secbot/griefsky/toy
|
||||
var/mob/living/simple_animal/bot/secbot/griefsky/toy/S = new /mob/living/simple_animal/bot/secbot/griefsky/toy
|
||||
S.forceMove(get_turf(src))
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "floorbot0"
|
||||
density = 0
|
||||
anchored = 0
|
||||
anchored = FALSE
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/max_targets = 50
|
||||
var/turf/target
|
||||
var/oldloc = null
|
||||
var/toolbox_color = ""
|
||||
|
||||
#define HULL_BREACH 1
|
||||
#define BRIDGE_MODE 2
|
||||
@@ -40,12 +41,16 @@
|
||||
#define REPLACE_TILE 5
|
||||
#define TILE_EMAG 6
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/New()
|
||||
/mob/living/simple_animal/bot/floorbot/New(mapload, new_toolbox_color)
|
||||
..()
|
||||
toolbox_color = new_toolbox_color
|
||||
update_icon()
|
||||
var/datum/job/engineer/J = new/datum/job/engineer
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
if(toolbox_color == "s")
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/bot_reset()
|
||||
..()
|
||||
@@ -53,7 +58,7 @@
|
||||
oldloc = null
|
||||
ignore_list = list()
|
||||
nagged = 0
|
||||
anchored = 0
|
||||
anchored = FALSE
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/set_custom_texts()
|
||||
@@ -235,7 +240,7 @@
|
||||
repair(target)
|
||||
else if(emagged == 2 && istype(target,/turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = target
|
||||
anchored = 1
|
||||
anchored = TRUE
|
||||
mode = BOT_REPAIRING
|
||||
if(prob(90))
|
||||
F.break_tile_to_plating()
|
||||
@@ -244,7 +249,7 @@
|
||||
audible_message("<span class='danger'>[src] makes an excited booping sound.</span>")
|
||||
spawn(50)
|
||||
amount ++
|
||||
anchored = 0
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
path = list()
|
||||
@@ -272,11 +277,11 @@
|
||||
if(HULL_BREACH) //The most common job, patching breaches in the station's hull.
|
||||
if(is_hull_breach(scan_target)) //Ensure that the targeted space turf is actually part of the station, and not random space.
|
||||
result = scan_target
|
||||
anchored = 1 //Prevent the floorbot being blown off-course while trying to reach a hull breach.
|
||||
anchored = TRUE //Prevent the floorbot being blown off-course while trying to reach a hull breach.
|
||||
if(BRIDGE_MODE) //Only space turfs in our chosen direction are considered.
|
||||
if(get_dir(src, scan_target) == targetdirection)
|
||||
result = scan_target
|
||||
anchored = 1
|
||||
anchored = TRUE
|
||||
if(REPLACE_TILE)
|
||||
F = scan_target
|
||||
if(istype(F, /turf/simulated/floor/plating)) //The floor must not already have a tile.
|
||||
@@ -306,9 +311,10 @@
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
return
|
||||
anchored = 1
|
||||
icon_state = "floorbot-c"
|
||||
anchored = TRUE
|
||||
icon_state = "[toolbox_color]floorbot-c"
|
||||
if(istype(target_turf, /turf/space/)) //If we are fixing an area not part of pure space, it is
|
||||
icon_state = "[toolbox_color]floorbot-c"
|
||||
visible_message("<span class='notice'>[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] </span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(50)
|
||||
@@ -320,11 +326,12 @@
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
anchored = FALSE
|
||||
target = null
|
||||
else
|
||||
var/turf/simulated/floor/F = target_turf
|
||||
mode = BOT_REPAIRING
|
||||
icon_state = "[toolbox_color]floorbot-c"
|
||||
visible_message("<span class='notice'>[src] begins repairing the floor.</span>")
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
@@ -334,7 +341,7 @@
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon()
|
||||
anchored = 0
|
||||
anchored = FALSE
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/eattile(obj/item/stack/tile/plasteel/T)
|
||||
@@ -380,9 +387,9 @@
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/update_icon()
|
||||
if(amount > 0)
|
||||
icon_state = "floorbot[on]"
|
||||
icon_state = "[toolbox_color]floorbot[on]"
|
||||
else
|
||||
icon_state = "floorbot[on]e"
|
||||
icon_state = "[toolbox_color]floorbot[on]e"
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/explode()
|
||||
on = 0
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
spawn() alert("You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
|
||||
if(matches)
|
||||
if(M.client)
|
||||
message_admins("<font color='red'><B>Notice: </B><font color='blue'><A href='?src=[usr.UID()];priv_msg=[src.UID()]'>[key_name_admin(src)]</A> has the same [matches] as <A href='?src=[usr.UID()];priv_msg=[M.UID()]'>[key_name_admin(M)]</A>.</font>", 1)
|
||||
message_admins("<font color='red'><B>Notice: </B><font color='blue'><A href='?src=[usr.UID()];priv_msg=[src.client.UID()]'>[key_name_admin(src)]</A> has the same [matches] as <A href='?src=[usr.UID()];priv_msg=[M.client.UID()]'>[key_name_admin(M)]</A>.</font>", 1)
|
||||
log_adminwarn("Notice: [key_name(src)] has the same [matches] as [key_name(M)].")
|
||||
else
|
||||
message_admins("<font color='red'><B>Notice: </B><font color='blue'><A href='?src=[usr.UID()];priv_msg=[src.UID()]'>[key_name_admin(src)]</A> has the same [matches] as [key_name_admin(M)] (no longer logged in). </font>", 1)
|
||||
message_admins("<font color='red'><B>Notice: </B><font color='blue'><A href='?src=[usr.UID()];priv_msg=[src.client.UID()]'>[key_name_admin(src)]</A> has the same [matches] as [key_name_admin(M)] (no longer logged in). </font>", 1)
|
||||
log_adminwarn("Notice: [key_name(src)] has the same [matches] as [key_name(M)] (no longer logged in).")
|
||||
|
||||
/mob/Login()
|
||||
|
||||
@@ -901,13 +901,18 @@ var/list/slot_equipment_priority = list( \
|
||||
/mob/MouseDrop(mob/M as mob)
|
||||
..()
|
||||
if(M != usr) return
|
||||
if(isliving(M)) // Ewww
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if(L.mob_size <= MOB_SIZE_SMALL)
|
||||
return // Stops pAI drones and small mobs (borers, parrots, crabs) from stripping people. --DZD
|
||||
if(!M.can_strip) return
|
||||
if(usr == src) return
|
||||
if(!Adjacent(usr)) return
|
||||
if(!M.can_strip)
|
||||
return
|
||||
if(usr == src)
|
||||
return
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isLivingSSD(src) && M.client && M.client.send_ssd_warning(src))
|
||||
return
|
||||
show_inv(usr)
|
||||
|
||||
/mob/proc/can_use_hands()
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
if(battery_module && battery_module.battery && battery_module.battery.charge)
|
||||
var/obj/item/stock_parts/cell/cell = battery_module.battery
|
||||
if(cell.use(amount * CELLRATE))
|
||||
if(cell.use(amount * GLOB.CELLRATE))
|
||||
return TRUE
|
||||
else // Discharge the cell anyway.
|
||||
cell.use(min(amount*CELLRATE, cell.charge))
|
||||
cell.use(min(amount*GLOB.CELLRATE, cell.charge))
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -137,18 +137,17 @@
|
||||
return 1
|
||||
return -1
|
||||
|
||||
/datum/computer_file/program/card_mod/proc/format_jobs(list/jobs)
|
||||
/datum/computer_file/program/card_mod/proc/format_jobs(list/jobs, targetrank, list/jobformats)
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
|
||||
if(!card_slot || !card_slot.stored_card)
|
||||
return null
|
||||
var/obj/item/card/id/id_card = card_slot.stored_card
|
||||
var/list/formatted = list()
|
||||
for(var/job in jobs)
|
||||
formatted.Add(list(list(
|
||||
"display_name" = replacetext(job, " ", " "),
|
||||
"target_rank" = id_card && id_card.assignment ? id_card.assignment : "Unassigned",
|
||||
"job" = job)))
|
||||
|
||||
"target_rank" = targetrank,
|
||||
"job" = job,
|
||||
"jlinkformat" = jobformats[job] ? jobformats[job] : null)))
|
||||
return formatted
|
||||
|
||||
|
||||
@@ -225,11 +224,12 @@
|
||||
var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN))
|
||||
//let custom jobs function as an impromptu alt title, mainly for sechuds
|
||||
if(temp_t && modify)
|
||||
SSjobs.log_job_transfer(modify.registered_name, modify.getRankAndAssignment(), temp_t, scan.registered_name)
|
||||
modify.assignment = temp_t
|
||||
log_game("[key_name(usr)] has given \"[modify.registered_name]\" the custom job title \"[temp_t]\".")
|
||||
else
|
||||
var/list/access = list()
|
||||
if(is_centcom)
|
||||
if(is_centcom && islist(get_centcom_access(t1)))
|
||||
access = get_centcom_access(t1)
|
||||
else
|
||||
var/datum/job/jobdatum
|
||||
@@ -249,6 +249,16 @@
|
||||
if(t1 == "Civilian")
|
||||
message_admins("[key_name_admin(usr)] has reassigned \"[modify.registered_name]\" from \"[jobnamedata]\" to \"[t1]\".")
|
||||
|
||||
SSjobs.log_job_transfer(modify.registered_name, jobnamedata, t1, scan.registered_name)
|
||||
SSjobs.slot_job_transfer(modify.rank, t1)
|
||||
|
||||
var/mob/living/carbon/human/H = modify.getPlayer()
|
||||
if(istype(H))
|
||||
if(jobban_isbanned(H, t1))
|
||||
message_admins("[ADMIN_FULLMONTY(H)] has been assigned the job [t1], in possible violation of their job ban.")
|
||||
if(H.mind)
|
||||
H.mind.playtime_role = t1
|
||||
|
||||
modify.access = access
|
||||
modify.assignment = t1
|
||||
modify.rank = t1
|
||||
@@ -271,6 +281,18 @@
|
||||
if("PRG_mode")
|
||||
mode = text2num(href_list["mode_target"])
|
||||
|
||||
if("PRG_wipe_my_logs")
|
||||
if(is_authenticated(usr) && is_centcom)
|
||||
var/delcount = SSjobs.delete_log_records(scan.registered_name, FALSE)
|
||||
if(delcount)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
if("PRG_wipe_all_logs")
|
||||
if(is_authenticated(usr))
|
||||
var/delcount = SSjobs.delete_log_records(scan.registered_name, TRUE)
|
||||
if(delcount)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
if("PRG_print")
|
||||
if(!printing && computer)
|
||||
printing = 1
|
||||
@@ -312,6 +334,7 @@
|
||||
var/jobnamedata = modify.getRankAndAssignment()
|
||||
log_game("[key_name(usr)] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\".")
|
||||
message_admins("[key_name_admin(usr)] has terminated the employment of \"[modify.registered_name]\" the \"[jobnamedata]\".")
|
||||
SSjobs.log_job_transfer(modify.registered_name, jobnamedata, "Terminated", scan.registered_name)
|
||||
modify.assignment = "Terminated"
|
||||
modify.access = list()
|
||||
callHook("terminate_employee", list(modify))
|
||||
@@ -398,6 +421,7 @@
|
||||
data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----"
|
||||
data["target_rank"] = get_target_rank()
|
||||
data["scan_name"] = scan ? scan.name : "-----"
|
||||
data["scan_owner"] = scan && scan.registered_name ? scan.registered_name : null
|
||||
data["authenticated"] = is_authenticated(user)
|
||||
data["has_modify"] = !!modify
|
||||
data["account_number"] = modify ? modify.associated_account_number : null
|
||||
@@ -405,14 +429,17 @@
|
||||
data["all_centcom_access"] = null
|
||||
data["regions"] = null
|
||||
|
||||
data["engineering_jobs"] = format_jobs(engineering_positions)
|
||||
data["medical_jobs"] = format_jobs(medical_positions)
|
||||
data["science_jobs"] = format_jobs(science_positions)
|
||||
data["security_jobs"] = format_jobs(security_positions)
|
||||
data["support_jobs"] = format_jobs(support_positions)
|
||||
data["civilian_jobs"] = format_jobs(civilian_positions)
|
||||
data["special_jobs"] = format_jobs(whitelisted_positions)
|
||||
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
|
||||
var/list/job_formats = SSjobs.format_jobs_for_id_computer(modify)
|
||||
|
||||
data["top_jobs"] = format_jobs(list("Captain", "Custom"), data["target_rank"], job_formats)
|
||||
data["engineering_jobs"] = format_jobs(engineering_positions, data["target_rank"], job_formats)
|
||||
data["medical_jobs"] = format_jobs(medical_positions, data["target_rank"], job_formats)
|
||||
data["science_jobs"] = format_jobs(science_positions, data["target_rank"], job_formats)
|
||||
data["security_jobs"] = format_jobs(security_positions, data["target_rank"], job_formats)
|
||||
data["support_jobs"] = format_jobs(support_positions, data["target_rank"], job_formats)
|
||||
data["civilian_jobs"] = format_jobs(civilian_positions, data["target_rank"], job_formats)
|
||||
data["special_jobs"] = format_jobs(whitelisted_positions, data["target_rank"], job_formats)
|
||||
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs(), data["target_rank"], job_formats)
|
||||
data["card_skins"] = format_card_skins(get_station_card_skins())
|
||||
|
||||
data["job_slots"] = format_job_slots()
|
||||
@@ -423,6 +450,9 @@
|
||||
data["cooldown_mins"] = mins
|
||||
data["cooldown_secs"] = (seconds < 10) ? "0[seconds]" : seconds
|
||||
|
||||
if(mode == 3 && is_authenticated(user))
|
||||
data["id_change_html"] = SSjobs.fetch_transfer_record_html(is_centcom)
|
||||
|
||||
if(modify)
|
||||
data["current_skin"] = modify.icon_state
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
data["powermonitor"] = attached ? TRUE : FALSE
|
||||
|
||||
if(attached)
|
||||
var/datum/powernet/powernet = attached.get_powernet()
|
||||
var/datum/powernet/powernet = attached.powernet
|
||||
data["poweravail"] = powernet.avail
|
||||
data["powerload"] = powernet.viewload
|
||||
data["powerdemand"] = powernet.load
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
return
|
||||
|
||||
if(use_power(charge_rate, charging=1))
|
||||
holder.give_power(charge_rate * CELLRATE)
|
||||
holder.give_power(charge_rate * GLOB.CELLRATE)
|
||||
|
||||
|
||||
/obj/item/computer_hardware/recharger/APC
|
||||
|
||||
@@ -131,13 +131,13 @@ obj/item/clipboard/proc/penPlacement(mob/user, obj/item/pen/P, placing)
|
||||
else
|
||||
penPlacement(usr, containedpen, FALSE)
|
||||
else if(href_list["remove"])
|
||||
var/obj/item/P = locate(href_list["remove"])
|
||||
var/obj/item/P = locate(href_list["remove"]) in src
|
||||
if(isPaperwork(P))
|
||||
usr.put_in_hands(P)
|
||||
to_chat(usr, "<span class='notice'>You remove [P] from [src].</span>")
|
||||
checkTopPaper() //So we don't accidentally make the top sheet not be on the clipboard
|
||||
else if(href_list["viewOrWrite"])
|
||||
var/obj/item/P = locate(href_list["viewOrWrite"])
|
||||
var/obj/item/P = locate(href_list["viewOrWrite"]) in src
|
||||
if(!isPaperwork(P))
|
||||
return
|
||||
if(is_pen(I) && isPaperwork(P) != PHOTO) //Because you can't write on photos that aren't in your hand
|
||||
@@ -148,7 +148,7 @@ obj/item/clipboard/proc/penPlacement(mob/user, obj/item/pen/P, placing)
|
||||
var/obj/item/photo/Ph = P
|
||||
Ph.show(usr)
|
||||
else if(href_list["topPaper"])
|
||||
var/obj/item/P = locate(href_list["topPaper"])
|
||||
var/obj/item/P = locate(href_list["topPaper"]) in src
|
||||
if(P == toppaper)
|
||||
return
|
||||
to_chat(usr, "<span class='notice'>You flick the pages so that [P] is on top.</span>")
|
||||
|
||||
+38
-42
@@ -46,7 +46,6 @@
|
||||
name = "area power controller"
|
||||
desc = "A control terminal for the area electrical systems."
|
||||
icon_state = "apc0"
|
||||
anchored = 1
|
||||
use_power = NO_POWER_USE
|
||||
req_access = list(access_engine_equip)
|
||||
siemens_strength = 1
|
||||
@@ -55,7 +54,7 @@
|
||||
var/areastring = null
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/start_charge = 90 // initial cell charge %
|
||||
var/cell_type = 2500
|
||||
var/cell_type = 2500 //Base cell has 2500 capacity. Enter the path of a different cell you want to use. cell determines charge rates, max capacity, ect. These can also be changed with other APC vars, but isn't recommended to minimize the risk of accidental usage of dirty editted APCs
|
||||
var/opened = 0 //0=closed, 1=opened, 2=cover removed
|
||||
var/shorted = 0
|
||||
var/lighting = 3
|
||||
@@ -140,40 +139,35 @@
|
||||
/obj/machinery/power/apc/connect_to_network()
|
||||
//Override because the APC does not directly connect to the network; it goes through a terminal.
|
||||
//The terminal is what the power computer looks for anyway.
|
||||
if(!terminal)
|
||||
make_terminal()
|
||||
if(terminal)
|
||||
terminal.connect_to_network()
|
||||
|
||||
/obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0)
|
||||
/obj/machinery/power/apc/New(turf/loc, ndir, building = 0)
|
||||
if(!armor)
|
||||
armor = list(melee = 20, bullet = 20, laser = 10, energy = 100, bomb = 30, bio = 100, rad = 100)
|
||||
..()
|
||||
GLOB.apcs += src
|
||||
GLOB.apcs = sortAtom(GLOB.apcs)
|
||||
wires = new(src)
|
||||
|
||||
wires = new(src)
|
||||
// offset 24 pixels in direction of dir
|
||||
// this allows the APC to be embedded in a wall, yet still inside an area
|
||||
if(building)
|
||||
dir = ndir
|
||||
src.tdir = dir // to fix Vars bug
|
||||
dir = SOUTH
|
||||
setDir(ndir)
|
||||
tdir = dir // to fix Vars bug
|
||||
setDir(SOUTH)
|
||||
|
||||
pixel_x = (src.tdir & 3)? 0 : (src.tdir == 4 ? 24 : -24)
|
||||
pixel_y = (src.tdir & 3)? (src.tdir ==1 ? 24 : -24) : 0
|
||||
if(building==0)
|
||||
init()
|
||||
else
|
||||
if(building)
|
||||
area = get_area(src)
|
||||
area.apc |= src
|
||||
opened = 1
|
||||
operating = 0
|
||||
name = "[area.name] APC"
|
||||
stat |= MAINT
|
||||
src.update_icon()
|
||||
spawn(5)
|
||||
src.update()
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, .proc/update), 5)
|
||||
|
||||
/obj/machinery/power/apc/Destroy()
|
||||
GLOB.apcs -= src
|
||||
@@ -196,14 +190,17 @@
|
||||
// create a terminal object at the same position as original turf loc
|
||||
// wires will attach to this
|
||||
terminal = new/obj/machinery/power/terminal(src.loc)
|
||||
terminal.dir = tdir
|
||||
terminal.setDir(tdir)
|
||||
terminal.master = src
|
||||
|
||||
/obj/machinery/power/apc/proc/init()
|
||||
/obj/machinery/power/apc/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!mapload)
|
||||
return
|
||||
has_electronics = 2 //installed and secured
|
||||
// is starting with a power cell installed, create it and set its charge level
|
||||
if(cell_type)
|
||||
src.cell = new/obj/item/stock_parts/cell(src)
|
||||
cell = new/obj/item/stock_parts/cell(src)
|
||||
cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively)
|
||||
cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value)
|
||||
|
||||
@@ -222,12 +219,12 @@
|
||||
area = get_area_name(areastring)
|
||||
name = "\improper [area.name] APC"
|
||||
area.apc |= src
|
||||
|
||||
update_icon()
|
||||
|
||||
make_terminal()
|
||||
|
||||
spawn(5)
|
||||
src.update()
|
||||
addtimer(CALLBACK(src, .proc/update), 5)
|
||||
|
||||
/obj/machinery/power/apc/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
@@ -1087,14 +1084,9 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
//Returns 1 if the APC should attempt to charge
|
||||
/obj/machinery/power/apc/proc/attempt_charging()
|
||||
return (chargemode && charging == 1 && operating)
|
||||
|
||||
/obj/machinery/power/apc/draw_power(var/amount)
|
||||
/obj/machinery/power/apc/add_load(amount)
|
||||
if(terminal && terminal.powernet)
|
||||
return terminal.powernet.draw_power(amount)
|
||||
return 0
|
||||
terminal.add_load(amount)
|
||||
|
||||
/obj/machinery/power/apc/avail()
|
||||
if(terminal)
|
||||
@@ -1103,7 +1095,6 @@
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/apc/process()
|
||||
|
||||
if(stat & (BROKEN|MAINT))
|
||||
return
|
||||
if(!area.requires_power)
|
||||
@@ -1139,18 +1130,21 @@
|
||||
|
||||
if(cell && !shorted)
|
||||
// draw power from cell as before to power the area
|
||||
var/cellused = min(cell.charge, CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
|
||||
var/cellused = min(cell.charge, GLOB.CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
|
||||
cell.use(cellused)
|
||||
|
||||
if(excess > lastused_total) // if power excess recharge the cell
|
||||
// by the same amount just used
|
||||
var/draw = draw_power(cellused/CELLRATE) // draw the power needed to charge this cell
|
||||
cell.give(draw * CELLRATE)
|
||||
cell.give(cellused)
|
||||
add_load(cellused/GLOB.CELLRATE) // add the load used to recharge the cell
|
||||
|
||||
|
||||
else // no excess, and not enough per-apc
|
||||
if( (cell.charge/CELLRATE + excess) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
|
||||
var/draw = draw_power(excess)
|
||||
cell.charge = min(cell.maxcharge, cell.charge + CELLRATE * draw) //recharge with what we can
|
||||
if((cell.charge/GLOB.CELLRATE + excess) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
|
||||
cell.charge = min(cell.maxcharge, cell.charge + GLOB.CELLRATE * excess) //recharge with what we can
|
||||
add_load(excess) // so draw what we can from the grid
|
||||
charging = 0
|
||||
|
||||
else // not enough power available to run the last tick!
|
||||
charging = 0
|
||||
chargecount = 0
|
||||
@@ -1203,14 +1197,12 @@
|
||||
autoflag = 0
|
||||
|
||||
// now trickle-charge the cell
|
||||
|
||||
if(src.attempt_charging())
|
||||
if(chargemode && charging == 1 && operating)
|
||||
if(excess > 0) // check to make sure we have enough to charge
|
||||
// Max charge is capped to % per second constant
|
||||
var/ch = min(excess*CELLRATE, cell.maxcharge*CHARGELEVEL)
|
||||
|
||||
ch = draw_power(ch/CELLRATE) // Removes the power we're taking from the grid
|
||||
cell.give(ch*CELLRATE) // actually recharge the cell
|
||||
var/ch = min(excess*GLOB.CELLRATE, cell.maxcharge*GLOB.CHARGELEVEL)
|
||||
add_load(ch/GLOB.CELLRATE) // Removes the power we're taking from the grid
|
||||
cell.give(ch) // actually recharge the cell
|
||||
|
||||
else
|
||||
charging = 0 // stop charging
|
||||
@@ -1223,12 +1215,12 @@
|
||||
|
||||
if(chargemode)
|
||||
if(!charging)
|
||||
if(excess > cell.maxcharge*CHARGELEVEL)
|
||||
if(excess > cell.maxcharge*GLOB.CHARGELEVEL)
|
||||
chargecount++
|
||||
else
|
||||
chargecount = 0
|
||||
|
||||
if(chargecount >= 10)
|
||||
if(chargecount == 10)
|
||||
|
||||
chargecount = 0
|
||||
charging = 1
|
||||
@@ -1295,9 +1287,13 @@
|
||||
lighting = 0
|
||||
equipment = 0
|
||||
environ = 0
|
||||
update_icon()
|
||||
update()
|
||||
spawn(600)
|
||||
equipment = 3
|
||||
environ = 3
|
||||
update_icon()
|
||||
update()
|
||||
..()
|
||||
|
||||
/obj/machinery/power/apc/ex_act(severity)
|
||||
|
||||
+140
-112
@@ -59,17 +59,16 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
/obj/structure/cable/white
|
||||
color = COLOR_WHITE
|
||||
|
||||
/obj/structure/cable/New()
|
||||
..()
|
||||
/obj/structure/cable/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
// ensure d1 & d2 reflect the icon_state for entering and exiting cable
|
||||
var/dash = findtext(icon_state, "-")
|
||||
d1 = text2num(copytext(icon_state, 1, dash))
|
||||
d2 = text2num(copytext(icon_state, dash+1 ))
|
||||
d1 = text2num(copytext( icon_state, 1, dash ))
|
||||
d2 = text2num(copytext( icon_state, dash+1 ))
|
||||
|
||||
var/turf/T = loc // hide if turf is not intact
|
||||
|
||||
if(level == 1)
|
||||
var/turf/T = get_turf(src) // hide if turf is not intact
|
||||
if(level == 1)
|
||||
hide(T.intact)
|
||||
LAZYADD(GLOB.cable_list, src) //add it to the global cable list
|
||||
|
||||
@@ -79,14 +78,22 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
LAZYREMOVE(GLOB.cable_list, src) //remove it from global cable list
|
||||
return ..() // then go ahead and delete the cable
|
||||
|
||||
/obj/structure/cable/deconstruct(disassembled = TRUE)
|
||||
var/turf/T = get_turf(src)
|
||||
if(d1) // 0-X cables are 1 unit, X-X cables are 2 units long
|
||||
new/obj/item/stack/cable_coil(T, 2, paramcolor = color)
|
||||
else
|
||||
new/obj/item/stack/cable_coil(T, 1, paramcolor = color)
|
||||
qdel(src)
|
||||
|
||||
///////////////////////////////////
|
||||
// General procedures
|
||||
///////////////////////////////////
|
||||
|
||||
//If underfloor, hide the cable
|
||||
/obj/structure/cable/hide(var/i)
|
||||
/obj/structure/cable/hide(i)
|
||||
|
||||
if(level == 1 && istype(loc, /turf))
|
||||
if(level == 1 && isturf(loc))
|
||||
invisibility = i ? 101 : 0
|
||||
updateicon()
|
||||
|
||||
@@ -97,9 +104,49 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
icon_state = "[d1]-[d2]"
|
||||
|
||||
|
||||
// returns the powernet this cable belongs to
|
||||
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
|
||||
return powernet
|
||||
////////////////////////////////////////////
|
||||
// Power related
|
||||
///////////////////////////////////////////
|
||||
|
||||
// All power generation handled in add_avail()
|
||||
// Machines should use add_load(), surplus(), avail()
|
||||
// Non-machines should use add_delayedload(), delayed_surplus(), newavail()
|
||||
|
||||
/obj/structure/cable/proc/add_avail(amount)
|
||||
if(powernet)
|
||||
powernet.newavail += amount
|
||||
|
||||
/obj/structure/cable/proc/add_load(amount)
|
||||
if(powernet)
|
||||
powernet.load += amount
|
||||
|
||||
/obj/structure/cable/proc/surplus()
|
||||
if(powernet)
|
||||
return Clamp(powernet.avail-powernet.load, 0, powernet.avail)
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/cable/proc/avail()
|
||||
if(powernet)
|
||||
return powernet.avail
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/cable/proc/add_delayedload(amount)
|
||||
if(powernet)
|
||||
powernet.delayedload += amount
|
||||
|
||||
/obj/structure/cable/proc/delayed_surplus()
|
||||
if(powernet)
|
||||
return Clamp(powernet.newavail - powernet.delayedload, 0, powernet.newavail)
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/cable/proc/newavail()
|
||||
if(powernet)
|
||||
return powernet.newavail
|
||||
else
|
||||
return 0
|
||||
|
||||
//Telekinesis has no effect on a cable
|
||||
/obj/structure/cable/attack_tk(mob/user)
|
||||
@@ -116,47 +163,19 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
if(T.intact)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/wirecutters))
|
||||
///// Z-Level Stuff
|
||||
/* if(src.d1 == 12 || src.d2 == 12)
|
||||
to_chat(user, "<span class='warning'>You must cut this cable from above.</span>")
|
||||
return */
|
||||
///// Z-Level Stuff
|
||||
/* if(breaker_box)
|
||||
to_chat(user, "<span class='warning'>This cable is connected to nearby breaker box. Use breaker box to interact with it.</span>")
|
||||
return */
|
||||
|
||||
if(iswirecutter(W))
|
||||
if(shock(user, 50))
|
||||
return
|
||||
|
||||
if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long
|
||||
new/obj/item/stack/cable_coil(T, 2, paramcolor = color)
|
||||
else
|
||||
new/obj/item/stack/cable_coil(T, 1, paramcolor = color)
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span class='warning'>[user] cuts the cable.</span>", 1)
|
||||
|
||||
///// Z-Level Stuff
|
||||
/*if(src.d1 == 11 || src.d2 == 11)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.down)
|
||||
var/turf/below = locate(src.x, src.y, controller.down_target)
|
||||
for(var/obj/structure/cable/c in below)
|
||||
if(c.d1 == 12 || c.d2 == 12)
|
||||
c.qdel()*/
|
||||
///// Z-Level Stuff
|
||||
user.visible_message("[user] cuts the cable.", "<span class='notice'>You cut the cable.</span>")
|
||||
investigate_log("was cut by [key_name(usr, 1)] in [get_area(user)]([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])","wires")
|
||||
|
||||
qdel(src) // qdel
|
||||
deconstruct()
|
||||
return
|
||||
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if(coil.get_amount() < 1)
|
||||
to_chat(user, "Not enough cable")
|
||||
to_chat(user, "<span class='warning'>Not enough cable!</span>")
|
||||
return
|
||||
coil.cable_join(src, user)
|
||||
|
||||
@@ -169,11 +188,9 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
else if(istype(W, /obj/item/multitool))
|
||||
|
||||
if(powernet && (powernet.avail > 0)) // is it powered?
|
||||
to_chat(user, "<span class='warning'>[powernet.avail]W in power network.</span>")
|
||||
|
||||
to_chat(user, "<span class='danger'>Total power: [DisplayPower(powernet.avail)]\nLoad: [DisplayPower(powernet.load)]\nExcess power: [DisplayPower(surplus())]</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The cable is not powered.</span>")
|
||||
|
||||
to_chat(user, "<span class='danger'>The cable is not powered.</span>")
|
||||
shock(user, 5, 0.2)
|
||||
|
||||
else if(istype(W, /obj/item/toy/crayon))
|
||||
@@ -184,7 +201,7 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
if(W.flags & CONDUCT)
|
||||
shock(user, 50, 0.7)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
add_fingerprint(user)
|
||||
|
||||
// shock the user with probability prb
|
||||
/obj/structure/cable/proc/shock(mob/user, prb, siemens_coeff = 1)
|
||||
@@ -196,21 +213,22 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/structure/cable/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct()
|
||||
|
||||
//explosion handling
|
||||
/obj/structure/cable/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
if(1)
|
||||
qdel(src) // qdel
|
||||
if(2.0)
|
||||
if(2)
|
||||
if(prob(50))
|
||||
new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, paramcolor = color)
|
||||
qdel(src) // qdel
|
||||
|
||||
if(3.0)
|
||||
deconstruct()
|
||||
if(3)
|
||||
if(prob(25))
|
||||
new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, paramcolor = color)
|
||||
qdel(src) // qdel
|
||||
return
|
||||
deconstruct()
|
||||
|
||||
obj/structure/cable/proc/cable_color(var/colorC)
|
||||
if(colorC)
|
||||
@@ -231,7 +249,7 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
|
||||
//handles merging diagonally matching cables
|
||||
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
|
||||
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
|
||||
/obj/structure/cable/proc/mergeDiagonalsNetworks(direction)
|
||||
|
||||
//search for and merge diagonally matching cables from the first direction component (north/south)
|
||||
var/turf/T = get_step(src, direction&3)//go north/south
|
||||
@@ -275,7 +293,7 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
|
||||
|
||||
// merge with the powernets of power objects in the given direction
|
||||
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
|
||||
/obj/structure/cable/proc/mergeConnectedNetworks(direction)
|
||||
|
||||
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
|
||||
|
||||
@@ -313,25 +331,27 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
//first let's add turf cables to our powernet
|
||||
//then we'll connect machines on turf with a node cable is present
|
||||
for(var/AM in loc)
|
||||
if(istype(AM,/obj/structure/cable))
|
||||
if(istype(AM, /obj/structure/cable))
|
||||
var/obj/structure/cable/C = AM
|
||||
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
|
||||
if(C.powernet == powernet) continue
|
||||
if(C.powernet == powernet)
|
||||
continue
|
||||
if(C.powernet)
|
||||
merge_powernets(powernet, C.powernet)
|
||||
else
|
||||
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
|
||||
|
||||
else if(istype(AM,/obj/machinery/power/apc))
|
||||
else if(istype(AM, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/N = AM
|
||||
if(!N.terminal) continue // APC are connected through their terminal
|
||||
if(!N.terminal)
|
||||
continue // APC are connected through their terminal
|
||||
|
||||
if(N.terminal.powernet == powernet)
|
||||
continue
|
||||
|
||||
to_connect += N.terminal //we'll connect the machines after all cables are merged
|
||||
|
||||
else if(istype(AM,/obj/machinery/power)) //other power machines
|
||||
else if(istype(AM, /obj/machinery/power)) //other power machines
|
||||
var/obj/machinery/power/M = AM
|
||||
|
||||
if(M.powernet == powernet)
|
||||
@@ -349,23 +369,10 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
//////////////////////////////////////////////
|
||||
|
||||
//if powernetless_only = 1, will only get connections without powernet
|
||||
/obj/structure/cable/proc/get_connections(var/powernetless_only = 0)
|
||||
/obj/structure/cable/proc/get_connections(powernetless_only = 0)
|
||||
. = list() // this will be a list of all connected power objects
|
||||
var/turf/T
|
||||
|
||||
///// Z-Level Stuff
|
||||
/* if(d1 == 11 || d1 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d1 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d1 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1) */
|
||||
///// Z-Level Stuff
|
||||
//get matching cables from the first direction
|
||||
if(d1) //if not a node cable
|
||||
T = get_step(src, d1)
|
||||
@@ -382,20 +389,6 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
|
||||
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
|
||||
|
||||
///// Z-Level Stuff
|
||||
/*if(d2 == 11 || d2 == 12)
|
||||
var/turf/controllerlocation = locate(1, 1, z)
|
||||
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
|
||||
if(controller.up && d2 == 12)
|
||||
T = locate(src.x, src.y, controller.up_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 11, 1)
|
||||
if(controller.down && d2 == 11)
|
||||
T = locate(src.x, src.y, controller.down_target)
|
||||
if(T)
|
||||
. += power_list(T, src, 12, 1)
|
||||
///// Z-Level Stuff
|
||||
else */
|
||||
//do the same on the second direction (which can't be 0)
|
||||
T = get_step(src, d2)
|
||||
if(T)
|
||||
@@ -416,7 +409,8 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
//needed as this can, unlike other placements, disconnect cables
|
||||
/obj/structure/cable/proc/denode()
|
||||
var/turf/T1 = loc
|
||||
if(!T1) return
|
||||
if(!T1)
|
||||
return
|
||||
|
||||
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
|
||||
if(powerlist.len>0)
|
||||
@@ -424,13 +418,19 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
|
||||
|
||||
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
|
||||
qdel(PN) // qdel
|
||||
qdel(PN)
|
||||
|
||||
/obj/structure/cable/proc/auto_propogate_cut_cable(obj/O)
|
||||
if(O && !QDELETED(O))
|
||||
var/datum/powernet/newPN = new()// creates a new powernet...
|
||||
propagate_network(O, newPN)//... and propagates it to the other side of the cable
|
||||
|
||||
// cut the cable's powernet at this cable and updates the powergrid
|
||||
/obj/structure/cable/proc/cut_cable_from_powernet()
|
||||
/obj/structure/cable/proc/cut_cable_from_powernet(remove=TRUE)
|
||||
var/turf/T1 = loc
|
||||
var/list/P_list
|
||||
if(!T1) return
|
||||
if(!T1)
|
||||
return
|
||||
if(d1)
|
||||
T1 = get_step(T1, d1)
|
||||
P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable...
|
||||
@@ -448,11 +448,13 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
|
||||
var/obj/O = P_list[1]
|
||||
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
|
||||
loc = null
|
||||
if(remove)
|
||||
loc = null
|
||||
powernet.remove_cable(src) //remove the cut cable from its powernet
|
||||
|
||||
// queue it to rebuild
|
||||
SSmachines.deferred_powernet_rebuilds += O
|
||||
// addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables
|
||||
|
||||
// Disconnect machines connected to nodes
|
||||
if(d1 == 0) // if we cut a node (O-X) cable
|
||||
@@ -460,6 +462,7 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
|
||||
P.disconnect_from_network() //remove from current network
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// The cable coil object, used for laying cable
|
||||
///////////////////////////////////////////////
|
||||
@@ -468,9 +471,7 @@ obj/structure/cable/proc/cable_color(var/colorC)
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
new /datum/stack_recipe/cable_restraints("cable restraints", /obj/item/restraints/handcuffs/cable, 15),
|
||||
)
|
||||
GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restraints", /obj/item/restraints/handcuffs/cable, 15)))
|
||||
|
||||
/obj/item/stack/cable_coil
|
||||
name = "cable coil"
|
||||
@@ -510,7 +511,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
update_icon()
|
||||
recipes = cable_coil_recipes
|
||||
recipes = GLOB.cable_coil_recipes
|
||||
update_wclass()
|
||||
|
||||
///////////////////////////////////
|
||||
@@ -653,7 +654,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
to_chat(user, "<span class='warning'>You can't lay cable at a place that far away!</span>")
|
||||
return
|
||||
|
||||
var/dirn = null
|
||||
var/dirn
|
||||
if(!dirnew) //If we weren't given a direction, come up with one! (Called as null from catwalk.dm and floor.dm)
|
||||
if(user.loc == T)
|
||||
dirn = user.dir //If laying on the tile we're on, lay in the direction we're facing
|
||||
@@ -690,7 +691,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
if(C.shock(user, 50))
|
||||
if(prob(50)) //fail
|
||||
new /obj/item/stack/cable_coil(get_turf(C), 1, paramcolor = C.color)
|
||||
qdel(C) // qdel
|
||||
C.deconstruct()
|
||||
|
||||
return C
|
||||
|
||||
@@ -707,7 +708,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
return
|
||||
|
||||
if(get_dist(C, user) > 1) // make sure it's close enough
|
||||
to_chat(user, "You can't lay cable at a place that far away.")
|
||||
to_chat(user, "<span class='warning'>You can't lay cable at a place that far away!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -720,13 +721,41 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
// one end of the clicked cable is pointing towards us
|
||||
if(C.d1 == dirn || C.d2 == dirn)
|
||||
if(U.intact) // can't place a cable if the floor is complete
|
||||
to_chat(user, "You can't lay cable there unless the floor tiles are removed.")
|
||||
to_chat(user, "<span class='warning'>You can't lay cable there unless the floor tiles are removed!</span>")
|
||||
return
|
||||
else
|
||||
// cable is pointing at us, we're standing on an open tile
|
||||
// so create a stub pointing at the clicked cable on our tile
|
||||
|
||||
place_turf(U, user, turn(dirn, 180))
|
||||
var/fdirn = turn(dirn, 180) // the opposite direction
|
||||
|
||||
for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already
|
||||
if(LC.d1 == fdirn || LC.d2 == fdirn)
|
||||
to_chat(user, "<span class='warning'>There's already a cable at that position!</span>")
|
||||
return
|
||||
|
||||
var/obj/structure/cable/NC = get_new_cable (U)
|
||||
|
||||
NC.d1 = 0
|
||||
NC.d2 = fdirn
|
||||
NC.add_fingerprint(user)
|
||||
NC.update_icon()
|
||||
|
||||
//create a new powernet with the cable, if needed it will be merged later
|
||||
var/datum/powernet/newPN = new()
|
||||
newPN.add_cable(NC)
|
||||
|
||||
NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets
|
||||
NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
|
||||
|
||||
if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
|
||||
NC.mergeDiagonalsNetworks(NC.d2)
|
||||
|
||||
use(1)
|
||||
|
||||
if(NC.shock(user, 50))
|
||||
if(prob(50)) //fail
|
||||
NC.deconstruct()
|
||||
return
|
||||
|
||||
// exisiting cable doesn't point at our position, so see if it's a stub
|
||||
@@ -745,7 +774,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
if(LC == C) // skip the cable we're interacting with
|
||||
continue
|
||||
if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
|
||||
to_chat(user, "There's already a cable at that position.")
|
||||
to_chat(user, "<span class='warning'>There's already a cable at that position!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -772,8 +801,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
|
||||
if(C.shock(user, 50))
|
||||
if(prob(50)) //fail
|
||||
new/obj/item/stack/cable_coil(get_turf(C), 2, paramcolor = C.color)
|
||||
qdel(C) // qdel
|
||||
C.deconstruct()
|
||||
return
|
||||
|
||||
C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets.
|
||||
@@ -786,8 +814,8 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list(
|
||||
/obj/item/stack/cable_coil/cut
|
||||
item_state = "coil2"
|
||||
|
||||
/obj/item/stack/cable_coil/cut/New(loc)
|
||||
..()
|
||||
/obj/item/stack/cable_coil/cut/Initialize(mapload)
|
||||
. = ..()
|
||||
src.amount = rand(1,2)
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
|
||||
@@ -85,8 +85,8 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
// Generator which spawns with the station.
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/Initialize()
|
||||
..()
|
||||
/obj/machinery/gravity_generator/main/station/Initialize(mapload)
|
||||
. = ..()
|
||||
setup_parts()
|
||||
middle.overlays += "activated"
|
||||
update_list()
|
||||
|
||||
+85
-71
@@ -9,7 +9,7 @@
|
||||
/obj/machinery/power
|
||||
name = null
|
||||
icon = 'icons/obj/power.dmi'
|
||||
anchored = 1.0
|
||||
anchored = TRUE
|
||||
on_blueprints = TRUE
|
||||
var/datum/powernet/powernet = null
|
||||
use_power = NO_POWER_USE
|
||||
@@ -25,18 +25,24 @@
|
||||
//////////////////////////////
|
||||
|
||||
// common helper procs for all power machines
|
||||
/obj/machinery/power/proc/add_avail(var/amount)
|
||||
// All power generation handled in add_avail()
|
||||
// Machines should use add_load(), surplus(), avail()
|
||||
// Non-machines should use add_delayedload(), delayed_surplus(), newavail()
|
||||
|
||||
/obj/machinery/power/proc/add_avail(amount)
|
||||
if(powernet)
|
||||
powernet.newavail += amount
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/power/proc/draw_power(var/amount)
|
||||
/obj/machinery/power/proc/add_load(amount)
|
||||
if(powernet)
|
||||
return powernet.draw_power(amount)
|
||||
return 0
|
||||
powernet.load += amount
|
||||
|
||||
/obj/machinery/power/proc/surplus()
|
||||
if(powernet)
|
||||
return powernet.avail-powernet.load
|
||||
return Clamp(powernet.avail-powernet.load, 0, powernet.avail)
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -46,9 +52,19 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/proc/load()
|
||||
/obj/machinery/power/proc/add_delayedload(amount)
|
||||
if(powernet)
|
||||
return powernet.load
|
||||
powernet.delayedload += amount
|
||||
|
||||
/obj/machinery/power/proc/delayed_surplus()
|
||||
if(powernet)
|
||||
return Clamp(powernet.newavail - powernet.delayedload, 0, powernet.newavail)
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/proc/newavail()
|
||||
if(powernet)
|
||||
return powernet.newavail
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -58,21 +74,20 @@
|
||||
// returns true if the area has power on given channel (or doesn't require power).
|
||||
// defaults to power_channel
|
||||
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
|
||||
|
||||
if(!loc)
|
||||
return 0
|
||||
return FALSE
|
||||
if(!use_power)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/area/A = get_area(src) // make sure it's in an area
|
||||
if(!A)
|
||||
return 0 // if not, then not powered
|
||||
return FALSE // if not, then not powered
|
||||
if(chan == -1)
|
||||
chan = power_channel
|
||||
return A.powered(chan) // return power status of the area
|
||||
|
||||
// increment the power usage stats for an area
|
||||
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
|
||||
/obj/machinery/proc/use_power(amount, chan = -1) // defaults to power_channel
|
||||
var/area/A = get_area(src) // make sure it's in an area
|
||||
if(!A)
|
||||
return
|
||||
@@ -103,43 +118,36 @@
|
||||
/obj/machinery/power/proc/connect_to_network()
|
||||
var/turf/T = src.loc
|
||||
if(!T || !istype(T))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
|
||||
if(!C || !C.powernet)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
C.powernet.add_machine(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// remove and disconnect the machine from its current powernet
|
||||
/obj/machinery/power/proc/disconnect_from_network()
|
||||
if(!powernet)
|
||||
return 0
|
||||
return FALSE
|
||||
powernet.remove_machine(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
// attach a wire to a power machine - leads from the turf you are standing on
|
||||
//almost never called, overwritten by all power machines but terminal and generator
|
||||
/obj/machinery/power/attackby(obj/item/W, mob/user)
|
||||
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
|
||||
/obj/machinery/power/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/coil = I
|
||||
var/turf/T = user.loc
|
||||
|
||||
if(T.intact || !istype(T, /turf/simulated/floor))
|
||||
if(T.intact || !isfloorturf(T))
|
||||
return
|
||||
|
||||
if(get_dist(src, user) > 1)
|
||||
return
|
||||
|
||||
coil.place_turf(T, user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Powernet handling helpers
|
||||
@@ -159,7 +167,8 @@
|
||||
cdir = get_dir(T,loc)
|
||||
|
||||
for(var/obj/structure/cable/C in T)
|
||||
if(C.powernet) continue
|
||||
if(C.powernet)
|
||||
continue
|
||||
if(C.d1 == cdir || C.d2 == cdir)
|
||||
. += C
|
||||
return .
|
||||
@@ -186,7 +195,8 @@
|
||||
/obj/machinery/power/proc/get_indirect_connections()
|
||||
. = list()
|
||||
for(var/obj/structure/cable/C in loc)
|
||||
if(C.powernet) continue
|
||||
if(C.powernet)
|
||||
continue
|
||||
if(C.d1 == 0) // the cable is a node cable
|
||||
. += C
|
||||
return .
|
||||
@@ -199,44 +209,32 @@
|
||||
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
|
||||
// excluding source, that match the direction d
|
||||
// if unmarked==1, only return those with no powernet
|
||||
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
|
||||
/proc/power_list(turf/T, source, d, unmarked=0, cable_only = 0)
|
||||
. = list()
|
||||
var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
|
||||
///// Z-Level Stuff
|
||||
var/Zdir
|
||||
if(d==11)
|
||||
Zdir = 11
|
||||
else if(d==12)
|
||||
Zdir = 12
|
||||
else
|
||||
Zdir = 999
|
||||
///// Z-Level Stuff
|
||||
for(var/AM in T)
|
||||
if(AM == source) continue //we don't want to return source
|
||||
|
||||
if(!cable_only && istype(AM,/obj/machinery/power))
|
||||
for(var/AM in T)
|
||||
if(AM == source)
|
||||
continue //we don't want to return source
|
||||
|
||||
if(!cable_only && istype(AM, /obj/machinery/power))
|
||||
var/obj/machinery/power/P = AM
|
||||
if(P.powernet == 0) continue // exclude APCs which have powernet=0
|
||||
if(P.powernet == 0)
|
||||
continue // exclude APCs which have powernet=0
|
||||
|
||||
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
|
||||
if(d == 0)
|
||||
. += P
|
||||
|
||||
else if(istype(AM,/obj/structure/cable))
|
||||
else if(istype(AM, /obj/structure/cable))
|
||||
var/obj/structure/cable/C = AM
|
||||
|
||||
if(!unmarked || !C.powernet)
|
||||
///// Z-Level Stuff
|
||||
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
|
||||
///// Z-Level Stuff
|
||||
. += C
|
||||
else if(C.d1 == d || C.d2 == d)
|
||||
if(C.d1 == d || C.d2 == d)
|
||||
. += C
|
||||
return .
|
||||
|
||||
//remove the old powernet and replace it with a new one throughout the network.
|
||||
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
|
||||
//log_world("propagating new network")
|
||||
/proc/propagate_network(obj/O, datum/powernet/PN)
|
||||
var/list/worklist = list()
|
||||
var/list/found_machines = list()
|
||||
var/index = 1
|
||||
@@ -248,13 +246,13 @@
|
||||
P = worklist[index] //get the next power object found
|
||||
index++
|
||||
|
||||
if( istype(P,/obj/structure/cable))
|
||||
if(istype(P, /obj/structure/cable))
|
||||
var/obj/structure/cable/C = P
|
||||
if(C.powernet != PN) //add it to the powernet, if it isn't already there
|
||||
PN.add_cable(C)
|
||||
worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
|
||||
|
||||
else if(P.anchored && istype(P,/obj/machinery/power))
|
||||
else if(P.anchored && istype(P, /obj/machinery/power))
|
||||
var/obj/machinery/power/M = P
|
||||
found_machines |= M //we wait until the powernet is fully propagates to connect the machines
|
||||
|
||||
@@ -268,7 +266,7 @@
|
||||
|
||||
|
||||
//Merge two powernets, the bigger (in cable length term) absorbing the other
|
||||
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
|
||||
/proc/merge_powernets(datum/powernet/net1, datum/powernet/net2)
|
||||
if(!net1 || !net2) //if one of the powernet doesn't exist, return
|
||||
return
|
||||
|
||||
@@ -285,8 +283,6 @@
|
||||
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
|
||||
net1.add_cable(Cable)
|
||||
|
||||
if(!net2) return net1
|
||||
|
||||
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
|
||||
if(!Node.connect_to_network())
|
||||
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
|
||||
@@ -299,14 +295,12 @@
|
||||
//source is an object caused electrocuting (airlock, grille, etc)
|
||||
//No animations will be performed by this proc.
|
||||
/proc/electrocute_mob(mob/living/M, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE)
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
if(istype(M.loc,/obj/mecha))
|
||||
if(!M || ismecha(M.loc))
|
||||
return FALSE //feckin mechs are dumb
|
||||
if(dist_check)
|
||||
if(!in_range(source, M))
|
||||
return FALSE
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.gloves)
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
@@ -326,7 +320,7 @@
|
||||
|
||||
if(istype(power_source, /datum/powernet))
|
||||
PN = power_source
|
||||
else if(istype(power_source,/obj/item/stock_parts/cell))
|
||||
else if(istype(power_source, /obj/item/stock_parts/cell))
|
||||
cell = power_source
|
||||
else if(istype(power_source, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/apc = power_source
|
||||
@@ -357,10 +351,30 @@
|
||||
var/drained_energy = drained_hp*20
|
||||
|
||||
if(source_area)
|
||||
source_area.use_power(drained_energy/CELLRATE)
|
||||
else if(istype(power_source,/datum/powernet))
|
||||
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
|
||||
drained_power = PN.draw_power(drained_power)
|
||||
else if(istype(power_source, /obj/item/stock_parts/cell))
|
||||
source_area.use_power(drained_energy/GLOB.CELLRATE)
|
||||
else if(istype(power_source, /datum/powernet))
|
||||
var/drained_power = drained_energy/GLOB.CELLRATE //convert from "joules" to "watts"
|
||||
PN.delayedload += (min(drained_power, max(PN.newavail - PN.delayedload, 0)))
|
||||
else if (istype(power_source, /obj/item/stock_parts/cell))
|
||||
cell.use(drained_energy)
|
||||
return drained_energy
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Misc.
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
// return a knot cable (O-X) if one is present in the turf
|
||||
// null if there's none
|
||||
/turf/proc/get_cable_node()
|
||||
if(!can_have_cabling())
|
||||
return null
|
||||
for(var/obj/structure/cable/C in src)
|
||||
if(C.d1 == 0)
|
||||
return C
|
||||
return null
|
||||
|
||||
/area/proc/get_apc()
|
||||
for(var/obj/machinery/power/apc/APC in GLOB.apcs)
|
||||
if(APC.area == src)
|
||||
return APC
|
||||
@@ -1,19 +1,19 @@
|
||||
////////////////////////////////////////////
|
||||
// POWERNET DATUM
|
||||
// each contiguous network of cables & nodes
|
||||
/////////////////////////////////////
|
||||
/datum/powernet
|
||||
var/number // unique id
|
||||
var/list/cables = list() // all cables & junctions
|
||||
var/list/nodes = list() // all connected machines
|
||||
|
||||
var/load = 0 // the current load on the powernet, increased by each machine at processing
|
||||
var/newavail = 0 // what available power was gathered last tick, then becomes...
|
||||
var/avail = 0 //...the current available power in the powernet
|
||||
var/viewavail = 0 // the available power as it appears on the power console (gradually updated)
|
||||
var/viewload = 0 // the load as it appears on the power console (gradually updated)
|
||||
var/number = 0 // Unused //TODEL
|
||||
|
||||
var/perapc = 0 // per-apc avilability
|
||||
var/perapc_excess = 0
|
||||
var/netexcess = 0 // excess power on the powernet (typically avail-load)
|
||||
|
||||
var/problem = 0 // If either of these is set to 1 there is some sort of issue at the powernet.
|
||||
|
||||
var/netexcess = 0 // excess power on the powernet (typically avail-load)///////
|
||||
var/delayedload = 0 // load applied to powernet between power ticks.
|
||||
|
||||
/datum/powernet/New()
|
||||
SSmachines.powernets += src
|
||||
@@ -31,31 +31,21 @@
|
||||
SSmachines.powernets -= src
|
||||
return ..()
|
||||
|
||||
//Returns the amount of excess power (before refunding to SMESs) from last tick.
|
||||
//This is for machines that might adjust their power consumption using this data.
|
||||
/datum/powernet/proc/last_surplus()
|
||||
return max(avail - load, 0)
|
||||
|
||||
/datum/powernet/proc/draw_power(var/amount)
|
||||
var/draw = between(0, amount, avail - load)
|
||||
load += draw
|
||||
return draw
|
||||
|
||||
/datum/powernet/proc/is_empty()
|
||||
return !cables.len && !nodes.len
|
||||
|
||||
//remove a cable from the current powernet
|
||||
//if the powernet is then empty, delete it
|
||||
//Warning : this proc DON'T check if the cable exists
|
||||
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
|
||||
/datum/powernet/proc/remove_cable(obj/structure/cable/C)
|
||||
cables -= C
|
||||
C.powernet = null
|
||||
if(is_empty())//the powernet is now empty...
|
||||
qdel(src)///... delete it - qdel
|
||||
qdel(src)///... delete it
|
||||
|
||||
//add a cable to the current powernet
|
||||
//Warning : this proc DON'T check if the cable exists
|
||||
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
|
||||
/datum/powernet/proc/add_cable(obj/structure/cable/C)
|
||||
if(C.powernet)// if C already has a powernet...
|
||||
if(C.powernet == src)
|
||||
return
|
||||
@@ -67,16 +57,16 @@
|
||||
//remove a power machine from the current powernet
|
||||
//if the powernet is then empty, delete it
|
||||
//Warning : this proc DON'T check if the machine exists
|
||||
/datum/powernet/proc/remove_machine(var/obj/machinery/power/M)
|
||||
/datum/powernet/proc/remove_machine(obj/machinery/power/M)
|
||||
nodes -=M
|
||||
M.powernet = null
|
||||
if(is_empty())//the powernet is now empty...
|
||||
qdel(src)///... delete it - qdel
|
||||
qdel(src)///... delete it
|
||||
|
||||
|
||||
//add a power machine to the current powernet
|
||||
//Warning : this proc DON'T check if the machine exists
|
||||
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
|
||||
/datum/powernet/proc/add_machine(obj/machinery/power/M)
|
||||
if(M.powernet)// if M already has a powernet...
|
||||
if(M.powernet == src)
|
||||
return
|
||||
@@ -85,45 +75,23 @@
|
||||
M.powernet = src
|
||||
nodes[M] = M
|
||||
|
||||
// Triggers warning for certain amount of ticks
|
||||
/datum/powernet/proc/trigger_warning(var/duration_ticks = 20)
|
||||
problem = max(duration_ticks, problem)
|
||||
|
||||
//handles the power changes in the powernet
|
||||
//called every ticks by the powernet controller
|
||||
/datum/powernet/proc/reset()
|
||||
var/numapc = 0
|
||||
|
||||
if(problem > 0)
|
||||
problem = max(problem - 1, 0)
|
||||
|
||||
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
|
||||
for(var/obj/machinery/power/terminal/term in nodes)
|
||||
if( istype( term.master, /obj/machinery/power/apc ) )
|
||||
numapc++
|
||||
|
||||
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
|
||||
netexcess = avail - load
|
||||
|
||||
if(numapc)
|
||||
//very simple load balancing. If there was a net excess this tick then it must have been that some APCs used less than perapc, since perapc*numapc = avail
|
||||
//Therefore we can raise the amount of power rationed out to APCs on the assumption that those APCs that used less than perapc will continue to do so.
|
||||
//If that assumption fails, then some APCs will miss out on power next tick, however it will be rebalanced for the tick after.
|
||||
if(netexcess >= 0)
|
||||
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
|
||||
else
|
||||
perapc_excess = 0
|
||||
|
||||
perapc = avail/numapc + perapc_excess
|
||||
|
||||
if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle
|
||||
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
|
||||
S.restore() // and restore some of the power that was used
|
||||
|
||||
//updates the viewed load (as seen on power computers)
|
||||
viewload = round(load)
|
||||
// update power consoles
|
||||
viewavail = round(0.8 * viewavail + 0.2 * avail)
|
||||
viewload = round(0.8 * viewload + 0.2 * load)
|
||||
|
||||
//reset the powernet
|
||||
load = 0
|
||||
// reset the powernet
|
||||
load = delayedload
|
||||
delayedload = 0
|
||||
avail = newavail
|
||||
newavail = 0
|
||||
|
||||
@@ -131,27 +99,4 @@
|
||||
if(avail >= 1000)
|
||||
return Clamp(20 + round(avail / 25000), 20, 195) + rand(-5, 5)
|
||||
else
|
||||
return 0
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Misc.
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
// return a knot cable (O-X) if one is present in the turf
|
||||
// null if there's none
|
||||
/turf/proc/get_cable_node()
|
||||
if(!istype(src, /turf/simulated/floor))
|
||||
return null
|
||||
for(var/obj/structure/cable/C in src)
|
||||
if(C.d1 == 0)
|
||||
return C
|
||||
return null
|
||||
|
||||
/area/proc/get_apc()
|
||||
// This was a simple locate() in src, but an unresolved BYOND bug causes trying to locate() in an
|
||||
// area to take an inconceivably long time, especially for large areas.
|
||||
// See: http://www.byond.com/forum/?post=1860571
|
||||
var/obj/machinery/power/apc/FINDME
|
||||
for(FINDME in src)
|
||||
return FINDME
|
||||
return 0
|
||||
@@ -15,8 +15,8 @@ var/global/list/rad_collectors = list()
|
||||
var/locked = 0
|
||||
var/drainratio = 1
|
||||
|
||||
/obj/machinery/power/rad_collector/New()
|
||||
..()
|
||||
/obj/machinery/power/rad_collector/Initialize(mapload)
|
||||
. = ..()
|
||||
rad_collectors += src
|
||||
|
||||
/obj/machinery/power/rad_collector/Destroy()
|
||||
|
||||
@@ -23,18 +23,25 @@
|
||||
|
||||
var/frequency = 0
|
||||
var/id_tag = null
|
||||
var/projectile_type = /obj/item/projectile/beam/emitter
|
||||
var/projectile_sound = 'sound/weapons/emitter.ogg'
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/datum/effect_system/spark_spread/sparks
|
||||
|
||||
/obj/machinery/power/emitter/New()
|
||||
..()
|
||||
/obj/machinery/power/emitter/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/emitter(null)
|
||||
component_parts += new /obj/item/stock_parts/micro_laser(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(null)
|
||||
RefreshParts()
|
||||
if(state == 2 && anchored)
|
||||
connect_to_network()
|
||||
sparks = new
|
||||
sparks.attach(src)
|
||||
sparks.set_up(5, 1, src)
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/power/emitter/RefreshParts()
|
||||
var/max_firedelay = 120
|
||||
@@ -79,13 +86,6 @@
|
||||
return
|
||||
rotate()
|
||||
|
||||
/obj/machinery/power/emitter/Initialize()
|
||||
..()
|
||||
if(state == 2 && anchored)
|
||||
connect_to_network()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/power/emitter/multitool_menu(var/mob/user,var/obj/item/multitool/P)
|
||||
return {"
|
||||
<ul>
|
||||
@@ -182,10 +182,9 @@
|
||||
src.active = 0
|
||||
update_icon()
|
||||
return
|
||||
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
|
||||
|
||||
var/actual_load = draw_power(active_power_usage)
|
||||
if(actual_load >= active_power_usage) //does the laser have enough power to shoot?
|
||||
if(active == TRUE)
|
||||
if(!active_power_usage || surplus() >= active_power_usage)
|
||||
add_load(active_power_usage)
|
||||
if(!powered)
|
||||
powered = 1
|
||||
update_icon()
|
||||
@@ -197,36 +196,57 @@
|
||||
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
|
||||
return
|
||||
|
||||
src.last_shot = world.time
|
||||
if(src.shot_number < 3)
|
||||
src.fire_delay = 2
|
||||
src.shot_number++
|
||||
else
|
||||
src.fire_delay = rand(minimum_fire_delay,maximum_fire_delay)
|
||||
src.shot_number = 0
|
||||
if(!check_delay())
|
||||
return FALSE
|
||||
fire_beam()
|
||||
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter(src.loc)
|
||||
/obj/machinery/power/emitter/proc/check_delay()
|
||||
if((last_shot + fire_delay) <= world.time)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
A.dir = src.dir
|
||||
playsound(get_turf(src), 'sound/weapons/emitter.ogg', 25, 1)
|
||||
if(prob(35))
|
||||
sparks.start()
|
||||
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
A.yo = 20
|
||||
A.xo = 0
|
||||
if(EAST)
|
||||
A.yo = 0
|
||||
A.xo = 20
|
||||
if(WEST)
|
||||
A.yo = 0
|
||||
A.xo = -20
|
||||
else // Any other
|
||||
A.yo = -20
|
||||
A.xo = 0
|
||||
A.fire() //TODO: Carn: check this out
|
||||
/obj/machinery/power/emitter/proc/fire_beam()
|
||||
var/obj/item/projectile/P = new projectile_type(get_turf(src))
|
||||
playsound(get_turf(src), projectile_sound, 50, TRUE)
|
||||
if(prob(35))
|
||||
sparks.start()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
P.yo = 20
|
||||
P.xo = 0
|
||||
if(NORTHEAST)
|
||||
P.yo = 20
|
||||
P.xo = 20
|
||||
if(EAST)
|
||||
P.yo = 0
|
||||
P.xo = 20
|
||||
if(SOUTHEAST)
|
||||
P.yo = -20
|
||||
P.xo = 20
|
||||
if(WEST)
|
||||
P.yo = 0
|
||||
P.xo = -20
|
||||
if(SOUTHWEST)
|
||||
P.yo = -20
|
||||
P.xo = -20
|
||||
if(NORTHWEST)
|
||||
P.yo = 20
|
||||
P.xo = -20
|
||||
else // Any other
|
||||
P.yo = -20
|
||||
P.xo = 0
|
||||
|
||||
last_shot = world.time
|
||||
if(shot_number < 3)
|
||||
fire_delay = 20
|
||||
shot_number ++
|
||||
else
|
||||
fire_delay = rand(minimum_fire_delay, maximum_fire_delay)
|
||||
shot_number = 0
|
||||
P.setDir(dir)
|
||||
P.starting = loc
|
||||
P.fire()
|
||||
return P
|
||||
|
||||
/obj/machinery/power/emitter/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/multitool))
|
||||
|
||||
@@ -48,8 +48,8 @@ field_generator power level display
|
||||
overlays += "+p[power_level]"
|
||||
|
||||
|
||||
/obj/machinery/field/generator/New()
|
||||
..()
|
||||
/obj/machinery/field/generator/Initialize(mapload)
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
name = "Accelerated Particles"
|
||||
desc = "Small things moving very fast."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "particle"//Need a new icon for this
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon_state = "particle"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/movement_range = 10
|
||||
var/energy = 10
|
||||
var/speed = 1
|
||||
|
||||
/obj/effect/accelerated_particle/weak
|
||||
movement_range = 8
|
||||
@@ -21,50 +22,45 @@
|
||||
energy = 50
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/New(loc, dir = 2)
|
||||
src.loc = loc
|
||||
src.dir = dir
|
||||
/obj/effect/accelerated_particle/New(loc)
|
||||
..()
|
||||
|
||||
if(movement_range > 20)
|
||||
movement_range = 20
|
||||
spawn(0)
|
||||
move(1)
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/move), 1)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bump(atom/A)
|
||||
if(A)
|
||||
if(ismob(A))
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/singularity/)))
|
||||
A:energy += energy
|
||||
return
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/singularity))
|
||||
var/obj/singularity/S = A
|
||||
S.energy += energy
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bumped(atom/A)
|
||||
if(ismob(A))
|
||||
Bump(A)
|
||||
return
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/ex_act(severity)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/accelerated_particle/singularity_pull()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M)
|
||||
M.apply_effect((energy*6),IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
return
|
||||
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
|
||||
M.apply_effect((energy * 6), IRRADIATE, 0)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/proc/move(var/lag)
|
||||
/obj/effect/accelerated_particle/proc/move()
|
||||
if(!step(src,dir))
|
||||
src.loc = get_step(src,dir)
|
||||
forceMove(get_step(src, dir))
|
||||
movement_range--
|
||||
if(movement_range <= 0)
|
||||
if(movement_range == 0)
|
||||
qdel(src)
|
||||
else
|
||||
sleep(lag)
|
||||
move(lag)
|
||||
sleep(speed)
|
||||
move()
|
||||
@@ -19,11 +19,11 @@
|
||||
var/parts = null
|
||||
var/datum/wires/particle_acc/control_box/wires = null
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/New()
|
||||
/obj/machinery/particle_accelerator/control_box/Initialize(mapload)
|
||||
. = ..()
|
||||
wires = new(src)
|
||||
connected_parts = list()
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Destroy()
|
||||
if(active)
|
||||
|
||||
@@ -29,21 +29,20 @@
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(var/strength = 0)
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(strength = 0)
|
||||
if((last_shot + fire_delay) <= world.time)
|
||||
last_shot = world.time
|
||||
var/obj/effect/accelerated_particle/A = null
|
||||
var/turf/T = get_step(src, dir)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/effect/accelerated_particle/P
|
||||
switch(strength)
|
||||
if(0)
|
||||
A = new/obj/effect/accelerated_particle/weak(T, dir)
|
||||
P = new/obj/effect/accelerated_particle/weak(T)
|
||||
if(1)
|
||||
A = new/obj/effect/accelerated_particle(T, dir)
|
||||
P = new/obj/effect/accelerated_particle(T)
|
||||
if(2)
|
||||
A = new/obj/effect/accelerated_particle/strong(T, dir)
|
||||
P = new/obj/effect/accelerated_particle/strong(T)
|
||||
if(3)
|
||||
A = new/obj/effect/accelerated_particle/powerful(T, dir)
|
||||
if(A)
|
||||
A.dir = dir
|
||||
return 1
|
||||
return 0
|
||||
P = new/obj/effect/accelerated_particle/powerful(T)
|
||||
P.setDir(dir)
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -3,8 +3,4 @@
|
||||
desc_holder = "This part uses electromagnetic waves to focus the Alpha particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "power_box"
|
||||
reference = "power_box"
|
||||
|
||||
/obj/structure/particle_accelerator/power_box/update_icon()
|
||||
..()
|
||||
return
|
||||
reference = "power_box"
|
||||
+60
-59
@@ -11,20 +11,20 @@
|
||||
name = "power storage unit"
|
||||
desc = "A high-capacity superconducting magnetic energy storage (SMES) unit."
|
||||
icon_state = "smes"
|
||||
density = 1
|
||||
anchored = 1
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/capacity = 5e6 // maximum charge
|
||||
var/charge = 0 // actual charge
|
||||
|
||||
var/input_attempt = 0 // 1 = attempting to charge, 0 = not attempting to charge
|
||||
var/inputting = 0 // 1 = actually inputting, 0 = not inputting
|
||||
var/input_attempt = TRUE // 1 = attempting to charge, 0 = not attempting to charge
|
||||
var/inputting = TRUE // 1 = actually inputting, 0 = not inputting
|
||||
var/input_level = 50000 // amount of power the SMES attempts to charge by
|
||||
var/input_level_max = 200000 // cap on input_level
|
||||
var/input_available = 0 // amount of charge available from input last tick
|
||||
|
||||
var/output_attempt = 1 // 1 = attempting to output, 0 = not attempting to output
|
||||
var/outputting = 1 // 1 = actually outputting, 0 = not outputting
|
||||
var/output_attempt = TRUE // 1 = attempting to output, 0 = not attempting to output
|
||||
var/outputting = TRUE // 1 = actually outputting, 0 = not outputting
|
||||
var/output_level = 50000 // amount of power the SMES attempts to output
|
||||
var/output_level_max = 200000 // cap on output_level
|
||||
var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power
|
||||
@@ -34,13 +34,11 @@
|
||||
var/last_input_attempt = 0
|
||||
var/last_charge = 0
|
||||
|
||||
var/open_hatch = 0
|
||||
var/name_tag = null
|
||||
var/building_terminal = 0 //Suggestions about how to avoid clickspam building several terminals accepted!
|
||||
var/obj/machinery/power/terminal/terminal = null
|
||||
|
||||
/obj/machinery/power/smes/New()
|
||||
..()
|
||||
/obj/machinery/power/smes/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/smes(null)
|
||||
component_parts += new /obj/item/stock_parts/cell/high(null)
|
||||
@@ -52,28 +50,22 @@
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
||||
RefreshParts()
|
||||
|
||||
spawn(5)
|
||||
if(!powernet)
|
||||
connect_to_network()
|
||||
dir_loop:
|
||||
for(var/d in cardinal)
|
||||
var/turf/T = get_step(src, d)
|
||||
for(var/obj/machinery/power/terminal/term in T)
|
||||
if(term && term.dir == turn(d, 180))
|
||||
terminal = term
|
||||
break dir_loop
|
||||
|
||||
dir_loop:
|
||||
for(var/d in cardinal)
|
||||
var/turf/T = get_step(src, d)
|
||||
for(var/obj/machinery/power/terminal/term in T)
|
||||
if(term && term.dir == turn(d, 180))
|
||||
terminal = term
|
||||
break dir_loop
|
||||
if(!terminal)
|
||||
stat |= BROKEN
|
||||
return
|
||||
terminal.master = src
|
||||
if(!terminal.powernet)
|
||||
terminal.connect_to_network()
|
||||
update_icon()
|
||||
return
|
||||
if(!terminal)
|
||||
stat |= BROKEN
|
||||
return
|
||||
terminal.master = src
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/smes/upgraded/New()
|
||||
..()
|
||||
/obj/machinery/power/smes/upgraded/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/smes(null)
|
||||
component_parts += new /obj/item/stock_parts/cell/hyper(null)
|
||||
@@ -222,8 +214,8 @@
|
||||
return round(5.5*charge/(capacity ? capacity : 5e6))
|
||||
|
||||
/obj/machinery/power/smes/process()
|
||||
|
||||
if(stat & BROKEN) return
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
//store machine state to see if we need to update the icon overlays
|
||||
var/last_disp = chargedisplay()
|
||||
@@ -231,33 +223,46 @@
|
||||
var/last_onln = outputting
|
||||
|
||||
//inputting
|
||||
if(input_attempt)
|
||||
var/target_load = min((capacity-charge)/SMESRATE, input_level) // charge at set rate, limited to spare capacity
|
||||
var/actual_load = draw_power(target_load) // add the load to the terminal side network
|
||||
charge += actual_load * SMESRATE // increase the charge
|
||||
if(terminal && input_attempt)
|
||||
input_available = terminal.surplus()
|
||||
|
||||
if(actual_load >= target_load) // Did we charge at full rate?
|
||||
inputting = 2
|
||||
else if(actual_load) // If not, did we charge at least partially?
|
||||
inputting = 1
|
||||
else // Or not at all?
|
||||
inputting = 0
|
||||
if(inputting)
|
||||
if(input_available > 0) // if there's power available, try to charge
|
||||
|
||||
var/load = min(min((capacity-charge)/SMESRATE, input_level), input_available) // charge at set rate, limited to spare capacity
|
||||
|
||||
charge += load * SMESRATE // increase the charge
|
||||
|
||||
terminal.add_load(load) // add the load to the terminal side network
|
||||
|
||||
else // if not enough capcity
|
||||
inputting = FALSE // stop inputting
|
||||
|
||||
else
|
||||
if(input_attempt && input_available > 0)
|
||||
inputting = TRUE
|
||||
else
|
||||
inputting = FALSE
|
||||
|
||||
//outputting
|
||||
if(outputting)
|
||||
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
|
||||
if(output_attempt)
|
||||
if(outputting)
|
||||
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
|
||||
|
||||
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
|
||||
if (add_avail(output_used)) // add output to powernet if it exists (smes side)
|
||||
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
|
||||
else
|
||||
outputting = FALSE
|
||||
|
||||
add_avail(output_used) // add output to powernet (smes side)
|
||||
|
||||
if(output_used < 0.0001) // either from no charge or set to 0
|
||||
outputting = 0
|
||||
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
|
||||
else if(output_attempt && charge > output_level && output_level > 0)
|
||||
outputting = 1
|
||||
if(output_used < 0.0001) // either from no charge or set to 0
|
||||
outputting = FALSE
|
||||
investigate_log("lost power and turned <font color='red'>off</font>", "singulo")
|
||||
else if(output_attempt && charge > output_level && output_level > 0)
|
||||
outputting = TRUE
|
||||
else
|
||||
output_used = 0
|
||||
else
|
||||
output_used = 0
|
||||
outputting = FALSE
|
||||
|
||||
// only update icon if state changed
|
||||
if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting)
|
||||
@@ -333,11 +338,6 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/power/smes/draw_power(var/amount)
|
||||
if(terminal && terminal.powernet)
|
||||
return terminal.powernet.draw_power(amount)
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/smes/attack_ai(mob/user)
|
||||
add_hiddenprint(user)
|
||||
ui_interact(user)
|
||||
@@ -483,7 +483,8 @@
|
||||
output_level = 250000
|
||||
|
||||
/obj/machinery/power/smes/magical/process()
|
||||
charge = 5000000
|
||||
capacity = INFINITY
|
||||
charge = INFINITY
|
||||
..()
|
||||
|
||||
#undef SMESRATE
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
desc = "A solar panel. Generates electricity when in contact with sunlight."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "sp_base"
|
||||
anchored = 1
|
||||
density = 1
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
@@ -20,8 +19,8 @@
|
||||
var/turn_angle = 0
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/solar/New(var/turf/loc, var/obj/item/solar_assembly/S)
|
||||
..(loc)
|
||||
/obj/machinery/power/solar/Initialize(mapload, obj/item/solar_assembly/S)
|
||||
. = ..()
|
||||
Make(S)
|
||||
connect_to_network()
|
||||
|
||||
@@ -118,7 +117,7 @@
|
||||
return
|
||||
|
||||
sunfrac = cos(p_angle) ** 2
|
||||
//isn't the power recieved from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ?
|
||||
//isn't the power received from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ?
|
||||
|
||||
/obj/machinery/power/solar/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY
|
||||
if(stat & BROKEN)
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
//This is a power switch. When turned on it looks at the cables around the tile that it's on and notes which cables are trying to connect to it.
|
||||
//After it knows this it creates the number of cables from the center to each of the cables attempting to conenct. These cables cannot be removed
|
||||
//with wirecutters. When the switch is turned off it removes all the cables on the tile it's on.
|
||||
//The switch uses a 5s delay to prevent powernet change spamming.
|
||||
/*
|
||||
/obj/structure/powerswitch
|
||||
name = "power switch"
|
||||
desc = "A switch that controls power."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "switch-dbl-up"
|
||||
var/icon_state_on = "switch-dbl-down"
|
||||
var/icon_state_off = "switch-dbl-up"
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/on = 0 //up is off, down is on
|
||||
var/busy = 0 //set to 1 when you start pulling
|
||||
|
||||
/obj/structure/powerswitch/simple
|
||||
icon_state = "switch-up"
|
||||
icon_state_on = "switch-down"
|
||||
icon_state_off = "switch-up"
|
||||
|
||||
|
||||
/obj/structure/powerswitch/examine(mob/user)
|
||||
..(user)
|
||||
if(on)
|
||||
to_chat(user, "The switch is in the on position")
|
||||
else
|
||||
to_chat(user, "The switch is in the off position")
|
||||
|
||||
/obj/structure/powerswitch/attack_ai(mob/user)
|
||||
to_chat(user, "<span class='warning'>You're an AI. This is a manual switch. It's not going to work.</span>")
|
||||
return
|
||||
|
||||
/obj/structure/powerswitch/attack_hand(mob/user)
|
||||
|
||||
if(busy)
|
||||
to_chat(user, "<span class='warning'>This switch is already being toggled.</span>")
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
busy = 1
|
||||
for(var/mob/O in viewers(user))
|
||||
O.show_message(text("<span class='warning'>[user] starts pulling the [src].</span>"), 1)
|
||||
|
||||
if(do_after(user, 50, target = src))
|
||||
set_state(!on)
|
||||
for(var/mob/O in viewers(user))
|
||||
O.show_message(text("<span class='warning'>[user] flips the [src] into the [on ? </span>"on": "off"] position."), 1)
|
||||
busy = 0
|
||||
|
||||
/obj/structure/powerswitch/proc/set_state(var/state)
|
||||
on = state
|
||||
if(on)
|
||||
icon_state = icon_state_on
|
||||
var/list/connection_dirs = list()
|
||||
for(var/direction in list(1,2,4,8,5,6,9,10))
|
||||
for(var/obj/structure/cable/C in get_step(src,direction))
|
||||
if(C.d1 == turn(direction, 180) || C.d2 == turn(direction, 180))
|
||||
connection_dirs += direction
|
||||
break
|
||||
|
||||
for(var/direction in connection_dirs)
|
||||
var/obj/structure/cable/C = new/obj/structure/cable(src.loc)
|
||||
C.d1 = 0
|
||||
C.d2 = direction
|
||||
C.icon_state = "[C.d1]-[C.d2]"
|
||||
C.power_switch = src
|
||||
|
||||
var/datum/powernet/PN = new()
|
||||
PN.number = powernets.len + 1
|
||||
powernets += PN
|
||||
C.netnum = PN.number
|
||||
PN.cables += C
|
||||
|
||||
C.mergeConnectedNetworks(C.d2)
|
||||
C.mergeConnectedNetworksOnTurf()
|
||||
|
||||
else
|
||||
icon_state = icon_state_off
|
||||
for(var/obj/structure/cable/C in src.loc)
|
||||
qdel(C)
|
||||
*/
|
||||
@@ -8,25 +8,24 @@
|
||||
icon_state = "term"
|
||||
desc = "It's an underfloor wiring terminal for power equipment."
|
||||
level = 1
|
||||
layer = TURF_LAYER
|
||||
layer = WIRE_TERMINAL_LAYER //a bit above wires
|
||||
var/obj/machinery/power/master = null
|
||||
anchored = 1
|
||||
layer = 2.6 // a bit above wires
|
||||
|
||||
|
||||
/obj/machinery/power/terminal/New()
|
||||
..()
|
||||
var/turf/T = src.loc
|
||||
if(level==1) hide(T.intact)
|
||||
return
|
||||
|
||||
/obj/machinery/power/terminal/Initialize(mapload)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(level == 1)
|
||||
hide(T.intact)
|
||||
|
||||
/obj/machinery/power/terminal/Destroy()
|
||||
if(master)
|
||||
master.disconnect_terminal()
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/power/terminal/hide(var/i)
|
||||
/obj/machinery/power/terminal/hide(i)
|
||||
if(i)
|
||||
invisibility = 101
|
||||
icon_state = "term-f"
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
var/last_zap = 0
|
||||
var/datum/wires/tesla_coil/wires = null
|
||||
|
||||
/obj/machinery/power/tesla_coil/New()
|
||||
..()
|
||||
/obj/machinery/power/tesla_coil/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/tesla_coil(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(null)
|
||||
@@ -77,7 +77,7 @@
|
||||
var/coeff = (20 - ((input_power_multiplier - 1) * 3))
|
||||
coeff = max(coeff, 10)
|
||||
var/power = (powernet.avail/2)
|
||||
draw_power(power)
|
||||
add_load(power)
|
||||
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
|
||||
tesla_zap(src, 10, power/(coeff/2))
|
||||
|
||||
@@ -89,8 +89,8 @@
|
||||
anchored = 0
|
||||
density = 1
|
||||
|
||||
/obj/machinery/power/grounding_rod/New()
|
||||
..()
|
||||
/obj/machinery/power/grounding_rod/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/grounding_rod(null)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(null)
|
||||
|
||||
@@ -8,16 +8,15 @@
|
||||
desc = "A solar directional tracker."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "tracker"
|
||||
anchored = 1
|
||||
density = 1
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/id = 0
|
||||
var/sun_angle = 0 // sun angle as set by sun datum
|
||||
var/obj/machinery/power/solar_control/control = null
|
||||
|
||||
/obj/machinery/power/tracker/New(var/turf/loc, var/obj/item/solar_assembly/S)
|
||||
..(loc)
|
||||
/obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S)
|
||||
. = ..()
|
||||
Make(S)
|
||||
connect_to_network()
|
||||
|
||||
@@ -26,7 +25,7 @@
|
||||
return ..()
|
||||
|
||||
//set the control of the tracker to a given computer if closer than SOLAR_MAX_DIST
|
||||
/obj/machinery/power/tracker/proc/set_control(var/obj/machinery/power/solar_control/SC)
|
||||
/obj/machinery/power/tracker/proc/set_control(obj/machinery/power/solar_control/SC)
|
||||
if(SC && (get_dist(src, SC) > SOLAR_MAX_DIST))
|
||||
return 0
|
||||
control = SC
|
||||
@@ -39,21 +38,21 @@
|
||||
control.connected_tracker = null
|
||||
control = null
|
||||
|
||||
/obj/machinery/power/tracker/proc/Make(var/obj/item/solar_assembly/S)
|
||||
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
|
||||
if(!S)
|
||||
S = new /obj/item/solar_assembly(src)
|
||||
S.glass_type = /obj/item/stack/sheet/glass
|
||||
S.tracker = 1
|
||||
S.anchored = 1
|
||||
S.loc = src
|
||||
S.anchored = TRUE
|
||||
S.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
//updates the tracker icon and the facing angle for the control computer
|
||||
/obj/machinery/power/tracker/proc/set_angle(var/angle)
|
||||
/obj/machinery/power/tracker/proc/set_angle(angle)
|
||||
sun_angle = angle
|
||||
|
||||
//set icon dir to show sun illumination
|
||||
dir = turn(NORTH, -angle - 22.5) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST
|
||||
setDir(turn(NORTH, -angle - 22.5)) // 22.5 deg bias ensures, e.g. 67.5-112.5 is EAST
|
||||
|
||||
if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet
|
||||
control.cdir = angle
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
name = "treadmill"
|
||||
desc = "A power-generating treadmill."
|
||||
layer = 2.2
|
||||
anchored = 1
|
||||
use_power = NO_POWER_USE
|
||||
|
||||
var/speed = 0
|
||||
@@ -18,8 +17,8 @@
|
||||
var/list/mobs_running[0]
|
||||
var/id = null // for linking to monitor
|
||||
|
||||
/obj/machinery/power/treadmill/Initialize()
|
||||
..()
|
||||
/obj/machinery/power/treadmill/Initialize(mapload)
|
||||
. = ..()
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
|
||||
@@ -138,8 +137,8 @@
|
||||
var/frame = 0 // on 0, show labels, on 1 show numbers
|
||||
var/redeem_immediately = 0 // redeem immediately for holding cell
|
||||
|
||||
/obj/machinery/treadmill_monitor/Initialize()
|
||||
..()
|
||||
/obj/machinery/treadmill_monitor/Initialize(mapload)
|
||||
. = ..()
|
||||
if(id)
|
||||
for(var/obj/machinery/power/treadmill/T in GLOB.machines)
|
||||
if(T.id == id)
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
|
||||
// the inlet stage of the gas turbine electricity generator
|
||||
|
||||
/obj/machinery/power/compressor/New()
|
||||
..()
|
||||
/obj/machinery/power/compressor/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/power_compressor(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(null)
|
||||
@@ -80,10 +80,6 @@
|
||||
|
||||
gas_contained = new
|
||||
inturf = get_step(src, dir)
|
||||
|
||||
|
||||
/obj/machinery/power/compressor/Initialize()
|
||||
..()
|
||||
locate_machinery()
|
||||
if(!turbine)
|
||||
stat |= BROKEN
|
||||
@@ -185,8 +181,8 @@
|
||||
#define TURBGENQ 100000
|
||||
#define TURBGENG 0.5
|
||||
|
||||
/obj/machinery/power/turbine/New()
|
||||
..()
|
||||
/obj/machinery/power/turbine/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/power_turbine(src)
|
||||
component_parts += new /obj/item/stock_parts/capacitor(src)
|
||||
@@ -200,10 +196,6 @@
|
||||
// The outlet is pointed at the direction of the turbine component
|
||||
|
||||
outturf = get_step(src, dir)
|
||||
|
||||
|
||||
/obj/machinery/power/turbine/Initialize()
|
||||
..()
|
||||
locate_machinery()
|
||||
if(!compressor)
|
||||
stat |= BROKEN
|
||||
|
||||
@@ -229,6 +229,8 @@
|
||||
if(href_list["ejectBeaker"])
|
||||
if(beaker)
|
||||
beaker.forceMove(loc)
|
||||
if(Adjacent(usr) && !issilicon(usr))
|
||||
usr.put_in_hands(beaker)
|
||||
beaker = null
|
||||
overlays.Cut()
|
||||
|
||||
|
||||
@@ -38,9 +38,11 @@
|
||||
if(state_change)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/obj/machinery/chem_heater/proc/eject_beaker()
|
||||
/obj/machinery/chem_heater/proc/eject_beaker(mob/user)
|
||||
if(beaker)
|
||||
beaker.forceMove(get_turf(src))
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(beaker)
|
||||
beaker = null
|
||||
icon_state = "mixer0b"
|
||||
on = FALSE
|
||||
@@ -118,7 +120,7 @@
|
||||
. = 1
|
||||
|
||||
if(href_list["eject_beaker"])
|
||||
eject_beaker()
|
||||
eject_beaker(usr)
|
||||
. = 0 //updated in eject_beaker() already
|
||||
|
||||
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
|
||||
|
||||
@@ -229,6 +229,8 @@
|
||||
else if(href_list["eject"])
|
||||
if(beaker)
|
||||
beaker.forceMove(get_turf(src))
|
||||
if(Adjacent(usr) && !issilicon(usr))
|
||||
usr.put_in_hands(beaker)
|
||||
beaker = null
|
||||
reagents.clear_reagents()
|
||||
update_icon()
|
||||
|
||||
@@ -447,6 +447,14 @@
|
||||
build_path = /obj/item/healthanalyzer
|
||||
category = list("initial", "Medical")
|
||||
|
||||
/datum/design/pillbottle
|
||||
name = "Pill Bottle"
|
||||
id = "pillbottle"
|
||||
build_type = AUTOLATHE
|
||||
materials = list(MAT_METAL = 80, MAT_GLASS = 20)
|
||||
build_path = /obj/item/storage/pill_bottle
|
||||
category = list("initial", "Medical")
|
||||
|
||||
/datum/design/beanbag_slug
|
||||
name = "Beanbag Slug"
|
||||
id = "beanbag_slug"
|
||||
|
||||
@@ -113,7 +113,15 @@
|
||||
build_type = BIOGENERATOR
|
||||
materials = list(MAT_BIOMASS = 50)
|
||||
build_path = /obj/item/stack/sheet/cloth
|
||||
category = list("initial","Leather and Cloth")
|
||||
category = list("initial", "Organic Materials")
|
||||
|
||||
/datum/design/cardboard
|
||||
name = "Sheet of cardboard"
|
||||
id = "cardboard"
|
||||
build_type = BIOGENERATOR
|
||||
materials = list(MAT_BIOMASS = 25)
|
||||
build_path = /obj/item/stack/sheet/cardboard
|
||||
category = list("initial", "Organic Materials")
|
||||
|
||||
/datum/design/wallet
|
||||
name = "Wallet"
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Grant(M)
|
||||
if(vital)
|
||||
M.update_stat("Vital organ inserted")
|
||||
|
||||
// Removes the given organ from its owner.
|
||||
// Returns the removed object, which is usually just itself
|
||||
|
||||
Reference in New Issue
Block a user