mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-29 19:43:16 +00:00
Merge tgstation13 r4570 into bs12_with_tgport
Conflicts: baystation12.dme code/defines/obj.dm code/defines/procs/helpers.dm code/defines/turf.dm code/game/gamemodes/changeling/modularchangling.dm code/game/gamemodes/cult/cult_structures.dm code/game/gamemodes/events.dm code/game/machinery/telecomms/machine_interactions.dm code/game/master_controller.dm code/game/objects/items/blueprints.dm code/game/objects/items/devices/uplinks.dm code/game/objects/items/item.dm code/game/objects/items/weapons/gift_wrappaper.dm code/game/objects/items/weapons/wires.dm code/game/objects/weapons.dm code/game/turfs/turf.dm code/modules/clothing/head/hardhat.dm code/modules/mining/mine_items.dm code/modules/mining/mine_turfs.dm code/modules/mob/living/silicon/robot/life.dm code/modules/mob/mob_defines.dm code/modules/mob/new_player/login.dm code/modules/paperwork/pen.dm code/modules/paperwork/stamps.dm code/unused/toilets.dm html/changelog.html icons/effects/alert.dmi Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
@@ -1090,6 +1090,17 @@ var/global/BSACooldown = 0
|
||||
else
|
||||
alert("You cannot perform this action. You must be of a higher administrative rank!")
|
||||
return
|
||||
if (href_list["makeanimal"])
|
||||
if(src.level>=3)
|
||||
var/mob/M = locate(href_list["makeanimal"])
|
||||
if(!istype(M, /mob/new_player))
|
||||
usr.client.cmd_admin_animalize(M)
|
||||
else
|
||||
alert("The mob must not be a new_player.")
|
||||
return
|
||||
else
|
||||
alert("You cannot perform this action. You must be of a higher administrative rank!")
|
||||
return
|
||||
/***************** BEFORE**************
|
||||
|
||||
if (href_list["l_players"])
|
||||
@@ -1973,7 +1984,11 @@ var/global/BSACooldown = 0
|
||||
if("comms_blackout")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","CB")
|
||||
communications_blackout()
|
||||
var/answer = alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No")
|
||||
if(answer == "Yes")
|
||||
communications_blackout(0)
|
||||
else
|
||||
communications_blackout(1)
|
||||
message_admins("[key_name_admin(usr)] triggered a communications blackout.", 1)
|
||||
if("spaceninja")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
@@ -2312,6 +2327,12 @@ var/global/BSACooldown = 0
|
||||
body += "<A href='?src=\ref[src];makealien=\ref[M]'>Make Alien</A> | "
|
||||
body += "<A href='?src=\ref[src];makemetroid=\ref[M]'>Make Metroid</A> "
|
||||
|
||||
//Simple Animals
|
||||
if(isanimal(M))
|
||||
body += "<A href='?src=\ref[src];makeanimal=\ref[M]'>Re-Animalize</A> | "
|
||||
else
|
||||
body += "<A href='?src=\ref[src];makeanimal=\ref[M]'>Animalize</A> | "
|
||||
|
||||
body += "<br><br>"
|
||||
body += "<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>"
|
||||
body += "<A href='?src=\ref[src];simplemake=observer;mob=\ref[M]'>Observer</A> | "
|
||||
@@ -2997,7 +3018,7 @@ var/global/BSACooldown = 0
|
||||
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/obj/admins/proc/show_traitor_panel(var/mob/M in mob_list)
|
||||
/obj/admins/proc/show_traitor_panel(var/mob/M in sortmobs())
|
||||
set category = "Admin"
|
||||
set desc = "Edit mobs's memory and role"
|
||||
set name = "Show Traitor Panel"
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
//verbs += /proc/togglebuildmode --Merged with view variables
|
||||
//verbs += /client/proc/cmd_modify_object_variables --Merged with view variables
|
||||
verbs += /client/proc/togglebuildmodeself
|
||||
verbs += /client/proc/debug_master_controller
|
||||
verbs += /client/proc/debug_controller
|
||||
else return
|
||||
|
||||
//Game Admin
|
||||
@@ -244,7 +244,7 @@
|
||||
verbs += /client/proc/make_sound
|
||||
verbs += /client/proc/play_local_sound
|
||||
verbs += /client/proc/send_space_ninja
|
||||
verbs += /client/proc/restartcontroller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri
|
||||
verbs += /client/proc/restart_controller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri
|
||||
verbs += /client/proc/Blobize //I need to remember to move/remove this later
|
||||
verbs += /client/proc/Blobcount //I need to remember to move/remove this later
|
||||
verbs += /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the new clickproc is being tested)
|
||||
@@ -389,7 +389,7 @@
|
||||
verbs -= /client/proc/air_report
|
||||
verbs -= /client/proc/cmd_admin_say
|
||||
verbs -= /client/proc/cmd_admin_gib_self
|
||||
verbs -= /client/proc/restartcontroller
|
||||
verbs -= /client/proc/restart_controller
|
||||
verbs -= /client/proc/play_local_sound
|
||||
verbs -= /client/proc/enable_debug_verbs
|
||||
verbs -= /client/proc/toggleprayers
|
||||
@@ -431,7 +431,7 @@
|
||||
//verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying
|
||||
verbs -= /client/proc/togglebuildmodeself
|
||||
verbs -= /client/proc/kill_airgroup
|
||||
verbs -= /client/proc/debug_master_controller
|
||||
verbs -= /client/proc/debug_controller
|
||||
verbs -= /client/proc/check_ai_laws
|
||||
verbs -= /client/proc/cmd_debug_mob_lists
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/client/proc/Jump(var/area/A in world)
|
||||
/client/proc/Jump(var/area/A in return_sorted_areas())
|
||||
set name = "Jump to Area"
|
||||
set desc = "Area to jump to"
|
||||
set category = "Admin"
|
||||
@@ -30,7 +30,7 @@
|
||||
alert("Admin jumping disabled")
|
||||
return
|
||||
|
||||
/client/proc/jumptomob(var/mob/M in mob_list)
|
||||
/client/proc/jumptomob(var/mob/M in sortmobs())
|
||||
set category = "Admin"
|
||||
set name = "Jump to Mob"
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
var/list/keys = list()
|
||||
for(var/mob/M in player_list)
|
||||
keys += M.client
|
||||
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in keys
|
||||
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
|
||||
if(!selection)
|
||||
return
|
||||
var/mob/M = selection:mob
|
||||
@@ -95,7 +95,7 @@
|
||||
else
|
||||
alert("Admin jumping disabled")
|
||||
|
||||
/client/proc/Getmob(var/mob/M in mob_list)
|
||||
/client/proc/Getmob(var/mob/M in sortmobs())
|
||||
set category = "Admin"
|
||||
set name = "Get Mob"
|
||||
set desc = "Mob to teleport"
|
||||
@@ -123,7 +123,7 @@
|
||||
var/list/keys = list()
|
||||
for(var/mob/M in player_list)
|
||||
keys += M.client
|
||||
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in keys
|
||||
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sortKey(keys)
|
||||
if(!selection)
|
||||
return
|
||||
var/mob/M = selection:mob
|
||||
@@ -138,7 +138,7 @@
|
||||
else
|
||||
alert("Admin jumping disabled")
|
||||
|
||||
/client/proc/sendmob(var/mob/M in mob_list, var/area/A in world)
|
||||
/client/proc/sendmob(var/mob/M in sortmobs(), var/area/A in return_sorted_areas())
|
||||
set category = "Admin"
|
||||
set name = "Send Mob"
|
||||
if(!src.holder)
|
||||
|
||||
@@ -172,6 +172,27 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/client/proc/cmd_admin_animalize(var/mob/M in mob_list)
|
||||
set category = "Fun"
|
||||
set name = "Make Simple Animal"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
|
||||
if(!M)
|
||||
alert("That mob doesn't seem to exist, close the panel and try again.")
|
||||
return
|
||||
|
||||
if(istype(M, /mob/new_player))
|
||||
alert("The mob must not be a new_player.")
|
||||
return
|
||||
|
||||
log_admin("[key_name(src)] has animalized [M.key].")
|
||||
spawn(10)
|
||||
M.Animalize()
|
||||
|
||||
|
||||
/client/proc/makepAI(var/turf/T in mob_list)
|
||||
set category = "Fun"
|
||||
set name = "Make pAI"
|
||||
@@ -644,7 +665,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(M), slot_gloves)
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(M), slot_ears)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/pen(M), slot_l_store)
|
||||
|
||||
var/obj/item/device/pda/heads/pda = new(M)
|
||||
|
||||
@@ -58,7 +58,7 @@ var/intercom_range_display_status = 0
|
||||
del(C)
|
||||
|
||||
if(camera_range_display_status)
|
||||
for(var/obj/machinery/camera/C in Cameras)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
new/obj/effect/debugging/camera_range(C.loc)
|
||||
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -74,7 +74,7 @@ var/intercom_range_display_status = 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
for(var/obj/machinery/camera/C in Cameras)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
CL += C
|
||||
|
||||
var/output = {"<B>CAMERA ANNOMALITIES REPORT</B><HR>
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
if(new_value == null) return
|
||||
|
||||
if(variable=="luminosity")
|
||||
O.sd_SetLuminosity(new_value)
|
||||
O.SetLuminosity(new_value)
|
||||
else
|
||||
O.vars[variable] = new_value
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
for(var/mob/M in mob_list)
|
||||
if ( istype(M , O.type) )
|
||||
if(variable=="luminosity")
|
||||
M.sd_SetLuminosity(new_value)
|
||||
M.SetLuminosity(new_value)
|
||||
else
|
||||
M.vars[variable] = O.vars[variable]
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
for(var/obj/A in world)
|
||||
if ( istype(A , O.type) )
|
||||
if(variable=="luminosity")
|
||||
A.sd_SetLuminosity(new_value)
|
||||
A.SetLuminosity(new_value)
|
||||
else
|
||||
A.vars[variable] = O.vars[variable]
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
for(var/turf/A in world)
|
||||
if ( istype(A , O.type) )
|
||||
if(variable=="luminosity")
|
||||
A.sd_SetLuminosity(new_value)
|
||||
A.SetLuminosity(new_value)
|
||||
else
|
||||
A.vars[variable] = O.vars[variable]
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
for(var/mob/M in mob_list)
|
||||
if (M.type == O.type)
|
||||
if(variable=="luminosity")
|
||||
M.sd_SetLuminosity(new_value)
|
||||
M.SetLuminosity(new_value)
|
||||
else
|
||||
M.vars[variable] = O.vars[variable]
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
for(var/obj/A in world)
|
||||
if (A.type == O.type)
|
||||
if(variable=="luminosity")
|
||||
A.sd_SetLuminosity(new_value)
|
||||
A.SetLuminosity(new_value)
|
||||
else
|
||||
A.vars[variable] = O.vars[variable]
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
for(var/turf/A in world)
|
||||
if (A.type == O.type)
|
||||
if(variable=="luminosity")
|
||||
A.sd_SetLuminosity(new_value)
|
||||
A.SetLuminosity(new_value)
|
||||
else
|
||||
A.vars[variable] = O.vars[variable]
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ var/list/forbidden_varedit_object_types = list(
|
||||
if(variable=="luminosity")
|
||||
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
|
||||
if(var_new == null) return
|
||||
O.sd_SetLuminosity(var_new)
|
||||
O.SetLuminosity(var_new)
|
||||
else if(variable=="stat")
|
||||
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
|
||||
if(var_new == null) return
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/proc/isassembly(O)
|
||||
if(istype(O, /obj/item/device/assembly))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isigniter(O)
|
||||
if(istype(O, /obj/item/device/assembly/igniter))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isinfared(O)
|
||||
if(istype(O, /obj/item/device/assembly/infra))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isprox(O)
|
||||
if(istype(O, /obj/item/device/assembly/prox_sensor))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/issignaler(O)
|
||||
if(istype(O, /obj/item/device/assembly/signaler))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/istimer(O)
|
||||
if(istype(O, /obj/item/device/assembly/timer))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/device/assembly
|
||||
name = "assembly"
|
||||
desc = "A small electronic device that should never exist."
|
||||
@@ -49,9 +15,7 @@
|
||||
origin_tech = "magnets=1"
|
||||
|
||||
var/secured = 1
|
||||
var/small_icon_state_left = null
|
||||
var/small_icon_state_right = null
|
||||
var/list/small_icon_state_overlays = null
|
||||
var/list/attached_overlays = null
|
||||
var/obj/item/device/assembly_holder/holder = null
|
||||
var/cooldown = 0//To prevent spam
|
||||
var/wires = WIRE_RECEIVE | WIRE_PULSE
|
||||
@@ -130,7 +94,7 @@
|
||||
attach_assembly(var/obj/item/device/assembly/A, var/mob/user)
|
||||
holder = new/obj/item/device/assembly_holder(get_turf(src))
|
||||
if(holder.attach(A,src,user))
|
||||
user.show_message("\blue You attach the [A.name] to the [name]!")
|
||||
user << "\blue You attach \the [A] to \the [src]!"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -143,9 +107,9 @@
|
||||
return
|
||||
if(isscrewdriver(W))
|
||||
if(toggle_secure())
|
||||
user.show_message("\blue The [name] is ready!")
|
||||
user << "\blue \The [src] is ready!"
|
||||
else
|
||||
user.show_message("\blue The [name] can now be attached!")
|
||||
user << "\blue \The [src] can now be attached!"
|
||||
return
|
||||
..()
|
||||
return
|
||||
@@ -161,9 +125,9 @@
|
||||
..()
|
||||
if((in_range(src, usr) || loc == usr))
|
||||
if(secured)
|
||||
usr.show_message("The [name] is ready!")
|
||||
usr << "\The [src] is ready!"
|
||||
else
|
||||
usr.show_message("The [name] can be attached!")
|
||||
usr << "\The [src] can be attached!"
|
||||
return
|
||||
|
||||
|
||||
@@ -177,26 +141,6 @@
|
||||
interact(mob/user as mob)
|
||||
return //HTML MENU FOR WIRES GOES HERE
|
||||
|
||||
/*
|
||||
Name: IsAssemblyHolder
|
||||
Desc: If true is an object that can hold an assemblyholder object
|
||||
*/
|
||||
/obj/proc/IsAssemblyHolder()
|
||||
return 0
|
||||
/*
|
||||
proc
|
||||
Process_Activation(var/obj/D, var/normal = 1, var/special = 1)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Name: IsSpecialAssembly
|
||||
Desc: If true is an object that can be attached to an assembly holder but is a special thing like a plasma can or door
|
||||
*/
|
||||
|
||||
/obj/proc/IsSpecialAssembly()
|
||||
return 0
|
||||
/*
|
||||
var/small_icon_state = null//If this obj will go inside the assembly use this for icons
|
||||
var/list/small_icon_state_overlays = null//Same here
|
||||
|
||||
44
code/modules/assembly/helpers.dm
Normal file
44
code/modules/assembly/helpers.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
/proc/isassembly(O)
|
||||
if(istype(O, /obj/item/device/assembly))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isigniter(O)
|
||||
if(istype(O, /obj/item/device/assembly/igniter))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isinfared(O)
|
||||
if(istype(O, /obj/item/device/assembly/infra))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isprox(O)
|
||||
if(istype(O, /obj/item/device/assembly/prox_sensor))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/issignaler(O)
|
||||
if(istype(O, /obj/item/device/assembly/signaler))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/istimer(O)
|
||||
if(istype(O, /obj/item/device/assembly/timer))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/*
|
||||
Name: IsSpecialAssembly
|
||||
Desc: If true is an object that can be attached to an assembly holder but is a special thing like a plasma can or door
|
||||
*/
|
||||
|
||||
/obj/proc/IsSpecialAssembly()
|
||||
return 0
|
||||
|
||||
/*
|
||||
Name: IsAssemblyHolder
|
||||
Desc: If true is an object that can hold an assemblyholder object
|
||||
*/
|
||||
/obj/proc/IsAssemblyHolder()
|
||||
return 0
|
||||
@@ -1,6 +1,5 @@
|
||||
/obj/item/device/assembly_holder
|
||||
name = "Assembly"
|
||||
desc = "Holds various devices"//Fix this by adding dynamic desc
|
||||
icon = 'icons/obj/assemblies/new_assemblies.dmi'
|
||||
icon_state = "holder"
|
||||
item_state = "assembly"
|
||||
@@ -44,7 +43,7 @@
|
||||
D2.loc = src
|
||||
a_left = D
|
||||
a_right = D2
|
||||
src.name = "[D.name] [D2.name] assembly"
|
||||
name = "[D.name]-[D2.name] assembly"
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
@@ -52,8 +51,8 @@
|
||||
attach_special(var/obj/O, var/mob/user)
|
||||
if(!O) return
|
||||
if(!O.IsSpecialAssembly()) return 0
|
||||
/*
|
||||
if(O:Attach_Holder())
|
||||
|
||||
/* if(O:Attach_Holder())
|
||||
special_assembly = O
|
||||
update_icon()
|
||||
src.name = "[a_left.name] [a_right.name] [special_assembly.name] assembly"
|
||||
@@ -62,15 +61,16 @@
|
||||
|
||||
|
||||
update_icon()
|
||||
src.overlays = null
|
||||
overlays = null
|
||||
if(a_left)
|
||||
src.overlays += a_left:small_icon_state_left
|
||||
for(var/O in a_left:small_icon_state_overlays)
|
||||
src.overlays += text("[]_l", O)
|
||||
overlays += "[initial(a_left.icon_state)]_left" //the initial() is probably unnecessary, but you just know
|
||||
for(var/O in a_left.attached_overlays) //someone is gonna fuck around with the icon_state in the future
|
||||
overlays += "[O]_l"
|
||||
if(a_right)
|
||||
src.overlays += a_right:small_icon_state_right
|
||||
for(var/O in a_right:small_icon_state_overlays)
|
||||
src.overlays += text("[]_r", O)
|
||||
src.overlays += "[initial(a_right.icon_state)]_right"
|
||||
for(var/O in a_right.attached_overlays)
|
||||
overlays += "[O]_r"
|
||||
|
||||
/* if(special_assembly)
|
||||
special_assembly.update_icon()
|
||||
if(special_assembly:small_icon_state)
|
||||
@@ -84,9 +84,9 @@
|
||||
..()
|
||||
if ((in_range(src, usr) || src.loc == usr))
|
||||
if (src.secured)
|
||||
usr.show_message("The [src.name] is ready!")
|
||||
usr << "\The [src] is ready!"
|
||||
else
|
||||
usr.show_message("The [src.name] can be attached!")
|
||||
usr << "\The [src] can be attached!"
|
||||
return
|
||||
|
||||
|
||||
@@ -123,15 +123,15 @@
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(isscrewdriver(W))
|
||||
if(!a_left || !a_right)
|
||||
user.show_message("\red BUG:Assembly part missing, please report this!")
|
||||
user << "\red BUG:Assembly part missing, please report this!"
|
||||
return
|
||||
a_left.toggle_secure()
|
||||
a_right.toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
user.show_message("\blue The [src.name] is ready!")
|
||||
user << "\blue \The [src] is ready!"
|
||||
else
|
||||
user.show_message("\blue The [src.name] can now be taken apart!")
|
||||
user << "\blue \The [src] can now be taken apart!"
|
||||
update_icon()
|
||||
return
|
||||
else if(W.IsSpecialAssembly())
|
||||
@@ -145,7 +145,7 @@
|
||||
src.add_fingerprint(user)
|
||||
if(src.secured)
|
||||
if(!a_left || !a_right)
|
||||
user.show_message("\red Assembly part missing!")
|
||||
user << "\red Assembly part missing!"
|
||||
return
|
||||
if(istype(a_left,a_right.type))//If they are the same type it causes issues due to window code
|
||||
switch(alert("Which side would you like to use?",,"Left","Right"))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/device/assembly/igniter
|
||||
name = "igniter"
|
||||
desc = "A small electronic device able to ignite combustable substances. Does not function well as a lighter."
|
||||
desc = "A small electronic device able to ignite combustable substances."
|
||||
icon_state = "igniter"
|
||||
m_amt = 500
|
||||
g_amt = 50
|
||||
@@ -8,8 +8,6 @@
|
||||
origin_tech = "magnets=1"
|
||||
|
||||
secured = 1
|
||||
small_icon_state_left = "igniter_left"
|
||||
small_icon_state_right = "igniter_right"
|
||||
|
||||
|
||||
activate()
|
||||
@@ -20,8 +18,6 @@
|
||||
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
activate()
|
||||
add_fingerprint(user)
|
||||
spawn( 5 )
|
||||
activate()
|
||||
return
|
||||
return
|
||||
return
|
||||
@@ -1,19 +1,17 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/device/assembly/infra
|
||||
name = "Infrared Beam"
|
||||
name = "infrared emitter"
|
||||
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
|
||||
icon_state = "infrared_old"
|
||||
icon_state = "infrared"
|
||||
m_amt = 1000
|
||||
g_amt = 500
|
||||
w_amt = 100
|
||||
origin_tech = "magnets=2"
|
||||
|
||||
secured = 0
|
||||
small_icon_state_left = "infrared_left"
|
||||
small_icon_state_right = "infrared_right"
|
||||
|
||||
var/scanning = 0
|
||||
var/on = 0
|
||||
var/visible = 0
|
||||
var/obj/effect/beam/i_beam/first = null
|
||||
|
||||
@@ -23,7 +21,7 @@
|
||||
|
||||
activate()
|
||||
if(!..()) return 0//Cooldown check
|
||||
src.scanning = !src.scanning
|
||||
on = !on
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
@@ -33,19 +31,19 @@
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
else
|
||||
scanning = 0
|
||||
if(src.first) del(src.first)
|
||||
on = 0
|
||||
if(first) del(first)
|
||||
processing_objects.Remove(src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
update_icon()
|
||||
src.overlays = null
|
||||
src.small_icon_state_overlays = list()
|
||||
if(scanning)
|
||||
src.overlays += text("infrared_old2")
|
||||
src.small_icon_state_overlays += text("infrared_on")
|
||||
overlays = null
|
||||
attached_overlays = list()
|
||||
if(on)
|
||||
overlays += "infrared_on"
|
||||
attached_overlays += "infrared_on"
|
||||
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
@@ -53,23 +51,23 @@
|
||||
|
||||
|
||||
process()//Old code
|
||||
if(!scanning)
|
||||
if(src.first)
|
||||
del(src.first)
|
||||
if(!on)
|
||||
if(first)
|
||||
del(first)
|
||||
return
|
||||
|
||||
if((!( src.first ) && (src.secured && (istype(src.loc, /turf) || (src.holder && istype(src.holder.loc, /turf))))))
|
||||
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam( (src.holder ? src.holder.loc : src.loc) )
|
||||
if((!(first) && (secured && (istype(loc, /turf) || (holder && istype(holder.loc, /turf))))))
|
||||
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam((holder ? holder.loc : loc) )
|
||||
I.master = src
|
||||
I.density = 1
|
||||
I.dir = src.dir
|
||||
I.dir = dir
|
||||
step(I, I.dir)
|
||||
if (I)
|
||||
if(I)
|
||||
I.density = 0
|
||||
src.first = I
|
||||
I.vis_spread(src.visible)
|
||||
spawn( 0 )
|
||||
if (I)
|
||||
first = I
|
||||
I.vis_spread(visible)
|
||||
spawn(0)
|
||||
if(I)
|
||||
//world << "infra: setting limit"
|
||||
I.limit = 8
|
||||
//world << "infra: processing beam \ref[I]"
|
||||
@@ -79,31 +77,30 @@
|
||||
|
||||
|
||||
attack_hand()
|
||||
del(src.first)
|
||||
del(first)
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
Move()
|
||||
var/t = src.dir
|
||||
var/t = dir
|
||||
..()
|
||||
src.dir = t
|
||||
del(src.first)
|
||||
dir = t
|
||||
del(first)
|
||||
return
|
||||
|
||||
|
||||
holder_movement()
|
||||
if(!holder) return 0
|
||||
// src.dir = holder.dir
|
||||
del(src.first)
|
||||
// dir = holder.dir
|
||||
del(first)
|
||||
return 1
|
||||
|
||||
|
||||
trigger_beam()
|
||||
if((!secured)||(!scanning)||(cooldown > 0)) return 0
|
||||
if((!secured)||(!on)||(cooldown > 0)) return 0
|
||||
pulse(0)
|
||||
for(var/mob/O in hearers(null, null))
|
||||
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
|
||||
visible_message("\icon[src] *beep* *beep*")
|
||||
cooldown = 2
|
||||
spawn(10)
|
||||
process_cooldown()
|
||||
@@ -113,7 +110,7 @@
|
||||
interact(mob/user as mob)//TODO: change this this to the wire control panel
|
||||
if(!secured) return
|
||||
user.machine = src
|
||||
var/dat = text("<TT><B>Infrared Laser</B>\n<B>Status</B>: []<BR>\n<B>Visibility</B>: []<BR>\n</TT>", (src.scanning ? text("<A href='?src=\ref[];state=0'>On</A>", src) : text("<A href='?src=\ref[];state=1'>Off</A>", src)), (src.visible ? text("<A href='?src=\ref[];visible=0'>Visible</A>", src) : text("<A href='?src=\ref[];visible=1'>Invisible</A>", src)))
|
||||
var/dat = text("<TT><B>Infrared Laser</B>\n<B>Status</B>: []<BR>\n<B>Visibility</B>: []<BR>\n</TT>", (on ? text("<A href='?src=\ref[];state=0'>On</A>", src) : text("<A href='?src=\ref[];state=1'>Off</A>", src)), (src.visible ? text("<A href='?src=\ref[];visible=0'>Visible</A>", src) : text("<A href='?src=\ref[];visible=1'>Invisible</A>", src)))
|
||||
dat += "<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
user << browse(dat, "window=infra")
|
||||
@@ -128,22 +125,22 @@
|
||||
onclose(usr, "infra")
|
||||
return
|
||||
|
||||
if (href_list["state"])
|
||||
src.scanning = !(src.scanning)
|
||||
if(href_list["state"])
|
||||
on = !(on)
|
||||
update_icon()
|
||||
|
||||
if (href_list["visible"])
|
||||
src.visible = !(src.visible)
|
||||
spawn( 0 )
|
||||
if(src.first)
|
||||
src.first.vis_spread(src.visible)
|
||||
if(href_list["visible"])
|
||||
visible = !(visible)
|
||||
spawn(0)
|
||||
if(first)
|
||||
first.vis_spread(visible)
|
||||
|
||||
if (href_list["close"])
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=infra")
|
||||
return
|
||||
|
||||
if(usr)
|
||||
src.attack_self(usr)
|
||||
attack_self(usr)
|
||||
|
||||
return
|
||||
|
||||
@@ -153,7 +150,7 @@
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
src.dir = turn(src.dir, 90)
|
||||
dir = turn(dir, 90)
|
||||
return
|
||||
|
||||
|
||||
@@ -175,63 +172,62 @@
|
||||
|
||||
/obj/effect/beam/i_beam/proc/hit()
|
||||
//world << "beam \ref[src]: hit"
|
||||
if(src.master)
|
||||
if(master)
|
||||
//world << "beam hit \ref[src]: calling master \ref[master].hit"
|
||||
src.master.trigger_beam()
|
||||
master.trigger_beam()
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/effect/beam/i_beam/proc/vis_spread(v)
|
||||
//world << "i_beam \ref[src] : vis_spread"
|
||||
src.visible = v
|
||||
visible = v
|
||||
spawn(0)
|
||||
if(src.next)
|
||||
if(next)
|
||||
//world << "i_beam \ref[src] : is next [next.type] \ref[next], calling spread"
|
||||
src.next.vis_spread(v)
|
||||
next.vis_spread(v)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/beam/i_beam/process()
|
||||
//world << "i_beam \ref[src] : process"
|
||||
|
||||
if((src.loc.density || !( src.master )))
|
||||
//SN src = null
|
||||
if((loc.density || !(master)))
|
||||
// world << "beam hit loc [loc] or no master [master], deleting"
|
||||
del(src)
|
||||
return
|
||||
//world << "proccess: [src.left] left"
|
||||
|
||||
if(src.left > 0)
|
||||
src.left--
|
||||
if(src.left < 1)
|
||||
if(!( src.visible ))
|
||||
src.invisibility = 101
|
||||
if(left > 0)
|
||||
left--
|
||||
if(left < 1)
|
||||
if(!(visible))
|
||||
invisibility = 101
|
||||
else
|
||||
src.invisibility = 0
|
||||
invisibility = 0
|
||||
else
|
||||
src.invisibility = 0
|
||||
invisibility = 0
|
||||
|
||||
|
||||
//world << "now [src.left] left"
|
||||
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam( src.loc )
|
||||
I.master = src.master
|
||||
var/obj/effect/beam/i_beam/I = new /obj/effect/beam/i_beam(loc)
|
||||
I.master = master
|
||||
I.density = 1
|
||||
I.dir = src.dir
|
||||
I.dir = dir
|
||||
//world << "created new beam \ref[I] at [I.x] [I.y] [I.z]"
|
||||
step(I, I.dir)
|
||||
|
||||
if(I)
|
||||
//world << "step worked, now at [I.x] [I.y] [I.z]"
|
||||
if (!( src.next ))
|
||||
//world << "no src.next"
|
||||
if(!(next))
|
||||
//world << "no next"
|
||||
I.density = 0
|
||||
//world << "spreading"
|
||||
I.vis_spread(src.visible)
|
||||
src.next = I
|
||||
spawn( 0 )
|
||||
//world << "limit = [src.limit] "
|
||||
if ((I && src.limit > 0))
|
||||
I.limit = src.limit - 1
|
||||
I.vis_spread(visible)
|
||||
next = I
|
||||
spawn(0)
|
||||
//world << "limit = [limit] "
|
||||
if((I && limit > 0))
|
||||
I.limit = limit - 1
|
||||
//world << "calling next process"
|
||||
I.process()
|
||||
return
|
||||
@@ -239,10 +235,10 @@
|
||||
//world << "is a next: \ref[next], deleting beam \ref[I]"
|
||||
del(I)
|
||||
else
|
||||
//world << "step failed, deleting \ref[src.next]"
|
||||
del(src.next)
|
||||
//world << "step failed, deleting \ref[next]"
|
||||
del(next)
|
||||
spawn(10)
|
||||
src.process()
|
||||
process()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -251,18 +247,18 @@
|
||||
return
|
||||
|
||||
/obj/effect/beam/i_beam/Bumped()
|
||||
src.hit()
|
||||
hit()
|
||||
return
|
||||
|
||||
/obj/effect/beam/i_beam/HasEntered(atom/movable/AM as mob|obj)
|
||||
if(istype(AM, /obj/effect/beam))
|
||||
return
|
||||
spawn( 0 )
|
||||
src.hit()
|
||||
spawn(0)
|
||||
hit()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/beam/i_beam/Del()
|
||||
del(src.next)
|
||||
del(next)
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/device/assembly/prox_sensor
|
||||
name = "proximity sensor"
|
||||
desc = "Used for scanning and alerting when someone enters a certain proximity."
|
||||
@@ -10,8 +8,6 @@
|
||||
origin_tech = "magnets=1"
|
||||
|
||||
secured = 0
|
||||
small_icon_state_left = "prox_left"
|
||||
small_icon_state_right = "prox_right"
|
||||
|
||||
var/scanning = 0
|
||||
var/timing = 0
|
||||
@@ -50,8 +46,7 @@
|
||||
sense()
|
||||
if((!secured)||(!scanning)||(cooldown > 0)) return 0
|
||||
pulse(0)
|
||||
for(var/mob/O in hearers(null, null))
|
||||
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
|
||||
visible_message("\icon[src] *beep* *beep*", "*beep* *beep*")
|
||||
cooldown = 2
|
||||
spawn(10)
|
||||
process_cooldown()
|
||||
@@ -84,13 +79,13 @@
|
||||
|
||||
update_icon()
|
||||
overlays = null
|
||||
small_icon_state_overlays = list()
|
||||
attached_overlays = list()
|
||||
if(timing)
|
||||
overlays += text("prox_timing")
|
||||
small_icon_state_overlays += text("prox_timing")
|
||||
overlays += "prox_timing"
|
||||
attached_overlays += "prox_timing"
|
||||
if(scanning)
|
||||
overlays += text("prox_scanning")
|
||||
small_icon_state_overlays += text("prox_scanning")
|
||||
overlays += "prox_scanning"
|
||||
attached_overlays += "prox_scanning"
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
return
|
||||
|
||||
56
code/modules/assembly/shock_kit.dm
Normal file
56
code/modules/assembly/shock_kit.dm
Normal file
@@ -0,0 +1,56 @@
|
||||
/obj/item/assembly/shock_kit
|
||||
name = "Shock Kit"
|
||||
desc = "This appears to be made from both an Electric Pack and a Helmet."
|
||||
icon_state = "shock_kit"
|
||||
var/obj/item/clothing/head/helmet/part1 = null
|
||||
var/obj/item/device/radio/electropack/part2 = null
|
||||
var/status = 0.0
|
||||
w_class = 5.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/shock_kit/Del()
|
||||
//src.part1 = null
|
||||
del(src.part1)
|
||||
//src.part2 = null
|
||||
del(src.part2)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if ((istype(W, /obj/item/weapon/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
src.part1.loc = T
|
||||
src.part2.loc = T
|
||||
src.part1.master = null
|
||||
src.part2.master = null
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
del(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/weapon/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (!src.status)
|
||||
user.show_message("\blue The shock pack is now secured!", 1)
|
||||
else
|
||||
user.show_message("\blue The shock pack is now unsecured!", 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/attack_self(mob/user as mob)
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.part2.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/receive_signal()
|
||||
//*****
|
||||
//world << "Shock kit got r_signal"
|
||||
if (istype(src.loc, /obj/structure/stool/bed/chair/e_chair))
|
||||
var/obj/structure/stool/bed/chair/e_chair/C = src.loc
|
||||
//world << "Shock kit sending shock to EC"
|
||||
C.shock()
|
||||
return
|
||||
@@ -1,7 +1,5 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/device/assembly/signaler
|
||||
name = "Remote Signaling Device"
|
||||
name = "remote signaling device"
|
||||
desc = "Used to remotely activate devices."
|
||||
icon_state = "signaller"
|
||||
item_state = "signaler"
|
||||
@@ -12,8 +10,6 @@
|
||||
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
|
||||
|
||||
secured = 1
|
||||
small_icon_state_left = "signaller_left"
|
||||
small_icon_state_right = "signaller_right"
|
||||
|
||||
var/code = 30
|
||||
var/frequency = 1457
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/device/assembly/timer
|
||||
name = "timer"
|
||||
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
|
||||
@@ -10,8 +8,6 @@
|
||||
origin_tech = "magnets=1"
|
||||
|
||||
secured = 0
|
||||
small_icon_state_left = "timer_left"
|
||||
small_icon_state_right = "timer_right"
|
||||
|
||||
var/timing = 0
|
||||
var/time = 10
|
||||
@@ -61,10 +57,10 @@
|
||||
|
||||
update_icon()
|
||||
overlays = null
|
||||
small_icon_state_overlays = list()
|
||||
attached_overlays = list()
|
||||
if(timing)
|
||||
overlays += text("timer_timing")
|
||||
small_icon_state_overlays += text("timer_timing")
|
||||
overlays += "timer_timing"
|
||||
attached_overlays += "timer_timing"
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
return
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja gloves"
|
||||
icon_state = "s-ninja"
|
||||
item_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
var/draining = 0
|
||||
var/candrain = 0
|
||||
var/mindrain = 200
|
||||
var/maxdrain = 400
|
||||
|
||||
/obj/item/clothing/gloves/captain
|
||||
desc = "Regal blue gloves, with a nice gold trim. Swanky."
|
||||
|
||||
54
code/modules/clothing/gloves/stungloves.dm
Normal file
54
code/modules/clothing/gloves/stungloves.dm
Normal file
@@ -0,0 +1,54 @@
|
||||
/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(src, /obj/item/clothing/gloves/boxing)) //quick fix for stunglove overlay not working nicely with boxing gloves.
|
||||
user << "<span class='notice'>That won't work.</span>" //i'm not putting my lips on that!
|
||||
..()
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/cable_coil))
|
||||
var/obj/item/weapon/cable_coil/C = W
|
||||
if(!wired)
|
||||
if(C.amount >= 2)
|
||||
C.amount -= 2
|
||||
wired = 1
|
||||
siemens_coefficient = 1
|
||||
user << "<span class='notice'>You wrap some wires around [src].</span>"
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='notice'>There is not enough wire to cover [src].</span>"
|
||||
else
|
||||
user << "<span class='notice'>[src] are already wired.</span>"
|
||||
|
||||
else if(istype(W, /obj/item/weapon/cell))
|
||||
if(!wired)
|
||||
user << "<span class='notice'>[src] need to be wired first.</span>"
|
||||
else if(!cell)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
cell = W
|
||||
user << "<span class='notice'>You attach a cell to [src].</span>"
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='notice'>[src] already have a cell.</span>"
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wirecutters))
|
||||
if(cell)
|
||||
cell.updateicon()
|
||||
cell.loc = get_turf(src.loc)
|
||||
cell = null
|
||||
user << "<span class='notice'>You cut the cell away from [src].</span>"
|
||||
update_icon()
|
||||
return
|
||||
if(wired) //wires disappear into the void because fuck that shit
|
||||
wired = 0
|
||||
siemens_coefficient = initial(siemens_coefficient)
|
||||
user << "<span class='notice'>You cut the wires away from [src].</span>"
|
||||
update_icon()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/update_icon()
|
||||
..()
|
||||
overlays = null
|
||||
if(wired)
|
||||
overlays += "gloves_wire"
|
||||
if(cell)
|
||||
overlays += "gloves_cell"
|
||||
@@ -19,22 +19,20 @@
|
||||
icon_state = "hardhat[on]_[color]"
|
||||
item_state = "hardhat[on]_[color]"
|
||||
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
else
|
||||
user.total_luminosity -= brightness_on
|
||||
if(on) user.SetLuminosity(user.luminosity + brightness_on)
|
||||
else user.SetLuminosity(user.luminosity - brightness_on)
|
||||
|
||||
pickup(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(0)
|
||||
user.SetLuminosity(user.luminosity + brightness_on)
|
||||
// user.UpdateLuminosity() //TODO: Carn
|
||||
SetLuminosity(0)
|
||||
|
||||
dropped(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity -= brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(brightness_on)
|
||||
user.SetLuminosity(user.luminosity - brightness_on)
|
||||
// user.UpdateLuminosity()
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
|
||||
/obj/item/clothing/head/hardhat/orange
|
||||
|
||||
@@ -133,22 +133,20 @@
|
||||
icon_state = "hardhat[on]_[color]"
|
||||
item_state = "hardhat[on]_[color]"
|
||||
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
else
|
||||
user.total_luminosity -= brightness_on
|
||||
if(on) user.SetLuminosity(user.luminosity + brightness_on)
|
||||
else user.SetLuminosity(user.luminosity - brightness_on)
|
||||
|
||||
pickup(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(0)
|
||||
user.SetLuminosity(user.luminosity + brightness_on)
|
||||
// user.UpdateLuminosity()
|
||||
SetLuminosity(0)
|
||||
|
||||
dropped(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity -= brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(brightness_on)
|
||||
user.SetLuminosity(user.luminosity - brightness_on)
|
||||
// user.UpdateLuminosity()
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
/*
|
||||
* Kitty ears
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja gloves"
|
||||
icon_state = "s-ninja"
|
||||
item_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
var/draining = 0
|
||||
var/candrain = 0
|
||||
var/mindrain = 200
|
||||
var/maxdrain = 400
|
||||
|
||||
/obj/item/clothing/head/helmet/space/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja hood"
|
||||
|
||||
@@ -19,22 +19,20 @@
|
||||
icon_state = "rig[on]-[color]"
|
||||
// item_state = "rig[on]-[color]"
|
||||
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
else
|
||||
user.total_luminosity -= brightness_on
|
||||
if(on) user.SetLuminosity(user.luminosity + brightness_on)
|
||||
else user.SetLuminosity(user.luminosity - brightness_on)
|
||||
|
||||
pickup(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity += brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(0)
|
||||
user.SetLuminosity(user.luminosity + brightness_on)
|
||||
// user.UpdateLuminosity()
|
||||
SetLuminosity(0)
|
||||
|
||||
dropped(mob/user)
|
||||
if(on)
|
||||
user.total_luminosity -= brightness_on
|
||||
user.UpdateLuminosity()
|
||||
src.sd_SetLuminosity(brightness_on)
|
||||
user.SetLuminosity(user.luminosity - brightness_on)
|
||||
// user.UpdateLuminosity()
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
/obj/item/clothing/suit/space/rig
|
||||
name = "engineering hardsuit"
|
||||
|
||||
@@ -262,7 +262,6 @@ proc/move_mining_shuttle()
|
||||
icon_state = "diamonddrill"
|
||||
item_state = "jackhammer"
|
||||
digspeed = 15
|
||||
force = 3
|
||||
desc = ""
|
||||
|
||||
/*****************************Shovel********************************/
|
||||
|
||||
@@ -185,17 +185,16 @@
|
||||
shroom.pixel_x = 0
|
||||
shroom.pixel_y = 0
|
||||
|
||||
W = new /turf/simulated/floor/plating/airless/asteroid( locate(src.x, src.y, src.z) )
|
||||
W.dir = old_dir
|
||||
W.fullUpdateMineralOverlays()
|
||||
var/old_lumcount = lighting_lumcount - initial(lighting_lumcount)
|
||||
W = new /turf/simulated/floor/plating/airless/asteroid(src)
|
||||
W.lighting_lumcount += old_lumcount
|
||||
if(old_lumcount != W.lighting_lumcount)
|
||||
W.lighting_changed = 1
|
||||
lighting_controller.changed_turfs += W
|
||||
|
||||
/*
|
||||
W.icon_old = old_icon
|
||||
if(old_icon) W.icon_state = old_icon
|
||||
*/
|
||||
W.opacity = 1
|
||||
W.sd_SetOpacity(0)
|
||||
W.sd_LumReset()
|
||||
W.dir = old_dir
|
||||
|
||||
W.fullUpdateMineralOverlays()
|
||||
W.levelupdate()
|
||||
return W
|
||||
|
||||
|
||||
@@ -174,6 +174,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
L+=T
|
||||
usr.loc = pick(L)
|
||||
|
||||
/mob/dead/observer/verb/follow()
|
||||
set category = "Ghost"
|
||||
set name = "Follow" // "Haunt"
|
||||
set desc = "Follow and haunt a mob."
|
||||
|
||||
if(istype(usr, /mob/dead/observer))
|
||||
var/mob/target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in sortAtom(mob_list)
|
||||
if(target)
|
||||
spawn(0)
|
||||
var/turf/pos = get_turf(src)
|
||||
while(src.loc == pos)
|
||||
src.loc = get_turf(target)
|
||||
pos = src.loc
|
||||
sleep(15)
|
||||
|
||||
|
||||
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -50,4 +50,30 @@
|
||||
else
|
||||
// add some movement delay
|
||||
move_delay_add = min(move_delay_add + round(amount / 2), 10) // a maximum delay of 10
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: AddInfectionImages()
|
||||
Des: Gives the client of the alien an image on each infected mob.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/alien/proc/AddInfectionImages()
|
||||
if (client)
|
||||
for (var/mob/living/carbon/C in world)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected")
|
||||
client.images += I
|
||||
return
|
||||
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: RemoveInfectionImages()
|
||||
Des: Removes all infected images from the alien.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/alien/proc/RemoveInfectionImages()
|
||||
if (client)
|
||||
for(var/image/I in client.images)
|
||||
if(I.icon_state == "infected")
|
||||
del(I)
|
||||
return
|
||||
|
||||
|
||||
4
code/modules/mob/living/carbon/alien/login.dm
Normal file
4
code/modules/mob/living/carbon/alien/login.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
/mob/living/carbon/alien/humanoid/Login()
|
||||
..()
|
||||
AddInfectionImages()
|
||||
return
|
||||
4
code/modules/mob/living/carbon/alien/logout.dm
Normal file
4
code/modules/mob/living/carbon/alien/logout.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
/mob/living/carbon/alien/humanoid/Logout()
|
||||
..()
|
||||
RemoveInfectionImages()
|
||||
return
|
||||
258
code/modules/mob/living/carbon/alien/special/facehugger.dm
Normal file
258
code/modules/mob/living/carbon/alien/special/facehugger.dm
Normal file
@@ -0,0 +1,258 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
|
||||
var/const/MAX_IMPREGNATION_TIME = 150
|
||||
|
||||
var/const/MIN_ACTIVE_TIME = 300 //time between being dropped and going idle
|
||||
var/const/MAX_ACTIVE_TIME = 600
|
||||
|
||||
/obj/item/clothing/mask/facehugger
|
||||
name = "alien"
|
||||
desc = "It has some sort of a tube at the end of its tail."
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = FPRINT|TABLEPASS|MASKCOVERSMOUTH|MASKCOVERSEYES
|
||||
|
||||
var/stat = UNCONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
var/sterile = 0
|
||||
|
||||
var/strength = 5
|
||||
|
||||
var/attached = 0
|
||||
|
||||
attack_paw(user as mob) //can be picked up by aliens
|
||||
if(isalien(user))
|
||||
attack_hand(user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
attack_hand(user as mob)
|
||||
if(stat == CONSCIOUS && !isalien(user))
|
||||
Attach(user)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
attack(mob/living/M as mob, mob/user as mob)
|
||||
..()
|
||||
user.drop_from_inventory(src)
|
||||
Attach(M)
|
||||
|
||||
New()
|
||||
if(aliens_allowed)
|
||||
..()
|
||||
else
|
||||
del(src)
|
||||
|
||||
examine()
|
||||
..()
|
||||
switch(stat)
|
||||
if(DEAD,UNCONSCIOUS)
|
||||
usr << "\red \b [src] is not moving."
|
||||
if(CONSCIOUS)
|
||||
usr << "\red \b [src] seems to be active."
|
||||
if (sterile)
|
||||
usr << "\red \b It looks like the proboscis has been removed."
|
||||
return
|
||||
|
||||
attackby()
|
||||
Die()
|
||||
return
|
||||
|
||||
bullet_act()
|
||||
Die()
|
||||
return
|
||||
|
||||
temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
Die()
|
||||
return
|
||||
|
||||
equipped(mob/M)
|
||||
Attach(M)
|
||||
|
||||
HasEntered(atom/target)
|
||||
Attach(target)
|
||||
return
|
||||
|
||||
dropped()
|
||||
..()
|
||||
GoActive()
|
||||
return
|
||||
|
||||
throw_impact(atom/hit_atom)
|
||||
Attach(hit_atom)
|
||||
return
|
||||
|
||||
proc/Attach(M as mob)
|
||||
if(!isliving(M) || isalien(M))
|
||||
return
|
||||
if(attached)
|
||||
return
|
||||
else
|
||||
attached++
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
|
||||
var/mob/living/L = M //just so I don't need to use :
|
||||
|
||||
if(stat != CONSCIOUS) return
|
||||
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
|
||||
|
||||
if(issilicon(L))
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("\red \b [src] smashes against [L]'s frame!", 1)
|
||||
Die()
|
||||
return
|
||||
|
||||
var/mob/living/carbon/target = L
|
||||
|
||||
for(var/mob/O in viewers(target, null))
|
||||
O.show_message("\red \b [src] leaps at [target]'s face!", 1)
|
||||
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.head && H.head.flags & HEADCOVERSMOUTH)
|
||||
for(var/mob/O in viewers(H, null))
|
||||
O.show_message("\red \b [src] smashes against [H]'s [H.head]!", 1)
|
||||
Die()
|
||||
return
|
||||
|
||||
if(target.wear_mask)
|
||||
if(prob(20)) return
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(!W.canremove) return
|
||||
target.drop_from_inventory(W)
|
||||
|
||||
for(var/mob/O in viewers(target, null))
|
||||
O.show_message("\red \b [src] tears [W] off of [target]'s face!", 1)
|
||||
|
||||
loc = target
|
||||
layer = 20
|
||||
target.wear_mask = src
|
||||
target.update_inv_wear_mask()
|
||||
|
||||
GoIdle() //so it doesn't jump the people that tear it off
|
||||
|
||||
if(!sterile) target.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
|
||||
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
|
||||
Impregnate(target)
|
||||
|
||||
return
|
||||
|
||||
proc/Impregnate(mob/living/carbon/target as mob)
|
||||
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
|
||||
return
|
||||
|
||||
if(!sterile)
|
||||
target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
|
||||
for(var/datum/disease/alien_embryo/A in target.viruses)
|
||||
target.status_flags |= XENO_HOST
|
||||
break
|
||||
|
||||
for(var/mob/O in viewers(target,null))
|
||||
O.show_message("\red \b [src] falls limp after violating [target]'s face!", 1)
|
||||
|
||||
Die()
|
||||
else
|
||||
for(var/mob/O in viewers(target,null))
|
||||
O.show_message("\red \b [src] violates [target]'s face!", 1)
|
||||
target.update_inv_wear_mask()
|
||||
return
|
||||
|
||||
proc/GoActive()
|
||||
if(stat == DEAD || stat == CONSCIOUS)
|
||||
return
|
||||
|
||||
stat = CONSCIOUS
|
||||
|
||||
/* for(var/mob/living/carbon/alien/alien in world)
|
||||
var/image/activeIndicator = image('icons/mob/alien.dmi', loc = src, icon_state = "facehugger_active")
|
||||
activeIndicator.override = 1
|
||||
if(alien && alien.client)
|
||||
alien.client.images += activeIndicator */
|
||||
|
||||
spawn(rand(MIN_ACTIVE_TIME,MAX_ACTIVE_TIME))
|
||||
GoIdle()
|
||||
|
||||
return
|
||||
|
||||
proc/GoIdle()
|
||||
if(stat == DEAD || stat == UNCONSCIOUS)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
stat = UNCONSCIOUS
|
||||
|
||||
return
|
||||
|
||||
proc/Die()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
icon_state = "facehugger_dead"
|
||||
stat = DEAD
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("\red \b[src] curls up into a ball!", 1)
|
||||
|
||||
return
|
||||
|
||||
/* proc/RemoveActiveIndicators() //removes the "active" facehugger indicator from all aliens in the world for this hugger
|
||||
for(var/mob/living/carbon/alien/alien in world)
|
||||
if(alien.client)
|
||||
for(var/image/image in alien.client.images)
|
||||
if(image.icon_state == "facehugger_active" && image.loc == src)
|
||||
del(image)
|
||||
|
||||
return */
|
||||
|
||||
/obj/item/clothing/mask/facehugger/angry
|
||||
stat = CONSCIOUS
|
||||
|
||||
/obj/item/clothing/mask/facehugger/angry/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(istype(AM , /mob/living/))
|
||||
Attach(AM)
|
||||
|
||||
|
||||
/*
|
||||
/obj/item/clothing/mask/facehugger/angry/New()
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/angry/process()
|
||||
if(!src || src.stat == (DEAD))
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/C in range(1,src))
|
||||
Attach(C)
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/C in range(5,src))
|
||||
if(isInSight(C,src))
|
||||
step_to(src,C,0)
|
||||
spawn(5)
|
||||
if(C in range(1,src))
|
||||
Attach(C)
|
||||
return
|
||||
|
||||
step_rand(src)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/angry/Attach(var/mob/M as mob)
|
||||
|
||||
..(M)
|
||||
processing_objects.Remove(src)
|
||||
|
||||
*/
|
||||
61
code/modules/mob/living/carbon/brain/brain_item.dm
Normal file
61
code/modules/mob/living/carbon/brain/brain_item.dm
Normal file
@@ -0,0 +1,61 @@
|
||||
/obj/item/brain/examine() // -- TLE
|
||||
set src in oview(12)
|
||||
if (!( usr ))
|
||||
return
|
||||
usr << "This is \icon[src] \an [name]."
|
||||
|
||||
if(brainmob)//if thar be a brain inside... the brain.
|
||||
usr << "You can feel the small spark of life still left in this one."
|
||||
else
|
||||
usr << "This one seems particularly lifeless. Perhaps it will regain some of its luster later. Probably not."
|
||||
|
||||
/obj/item/brain/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(!(user.zone_sel.selecting == ("head")) || !istype(M, /mob/living/carbon/human))
|
||||
return ..()
|
||||
|
||||
if( !(locate(/obj/machinery/optable, M.loc) && M.resting) && ( !(locate(/obj/structure/table/, M.loc) && M.lying) && prob(50) ) )
|
||||
return ..()
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
// you can't stab someone in the eyes wearing a mask!
|
||||
user << "\blue You're going to need to remove their head cover first."
|
||||
return
|
||||
|
||||
//since these people will be dead M != usr
|
||||
|
||||
if(M:brain_op_stage == 4.0)
|
||||
for(var/mob/O in viewers(M, null))
|
||||
if(O == (user || M))
|
||||
continue
|
||||
if(M == user)
|
||||
O.show_message(text("\red [user] inserts [src] into his head!"), 1)
|
||||
else
|
||||
O.show_message(text("\red [M] has [src] inserted into his head by [user]."), 1)
|
||||
|
||||
if(M != user)
|
||||
M << "\red [user] inserts [src] into your head!"
|
||||
user << "\red You insert [src] into [M]'s head!"
|
||||
else
|
||||
user << "\red You insert [src] into your head!"
|
||||
|
||||
//this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO
|
||||
if(M.key)//Revised. /N
|
||||
M.ghostize()
|
||||
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(M)
|
||||
else
|
||||
M.key = brainmob.key
|
||||
|
||||
M:brain_op_stage = 3.0
|
||||
|
||||
del(src)
|
||||
else
|
||||
..()
|
||||
return
|
||||
@@ -39,6 +39,9 @@
|
||||
var/obj/item/l_store = null
|
||||
var/obj/item/s_store = null
|
||||
|
||||
var/used_skillpoints = 0
|
||||
var/skill_specialization = null
|
||||
var/list/skills = null
|
||||
|
||||
var/icon/stand_icon = null
|
||||
var/icon/lying_icon = null
|
||||
|
||||
@@ -87,9 +87,6 @@
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
//Flashlights and such
|
||||
UpdateLuminosity()
|
||||
|
||||
//Status updates, death etc.
|
||||
handle_regular_status_updates() //TODO: optimise ~Carn
|
||||
update_canmove()
|
||||
@@ -745,13 +742,16 @@
|
||||
|
||||
if(dna && dna.mutantrace == "plant") //couldn't think of a better place to place it, since it handles nutrition -- Urist
|
||||
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
|
||||
if(istype(loc,/turf)) //else, there's considered to be no light
|
||||
light_amount = min(10,loc:sd_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
|
||||
if(istype(loc,/turf/simulated/shuttle))//Now not only will potatomen not starve on the shuttle, they will actually be fed
|
||||
light_amount = 5
|
||||
if(nutrition < 500) //so they can't store nutrition to survive without light forever
|
||||
nutrition += light_amount
|
||||
if(light_amount > 0) //if there's enough light, heal
|
||||
if(isturf(loc)) //else, there's considered to be no light
|
||||
var/turf/T = loc
|
||||
var/area/A = T.loc
|
||||
if(A)
|
||||
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
|
||||
else light_amount = 5
|
||||
nutrition += light_amount
|
||||
if(nutrition > 500)
|
||||
nutrition = 500
|
||||
if(light_amount > 2) //if there's enough light, heal
|
||||
heal_overall_damage(1,1)
|
||||
adjustToxLoss(-1)
|
||||
adjustOxyLoss(-1)
|
||||
@@ -1150,7 +1150,7 @@
|
||||
//0.1% chance of playing a scary sound to someone who's in complete darkness
|
||||
if(isturf(loc) && rand(1,1000) == 1)
|
||||
var/turf/currentTurf = loc
|
||||
if(!currentTurf.sd_lumcount)
|
||||
if(!currentTurf.lighting_lumcount)
|
||||
playsound_local(src,pick(scarySounds),50, 1, -1)
|
||||
|
||||
proc/handle_virus_updates()
|
||||
|
||||
@@ -53,9 +53,6 @@
|
||||
if(environment) // More error checking -- TLE
|
||||
handle_environment(environment)
|
||||
|
||||
//Flashlights and such
|
||||
UpdateLuminosity()
|
||||
|
||||
//Status updates, death etc.
|
||||
handle_regular_status_updates()
|
||||
update_canmove()
|
||||
|
||||
@@ -141,37 +141,6 @@ var/list/department_radio_keys = list(
|
||||
if (!message)
|
||||
return
|
||||
|
||||
//work out if we're speaking skrell or not
|
||||
var/is_speaking_skrell = 0
|
||||
|
||||
if(copytext(message, 1, 3) == ":k" || copytext(message, 1, 3) == ":K")
|
||||
message = copytext(message, 3)
|
||||
if(skrell_talk_understand || universal_speak)
|
||||
is_speaking_skrell = 1
|
||||
|
||||
//work out if we're speaking soghun or not
|
||||
var/is_speaking_soghun = 0
|
||||
if(copytext(message, 1, 3) == ":o" || copytext(message, 1, 3) == ":O")
|
||||
message = copytext(message, 3)
|
||||
if(soghun_talk_understand || universal_speak)
|
||||
is_speaking_soghun = 1
|
||||
|
||||
//work out if we're speaking tajaran or not
|
||||
var/is_speaking_tajaran = 0
|
||||
if(copytext(message, 1, 3) == ":j" || copytext(message, 1, 3) == ":J")
|
||||
message = copytext(message, 3)
|
||||
if(tajaran_talk_understand || universal_speak)
|
||||
is_speaking_soghun = 1
|
||||
|
||||
// if( !message_mode && (disease_symptoms & DISEASE_WHISPER))
|
||||
// message_mode = "whisper"
|
||||
|
||||
if(src.stunned > 2 /*|| (traumatic_shock > 61 && prob(50))*/)
|
||||
message_mode = "" //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
|
||||
|
||||
|
||||
message = capitalize(message) //capitalize the first letter of what they actually say
|
||||
|
||||
// :downs:
|
||||
if (getBrainLoss() >= 60)
|
||||
message = dd_replacetext(message, " am ", " ")
|
||||
@@ -187,12 +156,10 @@ var/list/department_radio_keys = list(
|
||||
message = uppertext(message)
|
||||
message += "[stutter(pick("!", "!!", "!!!"))]"
|
||||
if(!stuttering && prob(15))
|
||||
message = NewStutter(message,stunned)
|
||||
message = stutter(message)
|
||||
|
||||
if (stuttering)
|
||||
message = NewStutter(message,stunned)
|
||||
if (slurring)
|
||||
message = slur(message)
|
||||
message = stutter(message)
|
||||
|
||||
/* //qw do not have beesease atm.
|
||||
if(virus)
|
||||
@@ -316,13 +283,6 @@ var/list/department_radio_keys = list(
|
||||
var/list/V = view(message_range, T)
|
||||
var/list/W = V
|
||||
|
||||
var/list/eavesdroppers = get_mobs_in_view(7, src)
|
||||
for(var/mob/M in listening)
|
||||
eavesdroppers.Remove(M)
|
||||
for(var/mob/M in eavesdroppers)
|
||||
if(M.stat || !M.client || istype(M, /mob/living/silicon/pai) || M == src)
|
||||
eavesdroppers.Remove(M)
|
||||
|
||||
for (var/obj/O in ((W | contents)-used_radios))
|
||||
W |= O
|
||||
|
||||
@@ -352,24 +312,17 @@ var/list/department_radio_keys = list(
|
||||
var/list/heard_a = list() // understood us
|
||||
var/list/heard_b = list() // didn't understand us
|
||||
|
||||
for (var/mob/M in listening) //My god this is to terrible and hacky - Erthilo
|
||||
for (var/M in listening)
|
||||
if(hascall(M,"say_understands"))
|
||||
if (M:say_understands(src) && !is_speaking_skrell && !is_speaking_soghun && !is_speaking_tajaran) //This could probably be merged into say_understands(), but I'm too lazy
|
||||
heard_a += M
|
||||
else if(is_speaking_skrell && (M.skrell_talk_understand || M.universal_speak))
|
||||
heard_a += M
|
||||
else if(is_speaking_soghun && (M.soghun_talk_understand || M.universal_speak))
|
||||
heard_a += M
|
||||
else if(is_speaking_tajaran && (M.tajaran_talk_understand || M.universal_speak))
|
||||
if (M:say_understands(src))
|
||||
heard_a += M
|
||||
else
|
||||
heard_b += M
|
||||
var/speech_bubble_test = say_test(message)
|
||||
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
|
||||
|
||||
var/rendered = null
|
||||
if (length(heard_a))
|
||||
var/message_a = say_quote(message,is_speaking_soghun,is_speaking_skrell,is_speaking_tajaran)
|
||||
var/message_a = say_quote(message)
|
||||
|
||||
if (italics)
|
||||
message_a = "<i>[message_a]</i>"
|
||||
if (!istype(src, /mob/living/carbon/human))
|
||||
@@ -382,17 +335,10 @@ var/list/department_radio_keys = list(
|
||||
else
|
||||
rendered = "<span class='game say'><span class='name'>[real_name]</span>[alt_name] <span class='message'>[message_a]</span></span>"
|
||||
|
||||
for (var/mob/M in heard_a)
|
||||
|
||||
M.show_message(rendered, 2)
|
||||
M << speech_bubble
|
||||
spawn(30) del(speech_bubble)
|
||||
//spawn(30) del(speech_bubble)
|
||||
|
||||
/* for (var/M in heard_a)
|
||||
for (var/M in heard_a)
|
||||
if(hascall(M,"show_message"))
|
||||
M:show_message(rendered, 2)
|
||||
*/
|
||||
|
||||
if (length(heard_b))
|
||||
var/message_b
|
||||
|
||||
@@ -400,17 +346,13 @@ var/list/department_radio_keys = list(
|
||||
message_b = voice_message
|
||||
else
|
||||
message_b = stars(message)
|
||||
message_b = say_quote(message_b,is_speaking_soghun,is_speaking_skrell,is_speaking_tajaran)
|
||||
message_b = say_quote(message_b)
|
||||
|
||||
if (italics)
|
||||
message_b = "<i>[message_b]</i>"
|
||||
|
||||
rendered = "<span class='game say'><span class='name'>[voice_name]</span> <span class='message'>[message_b]</span></span>"
|
||||
|
||||
for (var/mob/M in heard_b)
|
||||
M.show_message(rendered, 2)
|
||||
M << speech_bubble
|
||||
spawn(30) del(speech_bubble)
|
||||
|
||||
for (var/M in heard_b)
|
||||
if(hascall(M,"show_message"))
|
||||
@@ -437,16 +379,9 @@ var/list/department_radio_keys = list(
|
||||
del(B)
|
||||
*/
|
||||
|
||||
if (length(eavesdroppers))
|
||||
|
||||
for (var/mob/M in eavesdroppers)
|
||||
M << "\blue [src] speaks into their radio..."
|
||||
M << speech_bubble
|
||||
spawn(30) del(speech_bubble)
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
|
||||
|
||||
|
||||
/obj/effect/speech_bubble
|
||||
var/mob/parent
|
||||
var/mob/parent
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/ioncheck[1]
|
||||
var/icon/holo_icon//Default is assigned when AI is created.
|
||||
var/obj/item/device/pda/ai/aiPDA = null
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/AI_Module/module_picker/malf_picker
|
||||
@@ -69,6 +70,8 @@
|
||||
aiPDA.ownjob = "AI"
|
||||
aiPDA.name = name + " (" + aiPDA.ownjob + ")"
|
||||
|
||||
aiMulti = new(src)
|
||||
|
||||
if (istype(loc, /turf))
|
||||
verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
|
||||
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
|
||||
@@ -101,7 +104,7 @@
|
||||
|
||||
/mob/living/silicon/ai/verb/pick_icon()
|
||||
set category = "AI Commands"
|
||||
set name = "Change AI Core Display"
|
||||
set name = "Set AI Core Display"
|
||||
if(stat || aiRestorePowerRoutine)
|
||||
return
|
||||
|
||||
@@ -292,7 +295,7 @@
|
||||
machine = null
|
||||
src << browse(null, t1)
|
||||
if (href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"]))
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
|
||||
if (href_list["showalerts"])
|
||||
ai_alerts()
|
||||
|
||||
@@ -325,15 +328,15 @@
|
||||
statelaws()
|
||||
|
||||
if (href_list["track"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
return
|
||||
|
||||
else if (href_list["faketrack"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
if(A && target)
|
||||
|
||||
A.cameraFollow = target
|
||||
@@ -426,25 +429,27 @@
|
||||
|
||||
/mob/living/silicon/ai/reset_view(atom/A)
|
||||
if(current)
|
||||
current.sd_SetLuminosity(0)
|
||||
current.SetLuminosity(0)
|
||||
if(istype(A,/obj/machinery/camera))
|
||||
current = A
|
||||
..()
|
||||
if(istype(A,/obj/machinery/camera))
|
||||
A.sd_SetLuminosity(camera_light_on * AI_CAMERA_LUMINOSITY)
|
||||
if(camera_light_on) A.SetLuminosity(AI_CAMERA_LUMINOSITY)
|
||||
else A.SetLuminosity(0)
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C)
|
||||
|
||||
src.cameraFollow = null
|
||||
if (!C || stat == 2 || !C.status || C.network != network)
|
||||
machine = null
|
||||
reset_view(null)
|
||||
if (!C || stat == 2 || !C.can_use())
|
||||
//machine = null
|
||||
//reset_view(null)
|
||||
return 0
|
||||
|
||||
// ok, we're alive, camera is good and in our network...
|
||||
machine = src
|
||||
reset_view(C)
|
||||
eyeobj.setLoc(get_turf(C))
|
||||
//machine = src
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
|
||||
@@ -468,7 +473,7 @@
|
||||
C = O
|
||||
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
|
||||
if (O)
|
||||
if (C && C.status)
|
||||
if (C && C.can_use())
|
||||
src << "--- [class] alarm detected in [A.name]! (<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>)"
|
||||
else if (CL && CL.len)
|
||||
var/foo = 0
|
||||
@@ -504,17 +509,17 @@
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set category = "AI Commands"
|
||||
set name = "Cancel Camera View"
|
||||
reset_view(null)
|
||||
machine = null
|
||||
//reset_view(null)
|
||||
//machine = null
|
||||
src.cameraFollow = null
|
||||
|
||||
|
||||
//Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm
|
||||
//Adds in /mob/living/silicon/ai/proc/ai_network_change() instead
|
||||
//Addition by Mord_Sith to define AI's network change ability
|
||||
/mob/living/silicon/ai/proc/ai_network_change()
|
||||
set category = "AI Commands"
|
||||
set name = "Change Camera Network"
|
||||
reset_view(null)
|
||||
set name = "Jump To Network"
|
||||
machine = null
|
||||
src.cameraFollow = null
|
||||
var/cameralist[0]
|
||||
@@ -523,8 +528,10 @@
|
||||
usr << "You can't change your camera network because you are dead!"
|
||||
return
|
||||
|
||||
for (var/obj/machinery/camera/C in Cameras)
|
||||
if(!C.status)
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network == "AI Satellite")
|
||||
if (ticker.mode.name == "AI malfunction")
|
||||
@@ -535,10 +542,17 @@
|
||||
else
|
||||
if(C.network != "CREED" && C.network != "thunder" && C.network != "RD" && C.network != "toxins" && C.network != "Prison")
|
||||
cameralist[C.network] = C.network
|
||||
|
||||
network = input(usr, "Which network would you like to view?") as null|anything in cameralist
|
||||
var/old_network = network
|
||||
network = input(U, "Which network would you like to view?") as null|anything in cameralist
|
||||
if(isnull(network))
|
||||
network = initial(network) // If nothing is selected, default to SS13 (or the initial network)
|
||||
network = old_network // If nothing is selected
|
||||
else
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network == network)
|
||||
U.eyeobj.setLoc(get_turf(C))
|
||||
break
|
||||
src << "\blue Switched to [network] camera network."
|
||||
//End of code by Mord_Sith
|
||||
|
||||
@@ -551,7 +565,7 @@
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_statuschange()
|
||||
set category = "AI Commands"
|
||||
set name = "AI status"
|
||||
set name = "AI Status"
|
||||
|
||||
if(usr.stat == 2)
|
||||
usr <<"You cannot change your emotional status because you are dead!"
|
||||
@@ -620,15 +634,35 @@
|
||||
|
||||
//Toggles the luminosity and applies it by re-entereing the camera.
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light()
|
||||
set name = "Toggle camera light"
|
||||
set name = "Toggle Camera Light"
|
||||
set desc = "Toggles the light on the camera the AI is looking through."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(!current)
|
||||
usr << "\red You are not looking through a camera right now."
|
||||
return
|
||||
camera_light_on = !camera_light_on
|
||||
reset_view(current)
|
||||
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
|
||||
if(!camera_light_on)
|
||||
if(src.current)
|
||||
src.current.SetLuminosity(0)
|
||||
else
|
||||
src.lightNearbyCamera()
|
||||
|
||||
|
||||
#undef AI_CAMERA_LUMINOSITY
|
||||
|
||||
// Handled camera lighting, when toggled.
|
||||
// It will get the nearest camera from the eyeobj, lighting it.
|
||||
|
||||
/mob/living/silicon/ai/proc/lightNearbyCamera()
|
||||
if(camera_light_on && camera_light_on < world.timeofday)
|
||||
if(src.current)
|
||||
var/camera = near_range_camera(src.eyeobj)
|
||||
if(camera && src.current != camera)
|
||||
src.current.SetLuminosity(0)
|
||||
src.current = camera
|
||||
src.current.SetLuminosity(AI_CAMERA_LUMINOSITY)
|
||||
else if(isnull(camera))
|
||||
src.current.SetLuminosity(0)
|
||||
src.current = null
|
||||
camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds.
|
||||
else
|
||||
src.current = near_range_camera(src.eyeobj)
|
||||
if(src.current) src.current.SetLuminosity(AI_CAMERA_LUMINOSITY)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon_state = "ai-crash"
|
||||
|
||||
update_canmove()
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
if(blind) blind.layer = 0
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
|
||||
134
code/modules/mob/living/silicon/ai/freelook/cameranet.dm
Normal file
134
code/modules/mob/living/silicon/ai/freelook/cameranet.dm
Normal file
@@ -0,0 +1,134 @@
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet
|
||||
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||
var/list/cameras = list()
|
||||
// The chunks of the map, mapping the areas that the cameras can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
return key in chunks
|
||||
|
||||
// Returns the chunk in the x, y, z.
|
||||
// If there is no chunk, it creates a new chunk and returns that.
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!(key in chunks))
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
|
||||
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
// 0xf = 15
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/datum/camerachunk/c in remove)
|
||||
c.remove(ai)
|
||||
|
||||
for(var/datum/camerachunk/c in add)
|
||||
c.add(ai)
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
/datum/cameranet/proc/updateChunk(x, y, z)
|
||||
// 0xf = 15
|
||||
if(!chunkGenerated(x, y, z))
|
||||
return
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
|
||||
chunk.hasChanged()
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Add a camera to a chunk.
|
||||
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
|
||||
// Used for Cyborg cameras. It is the same as "add" but named differently for easier readability
|
||||
// and to allow the user know what it is for. Since portable cameras can be in ANY chunk, we have to
|
||||
// all it to be added to all chunks. If the camera is disabled, it will instead remove.
|
||||
|
||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
else
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Never access this proc directly!!!!
|
||||
// This will update the chunk and all the surrounding chunks.
|
||||
// It will also add the atom to the cameras list if you set the choice to 1.
|
||||
// Setting the choice to 0 will remove the camera from the chunks.
|
||||
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
|
||||
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, var/choice)
|
||||
// 0xf = 15
|
||||
if(!c)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(c)
|
||||
if(T)
|
||||
var/x1 = max(0, T.x - 16) & ~0xf
|
||||
var/y1 = max(0, T.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, T.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, T.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
|
||||
if(choice == 0)
|
||||
// Remove the camera.
|
||||
chunk.cameras -= c
|
||||
else if(choice == 1)
|
||||
// You can't have the same camera in the list twice.
|
||||
chunk.cameras |= c
|
||||
chunk.hasChanged()
|
||||
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/datum/cameranet/proc/checkCameraVis(mob/living/target as mob)
|
||||
|
||||
// 0xf = 15
|
||||
var/turf/position = get_turf(target)
|
||||
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
|
||||
if(chunk)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
if(position in chunk.visibleTurfs)
|
||||
return 1
|
||||
return 0
|
||||
135
code/modules/mob/living/silicon/ai/freelook/chunk.dm
Normal file
135
code/modules/mob/living/silicon/ai/freelook/chunk.dm
Normal file
@@ -0,0 +1,135 @@
|
||||
#define UPDATE_BUFFER 15
|
||||
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the AI Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = 0
|
||||
var/changed = 0
|
||||
var/updating = 0
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks += src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images += obscured
|
||||
visible++
|
||||
seenby += ai
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks -= src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images -= obscured
|
||||
seenby -= ai
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!(loc in visibleTurfs))
|
||||
return
|
||||
|
||||
hasChanged()
|
||||
|
||||
// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
|
||||
// instead be flagged to update the next time an AI Eye moves near it.
|
||||
|
||||
/datum/camerachunk/proc/hasChanged(var/update_now = 0)
|
||||
if(visible || update_now)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
else
|
||||
changed = 1
|
||||
|
||||
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
if(!c.can_use())
|
||||
continue
|
||||
var/turf/pos = get_turf(c)
|
||||
if(pos)
|
||||
for(var/turf/t in range(7, pos))
|
||||
if(t in turfs)
|
||||
newVisibleTurfs += t
|
||||
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
obscuredTurfs = turfs - newVisibleTurfs
|
||||
|
||||
|
||||
for(var/turf/t in visAdded)
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visRemoved)
|
||||
if(t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(!m)
|
||||
seenby -= m
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.can_use())
|
||||
cameras += c
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs += t
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
if(!c.can_use())
|
||||
continue
|
||||
var/turf/pos = get_turf(c)
|
||||
if(pos)
|
||||
for(var/turf/t in range(7, pos))
|
||||
if(t in turfs)
|
||||
visibleTurfs += t
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf/t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
|
||||
obscured += t.obscured
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
114
code/modules/mob/living/silicon/ai/freelook/eye.dm
Normal file
114
code/modules/mob/living/silicon/ai/freelook/eye.dm
Normal file
@@ -0,0 +1,114 @@
|
||||
// AI EYE
|
||||
//
|
||||
// An invisible (no icon) mob that the AI controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
|
||||
|
||||
/mob/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
density = 0
|
||||
nodamage = 1 // You can't damage it.
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/aiEye/Move()
|
||||
return 0
|
||||
|
||||
// Hide popout menu verbs
|
||||
/mob/aiEye/examine()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/aiEye/pull()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/aiEye/point()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
// Use this when setting the aiEye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
|
||||
/mob/aiEye/proc/setLoc(var/T)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
cameranet.visibility(src)
|
||||
if(ai)
|
||||
if(ai.client)
|
||||
ai.client.eye = src
|
||||
|
||||
// AI MOVEMENT
|
||||
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/mob/aiEye/eyeobj = new()
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
|
||||
|
||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.ai = src
|
||||
spawn(5)
|
||||
eyeobj.loc = src.loc
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
|
||||
/mob/living/silicon/ai/Del()
|
||||
eyeobj.ai = null
|
||||
del(eyeobj) // No AI, no Eye
|
||||
..()
|
||||
|
||||
// This will move the AIEye. It will also cause lights near the eye to light up, if toggled.
|
||||
// This is handled in the proc below this one.
|
||||
|
||||
/client/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
||||
|
||||
var/initial = initial(user.sprint)
|
||||
var/max_sprint = 50
|
||||
|
||||
if(user.cooldown && user.cooldown < world.timeofday) // 3 seconds
|
||||
user.sprint = initial
|
||||
|
||||
for(var/i = 0; i < max(user.sprint, initial); i += 20)
|
||||
user.eyeobj.setLoc(get_turf(get_step(user.eyeobj, direct)))
|
||||
|
||||
user.cooldown = world.timeofday + 5
|
||||
if(user.acceleration)
|
||||
user.sprint = min(user.sprint + 0.5, max_sprint)
|
||||
else
|
||||
user.sprint = initial
|
||||
|
||||
user.cameraFollow = null
|
||||
src.eye = user.eyeobj
|
||||
|
||||
//user.machine = null //Uncomment this if it causes problems.
|
||||
user.lightNearbyCamera()
|
||||
|
||||
|
||||
// Return to the Core.
|
||||
|
||||
/mob/living/silicon/ai/verb/core()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Core"
|
||||
current = null
|
||||
cameraFollow = null
|
||||
machine = null
|
||||
src.eyeobj.loc = src.loc
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
|
||||
/mob/living/silicon/ai/verb/toggle_acceleration()
|
||||
set category = "AI Commands"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
acceleration = !acceleration
|
||||
usr << "Camera acceleration has been toggled [acceleration ? "on" : "off"]."
|
||||
51
code/modules/mob/living/silicon/ai/freelook/read_me.dm
Normal file
51
code/modules/mob/living/silicon/ai/freelook/read_me.dm
Normal file
@@ -0,0 +1,51 @@
|
||||
// CREDITS
|
||||
/*
|
||||
Initial code credit for this goes to Uristqwerty.
|
||||
Debugging, functionality, all comments and porting by Giacom.
|
||||
|
||||
Everything about freelook (or what we can put in here) will be stored here.
|
||||
|
||||
|
||||
WHAT IS THIS?
|
||||
|
||||
This is a replacement for the current camera movement system, of the AI. Before this, the AI had to move between cameras and could
|
||||
only see what the cameras could see. Not only this but the cameras could see through walls, which created problems.
|
||||
With this, the AI controls an "AI Eye" mob, which moves just like a ghost; such as moving through walls and being invisible to players.
|
||||
The AI's eye is set to this mob and then we use a system (explained below) to determine what the cameras around the AI Eye can and
|
||||
cannot see. If the camera cannot see a turf, it will black it out, otherwise it won't and the AI will be able to see it.
|
||||
This creates several features, such as.. no more see-through-wall cameras, easier to control camera movement, easier tracking,
|
||||
the AI only being able to track mobs which are visible to a camera, only trackable mobs appearing on the mob list and many more.
|
||||
|
||||
|
||||
HOW IT WORKS
|
||||
|
||||
It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be
|
||||
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Del().
|
||||
|
||||
Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk.
|
||||
These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside
|
||||
the 16x16 block, it is listed as an "obscured" turf. Meaning the AI won't be able to see it.
|
||||
|
||||
|
||||
HOW IT UPDATES
|
||||
|
||||
The camera network uses a streaming method in order to effeciently update chunks. Since the server will have doors opening, doors closing,
|
||||
turf being destroyed and other lag inducing stuff, we want to update it under certain conditions and not every tick.
|
||||
|
||||
The chunks are not created straight away, only when an AI eye moves into it's area is when it gets created.
|
||||
One a chunk is created, when a non glass door opens/closes or an opacity turf is destroyed, we check to see if an AI Eye is looking in the area.
|
||||
We do this with the "seenby" list, which updates everytime an AI is near a chunk. If there is an AI eye inside the area, we update the chunk
|
||||
that the changed atom is inside and all surrounding chunks, since a camera's vision could leak onto another chunk. If there is no AI Eye, we instead
|
||||
flag the chunk to update whenever it is loaded by an AI Eye. This is basically how the chunks update and keep it in sync. We then add some lag reducing
|
||||
measures, such as an UPDATE_BUFFER which stops a chunk from updating too many times in a certain time-frame, only updating if the changed atom was blocking
|
||||
sight; for example, we don't update glass airlocks or floors.
|
||||
|
||||
|
||||
WHERE IS EVERYTHING?
|
||||
|
||||
cameranet.dm = Everything about the cameranet datum.
|
||||
chunk.dm = Everything about the chunk datum.
|
||||
eye.dm = Everything about the AI and the AIEye.
|
||||
updating.dm = Everything about triggers that will update chunks.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,79 @@
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
// TURFS
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.client.eye == AI.eyeobj)
|
||||
AI.eyeobj.setLoc(src)
|
||||
|
||||
/*
|
||||
/turf/simulated/Del()
|
||||
visibilityChanged()
|
||||
..()
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
visibilityChanged()
|
||||
|
||||
// STRUCTURES
|
||||
|
||||
/obj/structure/Del()
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
// DOORS
|
||||
|
||||
// Simply updates the visibility of the area when it opens/closes/destroyed.
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
*/
|
||||
|
||||
// ROBOT MOVEMENT
|
||||
|
||||
// Update the portable camera everytime the Robot moves.
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
|
||||
/mob/living/silicon/robot/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.camera)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
|
||||
// CAMERA
|
||||
|
||||
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
|
||||
|
||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||
..(user, choice)
|
||||
if(src.can_use())
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
src.SetLuminosity(0)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.cameras += src
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.cameras -= src
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
@@ -22,4 +22,5 @@
|
||||
if(O)
|
||||
O.mode = 1
|
||||
O.emotion = "Neutral"
|
||||
src.core()
|
||||
return
|
||||
@@ -6,4 +6,5 @@
|
||||
if (client)
|
||||
client.eye = loc
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
src.core()
|
||||
return
|
||||
@@ -13,20 +13,6 @@
|
||||
var/obj/machinery/camera/closest = null
|
||||
var/atom/old = (user.current?user.current : user.loc)
|
||||
|
||||
if(istype(user.loc, /obj/item/clothing/suit/space/space_ninja))//To make ninja suit AI holograms work.
|
||||
var/obj/item/clothing/suit/space/space_ninja/S = user.loc//Ease of use.
|
||||
if(S.hologram)//If there is a hologram.
|
||||
S.hologram.loc = get_step(S.hologram, direct)
|
||||
S.hologram.dir = direct
|
||||
return//Whatever the case, return since you can't move anyway.
|
||||
|
||||
if(user.client)//To make AI holograms work. They will relay directions as long as they are centered on the object.
|
||||
var/obj/machinery/hologram/holopad/T = user.client.eye//Client eye centers on an object.
|
||||
if(istype(T)&&T.hologram&&T.master==user)//If there is a hologram and its master is the user.
|
||||
T.hologram.loc = get_step(T.hologram, direct)
|
||||
T.hologram.dir = direct
|
||||
return//Relay move and then return if that's the case.
|
||||
|
||||
if(!old) return
|
||||
|
||||
var/dx = 0
|
||||
@@ -43,7 +29,7 @@
|
||||
var/area/A = get_area(old)
|
||||
var/list/old_types = dd_text2list("[A.type]", "/")
|
||||
|
||||
for(var/obj/machinery/camera/current in Cameras)
|
||||
for(var/obj/machinery/camera/current in cameranet.cameras)
|
||||
if(user.network != current.network) continue
|
||||
if(!current.status) continue // ignore disabled cameras
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@
|
||||
var/mob/living/M = src.loc
|
||||
var/count = 0
|
||||
while(!istype(M, /mob/living))
|
||||
if(!M || !M.loc) return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
|
||||
M = M.loc
|
||||
count++
|
||||
if(count >= 6)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
handle_regular_status_updates()
|
||||
|
||||
if(client)
|
||||
// UpdateLuminosity()
|
||||
handle_regular_hud_updates()
|
||||
update_items()
|
||||
if (src.stat != DEAD) //still using power
|
||||
@@ -303,4 +302,4 @@
|
||||
/mob/living/silicon/robot/update_canmove()
|
||||
if(paralysis || stunned || weakened || buckled || lockcharge) canmove = 0
|
||||
else canmove = 1
|
||||
return canmove
|
||||
return canmove
|
||||
@@ -29,7 +29,7 @@
|
||||
modtype = "Synd"
|
||||
|
||||
radio = new /obj/item/device/radio/borg(src)
|
||||
if(!scrambledcodes)
|
||||
if(!scrambledcodes && !camera)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera.c_tag = real_name
|
||||
camera.network = "SS13"
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if (!isnull(src.camera) && !scrambledcodes)
|
||||
src.camera.status = 1
|
||||
src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
|
||||
|
||||
src.interact(usr)
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
robot_talk(message)
|
||||
else if ((copytext(message, 1, 3) == ":h") || (copytext(message, 1, 3) == ":H"))
|
||||
if(isAI(src)&&client)//For patching directly into AI holopads.
|
||||
var/mob/living/silicon/ai/U = src
|
||||
message = copytext(message, 3)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
holopad_talk(message)
|
||||
U.holopad_talk(message)
|
||||
else//Will not allow anyone by an active AI to use this function.
|
||||
src << "This function is not available to you."
|
||||
return
|
||||
@@ -38,7 +39,7 @@
|
||||
return ..(message)
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/proc/holopad_talk(var/message)
|
||||
/mob/living/silicon/ai/proc/holopad_talk(var/message)
|
||||
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
@@ -47,8 +48,8 @@
|
||||
if (!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = client.eye//Client eye centers on an object.
|
||||
if(istype(T)&&T.hologram&&T.master==src)//If there is a hologram and its master is the user.
|
||||
var/obj/machinery/hologram/holopad/T = locate(/obj/machinery/hologram/holopad) in src.eyeobj.loc
|
||||
if(istype(T) && T.hologram && T.master==src)//If there is a hologram and its master is the user.
|
||||
var/message_a = say_quote(message)
|
||||
|
||||
//Human-like, sorta, heard by those who understand humans.
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
/mob/living/silicon/proc/show_laws()
|
||||
return
|
||||
|
||||
/mob/living/silicon/drop_item()
|
||||
return
|
||||
|
||||
/mob/living/silicon/emp_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
emote_hear = list("barks", "woofs", "yaps","pants")
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
desc = "It's a corgi."
|
||||
src.sd_SetLuminosity(0)
|
||||
SetLuminosity(0)
|
||||
inventory_head.loc = src.loc
|
||||
inventory_head = null
|
||||
else
|
||||
@@ -216,7 +216,7 @@
|
||||
name = "Rudolph the Red-Nosed Corgi"
|
||||
emote_hear = list("barks christmas songs", "yaps")
|
||||
desc = "He has a very shiny nose."
|
||||
src.sd_SetLuminosity(6)
|
||||
SetLuminosity(6)
|
||||
if(/obj/item/clothing/head/soft)
|
||||
name = "Corgi Tech [real_name]"
|
||||
speak = list("Needs a stamp!", "Request DENIED!", "Fill these out in triplicate!")
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
|
||||
usr.show_message(t, 1)
|
||||
|
||||
/atom/proc/relaymove()
|
||||
return
|
||||
|
||||
/mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
|
||||
if(!client) return
|
||||
if (type)
|
||||
@@ -75,6 +72,33 @@
|
||||
M.show_message( message, 1, blind_message, 2)
|
||||
|
||||
|
||||
//What the fuck is this code
|
||||
/mob/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (user.intent != "harm")
|
||||
if (istype(src.l_hand,/obj/item/latexballon) && src.l_hand:air_contents && is_sharp(W))
|
||||
return src.l_hand.attackby(W)
|
||||
if (istype(src.r_hand,/obj/item/latexballon) && src.r_hand:air_contents && is_sharp(W))
|
||||
return src.r_hand.attackby(W)
|
||||
var/shielded = 0
|
||||
if (locate(/obj/item/weapon/grab, src))
|
||||
var/mob/safe = null
|
||||
if (istype(src.l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = src.l_hand
|
||||
if ((G.state == 3 && get_dir(src, user) == src.dir))
|
||||
safe = G.affecting
|
||||
if (istype(src.r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = src.r_hand
|
||||
if ((G.state == 3 && get_dir(src, user) == src.dir))
|
||||
safe = G.affecting
|
||||
if (safe)
|
||||
return safe.attackby(W, user)
|
||||
if ((!( shielded ) || !( W.flags ) & 32))
|
||||
spawn( 0 )
|
||||
if (W)
|
||||
W.attack(src, user)
|
||||
return
|
||||
return
|
||||
|
||||
/mob/proc/findname(msg)
|
||||
for(var/mob/M in mob_list)
|
||||
if (M.real_name == text("[]", msg))
|
||||
@@ -505,11 +529,6 @@ var/list/slot_equipment_priority = list( \
|
||||
// ..()
|
||||
return
|
||||
|
||||
/mob/proc/UpdateLuminosity()
|
||||
if(src.total_luminosity == src.last_luminosity) return 0//nothing to do here
|
||||
src.last_luminosity = src.total_luminosity
|
||||
sd_SetLuminosity(min(src.total_luminosity,7))//Current hardcode max at 7, should likely be a const somewhere else
|
||||
return 1
|
||||
|
||||
/mob/MouseDrop(mob/M as mob)
|
||||
..()
|
||||
@@ -520,16 +539,6 @@ var/list/slot_equipment_priority = list( \
|
||||
if(LinkBlocked(usr.loc,loc)) return
|
||||
show_inv(usr)
|
||||
|
||||
/atom/movable
|
||||
var/mob/pulledby = null
|
||||
|
||||
/atom/movable/verb/pull()
|
||||
set name = "Pull"
|
||||
set category = "IC"
|
||||
set src in oview(1)
|
||||
|
||||
usr.start_pulling(src)
|
||||
return
|
||||
|
||||
/mob/proc/stop_pulling()
|
||||
if(pulling)
|
||||
@@ -553,18 +562,6 @@ var/list/slot_equipment_priority = list( \
|
||||
else
|
||||
M.LAssailant = usr
|
||||
|
||||
/atom/verb/examine()
|
||||
set name = "Examine"
|
||||
set category = "IC"
|
||||
set src in oview(12) //make it work from farther away
|
||||
|
||||
if (!( usr ))
|
||||
return
|
||||
usr << "That's \a [src]." //changed to "That's" from "This is" because "This is some metal sheets" sounds dumb compared to "That's some metal sheets" ~Carn
|
||||
usr << desc
|
||||
// *****RM
|
||||
//usr << "[name]: Dn:[density] dir:[dir] cont:[contents] icon:[icon] is:[icon_state] loc:[loc]"
|
||||
return
|
||||
|
||||
/mob/proc/can_use_hands()
|
||||
if(handcuffed)
|
||||
@@ -850,4 +847,7 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
for(var/file in args)
|
||||
src << browse_rsc(file)
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
mob/proc/flash_weak_pain()
|
||||
flick("weak_pain",pain)
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
var/obj/screen/pressure = null
|
||||
var/obj/screen/damageoverlay = null
|
||||
|
||||
var/total_luminosity = 0 //This controls luminosity for mobs, when you pick up lights and such this is edited. If you want the mob to use lights it must update its lum in its life proc or such. Note clamp this value around 7 or such to prevent massive light lag.
|
||||
var/last_luminosity = 0
|
||||
|
||||
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
|
||||
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
|
||||
The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
|
||||
@@ -66,7 +63,7 @@
|
||||
var/ear_deaf = null //Carbon
|
||||
var/ear_damage = null //Carbon
|
||||
var/stuttering = null //Carbon
|
||||
var/slurring = null //Carbon
|
||||
var/slurring = null
|
||||
var/real_name = null
|
||||
// var/original_name = null //Original name is only used in ghost chat! Depracated, now used bb
|
||||
var/blinded = null
|
||||
@@ -85,7 +82,6 @@
|
||||
var/eye_stat = null//Living, potentially Carbon
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/flavor_text = ""
|
||||
|
||||
var/name_archive //For admin things like possession
|
||||
|
||||
@@ -126,11 +122,6 @@
|
||||
|
||||
var/seer = 0 //for cult//Carbon, probably Human
|
||||
|
||||
//skills
|
||||
var/used_skillpoints = 0
|
||||
var/skill_specialization = null
|
||||
var/list/skills = null
|
||||
|
||||
var/obj/hud/hud_used = null
|
||||
|
||||
//var/list/organs = list( ) //moved to human.
|
||||
@@ -228,6 +219,7 @@
|
||||
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
|
||||
var/robot_talk_understand = 0
|
||||
var/alien_talk_understand = 0
|
||||
var/skrell_talk_understand = 0
|
||||
var/tajaran_talk_understand = 0
|
||||
var/soghun_talk_understand = 0
|
||||
var/skrell_talk_understand = 0
|
||||
|
||||
|
||||
@@ -7,9 +7,13 @@
|
||||
var/atom/movable/structure = null // if the grab is not grabbing a mob
|
||||
var/mob/assailant = null
|
||||
var/state = 1.0
|
||||
var/killing = 0.0
|
||||
|
||||
var/killing = 0.0 // 1 = about to kill, 2 = killing
|
||||
var/kill_loc = null
|
||||
|
||||
var/allow_upgrade = 1.0
|
||||
var/last_suffocate = 1.0
|
||||
|
||||
layer = 21
|
||||
abstract = 1.0
|
||||
item_state = "nothing"
|
||||
@@ -94,7 +98,6 @@
|
||||
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
|
||||
if (G.state == 2)
|
||||
allow_upgrade = 0
|
||||
//Foreach goto(341)
|
||||
if (allow_upgrade)
|
||||
hud1.icon_state = "reinforce"
|
||||
else
|
||||
@@ -102,9 +105,15 @@
|
||||
else
|
||||
if (!( affecting.buckled ))
|
||||
affecting.loc = assailant.loc
|
||||
if ((killing && state == 3))
|
||||
affecting.Stun(5)
|
||||
affecting.Paralyse(3)
|
||||
if ((killing == 2 && state == 3))
|
||||
if(assailant.loc != kill_loc)
|
||||
for(var/mob/O in viewers(assailant, null))
|
||||
O.show_message(text("\red [] lost his tightened grip on []'s neck!", assailant, affecting), 1)
|
||||
killing = 0
|
||||
hud1.icon_state = "disarm/kill"
|
||||
return
|
||||
affecting.Weaken(3)
|
||||
affecting.Stun(3) // It will hamper your voice, being choked and all.
|
||||
affecting.losebreath = min(affecting.losebreath + 2, 3)
|
||||
return
|
||||
|
||||
@@ -112,6 +121,8 @@
|
||||
/obj/item/weapon/grab/proc/s_click(obj/screen/S as obj)
|
||||
if (!affecting)
|
||||
return
|
||||
if(killing)
|
||||
return
|
||||
if (assailant.next_move > world.time)
|
||||
return
|
||||
if ((!( assailant.canmove ) || assailant.lying))
|
||||
@@ -144,6 +155,9 @@
|
||||
if ((!( assailant.canmove ) || assailant.lying))
|
||||
del(src)
|
||||
return
|
||||
if(killing)
|
||||
return
|
||||
|
||||
switch(S.id)
|
||||
if(1.0)
|
||||
if (state < 2)
|
||||
@@ -196,9 +210,22 @@
|
||||
hud1.icon_state = "disarm/kill"
|
||||
hud1.name = "disarm/kill"
|
||||
else
|
||||
if (state >= 3)
|
||||
killing = !( killing )
|
||||
if (killing)
|
||||
if (state >= 3 && !killing)
|
||||
for(var/mob/O in viewers(assailant, null))
|
||||
O.show_message(text("\red [] starts to tighten his grip on []'s neck!", assailant, affecting), 1)
|
||||
hud1.icon_state = "disarm/kill1"
|
||||
killing = 1
|
||||
if(do_after(assailant, 50))
|
||||
if(killing == 2)
|
||||
return
|
||||
if(!affecting)
|
||||
del(src)
|
||||
return
|
||||
if ((!( assailant.canmove ) || assailant.lying))
|
||||
del(src)
|
||||
return
|
||||
killing = 2
|
||||
kill_loc = assailant.loc
|
||||
for(var/mob/O in viewers(assailant, null))
|
||||
O.show_message(text("\red [] has tightened his grip on []'s neck!", assailant, affecting), 1)
|
||||
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>")
|
||||
@@ -207,12 +234,11 @@
|
||||
|
||||
assailant.next_move = world.time + 10
|
||||
affecting.losebreath += 1
|
||||
hud1.icon_state = "disarm/kill1"
|
||||
else
|
||||
hud1.icon_state = "disarm/kill"
|
||||
for(var/mob/O in viewers(assailant, null))
|
||||
O.show_message(text("\red [] has loosened the grip on []'s neck!", assailant, affecting), 1)
|
||||
else
|
||||
O.show_message(text("\red [] was unable to tighten his grip on []'s neck!", assailant, affecting), 1)
|
||||
killing = 0
|
||||
hud1.icon_state = "disarm/kill"
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
|
||||
|
||||
spawn(60)
|
||||
spawn(30)
|
||||
if(client)
|
||||
if(!preferences.savefile_load(src, 0))
|
||||
preferences.ShowChoices(src)
|
||||
@@ -50,50 +50,49 @@
|
||||
new_player_panel()
|
||||
if(preferences.lobby_music)
|
||||
Playmusic()
|
||||
//PDA Resource Initialisation =======================================================>
|
||||
/*
|
||||
Quick note: local dream daemon instances don't seem to cache images right. Might be
|
||||
a local problem with my machine but it's annoying nontheless.
|
||||
*/
|
||||
if(client)
|
||||
//load the PDA iconset into the client
|
||||
src << browse_rsc('icons/pda_icons/pda_atmos.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_back.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_bell.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_blank.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_boom.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_bucket.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_crate.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_cuffs.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_eject.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_exit.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_flashlight.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_honk.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_mail.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_medical.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_menu.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_mule.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_notes.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_power.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_rdoor.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_reagent.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_refresh.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_scanner.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_signaler.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_status.png')
|
||||
//Loads icons for SpiderOS into client
|
||||
src << browse_rsc('icons/spideros_icons/sos_1.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_2.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_3.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_4.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_5.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_6.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_7.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_8.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_9.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_10.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_11.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_12.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_13.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_14.png')
|
||||
//PDA Resource Initialisation =======================================================>
|
||||
/*
|
||||
Quick note: local dream daemon instances don't seem to cache images right. Might be
|
||||
a local problem with my machine but it's annoying nontheless.
|
||||
*/
|
||||
//load the PDA iconset into the client
|
||||
src << browse_rsc('icons/pda_icons/pda_atmos.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_back.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_bell.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_blank.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_boom.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_bucket.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_crate.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_cuffs.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_eject.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_exit.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_flashlight.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_honk.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_mail.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_medical.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_menu.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_mule.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_notes.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_power.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_rdoor.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_reagent.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_refresh.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_scanner.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_signaler.png')
|
||||
src << browse_rsc('icons/pda_icons/pda_status.png')
|
||||
//Loads icons for SpiderOS into client
|
||||
src << browse_rsc('icons/spideros_icons/sos_1.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_2.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_3.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_4.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_5.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_6.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_7.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_8.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_9.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_10.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_11.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_12.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_13.png')
|
||||
src << browse_rsc('icons/spideros_icons/sos_14.png')
|
||||
//End PDA Resource Initialisation =====================================================>
|
||||
@@ -269,4 +269,87 @@
|
||||
new_corgi << "<B>You are now a Corgi. Yap Yap!</B>"
|
||||
spawn(0)//To prevent the proc from returning null.
|
||||
del(src)
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/Animalize()
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
|
||||
|
||||
if(bad_animal(mobpath))
|
||||
usr << "\red Sorry but this mob type is currently unavailable."
|
||||
return
|
||||
|
||||
if(monkeyizing)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
|
||||
regenerate_icons()
|
||||
monkeyizing = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
|
||||
for(var/t in organs)
|
||||
del(t)
|
||||
|
||||
var/mob/new_mob = new mobpath(src.loc)
|
||||
|
||||
new_mob.key = key
|
||||
new_mob.a_intent = "hurt"
|
||||
new_mob.UI = UI
|
||||
|
||||
|
||||
new_mob << "You suddenly feel more... animalistic."
|
||||
spawn()
|
||||
del(src)
|
||||
return
|
||||
|
||||
/mob/proc/Animalize()
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
|
||||
|
||||
if(bad_animal(mobpath))
|
||||
usr << "\red Sorry but this mob type is currently unavailable."
|
||||
return
|
||||
|
||||
var/mob/new_mob = new mobpath(src.loc)
|
||||
|
||||
new_mob.key = key
|
||||
new_mob.a_intent = "hurt"
|
||||
new_mob.UI = UI
|
||||
new_mob << "You feel more... animalistic"
|
||||
|
||||
del(src)
|
||||
|
||||
//Certain mob types either do not work, or have major problems and should now be allowed to be controlled by players.
|
||||
/mob/proc/bad_animal(var/MP)
|
||||
|
||||
//Sanity, this should never happen.
|
||||
if(!MP || !ispath(MP, /mob/living/simple_animal))
|
||||
return 1
|
||||
|
||||
//It is impossible to pull up the player panel for mice
|
||||
if(ispath(MP, /mob/living/simple_animal/mouse))
|
||||
return 1
|
||||
|
||||
//Bears will auto-attack mobs, even if they're player controlled
|
||||
if(ispath(MP, /mob/living/simple_animal/bear))
|
||||
return 1
|
||||
|
||||
//Parrots are unfinished, they have no sprite, movement, ect...
|
||||
else if(ispath(MP, /mob/living/simple_animal/parrot))
|
||||
return 1
|
||||
|
||||
//Very buggy, they seem to just spawn additional space worms everywhere and eating your own tail results in new worms spawning.
|
||||
else if(ispath(MP, /mob/living/simple_animal/space_worm))
|
||||
return 1
|
||||
|
||||
//No problems found!
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/* Pens!
|
||||
* Contains:
|
||||
* Pens
|
||||
* Sleepy Pens
|
||||
* Parapens
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Pens
|
||||
*/
|
||||
/obj/item/weapon/pen
|
||||
desc = "It's a normal black ink pen."
|
||||
name = "pen"
|
||||
@@ -32,4 +43,69 @@
|
||||
/obj/item/weapon/pen/invisble
|
||||
desc = "It's an invisble pen marker."
|
||||
icon_state = "pen"
|
||||
colour = "white"
|
||||
colour = "white"
|
||||
|
||||
|
||||
/obj/item/weapon/pen/attack(mob/M as mob, mob/user as mob)
|
||||
if(!ismob(M))
|
||||
return
|
||||
user << "\red You stab [M] with the pen."
|
||||
M << "\red You feel a tiny prick!"
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been stabbed with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to stab [M.name] ([M.ckey])</font>")
|
||||
|
||||
log_attack("<font color='red'>[user.name] ([user.ckey]) Used the [src.name] to stab [M.name] ([M.ckey])</font>")
|
||||
return
|
||||
|
||||
/*
|
||||
* Sleepy Pens
|
||||
*/
|
||||
/obj/item/weapon/pen/sleepypen
|
||||
origin_tech = "syndicate=5"
|
||||
|
||||
/obj/item/weapon/pen/sleepypen/attack_paw(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/pen/sleepypen/New()
|
||||
var/datum/reagents/R = new/datum/reagents(30) //Used to be 300
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("chloralhydrate", 22) //Used to be 100 sleep toxin//30 Chloral seems to be fatal, reducing it to 22./N
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/pen/sleepypen/attack(mob/M as mob, mob/user as mob)
|
||||
if(!(istype(M,/mob)))
|
||||
return
|
||||
..()
|
||||
if(reagents.total_volume)
|
||||
if(M.reagents) reagents.trans_to(M, 50) //used to be 150
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
* Parapens
|
||||
*/
|
||||
|
||||
/obj/item/weapon/pen/paralysis/attack_paw(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/pen/paralysis/attack(mob/M as mob, mob/user as mob)
|
||||
if(!(istype(M,/mob)))
|
||||
return
|
||||
..()
|
||||
if(reagents.total_volume)
|
||||
if(M.reagents) reagents.trans_to(M, 50)
|
||||
return
|
||||
|
||||
/obj/item/weapon/pen/paralysis/New()
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("zombiepowder", 10)
|
||||
R.add_reagent("impedrezene", 25)
|
||||
R.add_reagent("cryptobiolin", 15)
|
||||
..()
|
||||
return
|
||||
@@ -52,4 +52,8 @@
|
||||
/obj/item/weapon/stamp/clown
|
||||
name = "clown's rubber stamp"
|
||||
icon_state = "stamp-clown"
|
||||
color = "clown"
|
||||
color = "clown"
|
||||
|
||||
|
||||
/obj/item/weapon/stamp/attack_paw(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
@@ -177,7 +177,7 @@
|
||||
// update the APC icon to show the three base states
|
||||
// also add overlays for indicator lights
|
||||
/obj/machinery/power/apc/proc/updateicon()
|
||||
src.overlays = null
|
||||
overlays.Cut()
|
||||
if(opened)
|
||||
var/basestate = "apc[ cell ? "2" : "1" ]" // if opened, show cell if it's inserted
|
||||
if (opened==1)
|
||||
@@ -199,13 +199,10 @@
|
||||
else
|
||||
icon_state = "apc0"
|
||||
// if closed, update overlays for channel status
|
||||
if (!(stat & (BROKEN|MAINT)))
|
||||
overlays += image('icons/obj/power.dmi', "apcox-[locked]") // 0=blue 1=red
|
||||
overlays += image('icons/obj/power.dmi', "apco3-[charging]") // 0=red, 1=yellow/black 2=green
|
||||
if(!(stat & (BROKEN|MAINT)))
|
||||
overlays.Add("apcox-[locked]","apco3-[charging]") // 0=blue 1=red // 0=red, 1=yellow/black 2=green
|
||||
if(operating)
|
||||
overlays += image('icons/obj/power.dmi', "apco0-[equipment]") // 0=red, 1=green, 2=blue
|
||||
overlays += image('icons/obj/power.dmi', "apco1-[lighting]")
|
||||
overlays += image('icons/obj/power.dmi', "apco2-[environ]")
|
||||
overlays.Add("apco0-[equipment]","apco1-[lighting]","apco2-[environ]") // 0=red, 1=green, 2=blue
|
||||
|
||||
//attack with an item - open/close cover, insert cell, or (un)lock interface
|
||||
|
||||
@@ -744,6 +741,8 @@
|
||||
if (user.stat)
|
||||
user << "\red You must be conscious to use this [src]!"
|
||||
return 0
|
||||
if(!user.client)
|
||||
return 0
|
||||
if ( ! (istype(user, /mob/living/carbon/human) || \
|
||||
istype(user, /mob/living/silicon) || \
|
||||
istype(user, /mob/living/carbon/monkey) /*&& ticker && ticker.mode.name == "monkey"*/) )
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
icon_state = "bulb1"
|
||||
base_state = "bulb"
|
||||
fitting = "bulb"
|
||||
brightness = 3
|
||||
brightness = 4
|
||||
desc = "A small lighting fixture."
|
||||
light_type = /obj/item/weapon/light/bulb
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
name = "spotlight"
|
||||
fitting = "large tube"
|
||||
light_type = /obj/item/weapon/light/tube/large
|
||||
brightness = 15
|
||||
brightness = 12
|
||||
|
||||
/obj/machinery/light/built/New()
|
||||
status = LIGHT_EMPTY
|
||||
@@ -280,34 +280,28 @@
|
||||
/obj/machinery/light/proc/update(var/trigger = 1)
|
||||
|
||||
update_icon()
|
||||
if(!on)
|
||||
use_power = 1
|
||||
if(on)
|
||||
if(luminosity != brightness)
|
||||
switchcount++
|
||||
if(rigged)
|
||||
if(status == LIGHT_OK && trigger)
|
||||
explode()
|
||||
else if( prob( min(60, switchcount*switchcount*0.01) ) )
|
||||
if(status == LIGHT_OK && trigger)
|
||||
status = LIGHT_BURNED
|
||||
icon_state = "[base_state]-burned"
|
||||
on = 0
|
||||
SetLuminosity(0)
|
||||
else
|
||||
use_power = 2
|
||||
SetLuminosity(brightness)
|
||||
else
|
||||
use_power = 2
|
||||
var/oldlum = luminosity
|
||||
use_power = 1
|
||||
SetLuminosity(0)
|
||||
|
||||
//luminosity = on * brightness
|
||||
sd_SetLuminosity(on * brightness) // *DAL*
|
||||
|
||||
// if the state changed, inc the switching counter
|
||||
if(oldlum != luminosity)
|
||||
switchcount++
|
||||
|
||||
// now check to see if the bulb is burned out
|
||||
if(status == LIGHT_OK && trigger)
|
||||
if(on && rigged)
|
||||
explode()
|
||||
if( prob( min(60, switchcount*switchcount*0.01) ) )
|
||||
status = LIGHT_BURNED
|
||||
icon_state = "[base_state]-burned"
|
||||
on = 0
|
||||
sd_SetLuminosity(0)
|
||||
active_power_usage = (luminosity * 20)
|
||||
active_power_usage = (luminosity * 10)
|
||||
if(on != on_gs)
|
||||
on_gs = on
|
||||
// var/area/A = get_area(src)
|
||||
// if(A)
|
||||
// A.update_lights()
|
||||
|
||||
|
||||
// attempt to set the light's on/off status
|
||||
|
||||
@@ -1,596 +0,0 @@
|
||||
/* Overview of sd_DynamicAreaLighting as modified for SS13
|
||||
*
|
||||
*
|
||||
* Use sd_SetLuminosity(value) to change the luminosity of an atom
|
||||
* rather than setting the luminosity var directly.
|
||||
* Avoid having luminous objects at compile-time since this can mess up
|
||||
* the lighting system during map load. Instead use sd_SetLuminosity() in
|
||||
* the atom's New() proc after a small spawn delay.
|
||||
*
|
||||
* Use sd_SetOpacity(value) to change the opacity of an atom (e.g. doors)
|
||||
* rather than setting the opacity var directly. This ensures that lighting
|
||||
* will be blocked/unblocked as necessary.
|
||||
*
|
||||
* If creating a new opaque atom (e.g. a wall) at runtime, create the atom,
|
||||
* set its opacity var to zero, then perform sd_SetOpacity(1)
|
||||
* e.g.:
|
||||
*
|
||||
* var/obj/block/B = new(loc)
|
||||
* B.opacity = 0
|
||||
* B.sd_SetOpacity(1)
|
||||
*
|
||||
*
|
||||
* The library creates multiple instances of each /area to split a mapped area
|
||||
* into different lighting levels. Each area created has a "master" variable
|
||||
* which is a reference to the original un-split area, and a "related" variable
|
||||
* which is a reference to the list of split areas.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************************\
|
||||
sd_DynamicAreaLighting.dm
|
||||
Shadowdarke (shadowdarke@hotmail.com)
|
||||
December 12, 2002
|
||||
|
||||
The sd_DynamicAreaLighting library provides dynamic lighting
|
||||
with minimal cpu and bandwidth usage by shifting turfs between
|
||||
five areas which represent varying shades of darkness.
|
||||
|
||||
**********************************************************************
|
||||
Using sd_DynamicAreaLighting
|
||||
|
||||
This library uses BYOND's built in luminousity variable. In most
|
||||
cases, all you have to do is set luminosity and let the library
|
||||
worry about the work.
|
||||
|
||||
There are three cases that the library does not automatically
|
||||
compensate for, so you will need to use library procs:
|
||||
|
||||
1) Luminosity changes at run time.
|
||||
If your program makes changes in luminosity while it is
|
||||
running, you need to use sd_SetLuminosity(new_luminosity)
|
||||
so the library can remove the effect of the old luminosity
|
||||
and apply the new effect.
|
||||
|
||||
2) Opacity changes at run time.
|
||||
As with luminosity changes, you need to use
|
||||
sd_SetOpacity(new_opacity) if your program changes the opacity
|
||||
of atoms at runtime.
|
||||
|
||||
3) New atoms that change the opacity of a location.
|
||||
This is somewhat more complex, and the library doesn't
|
||||
have a simple proc to take care of it yet. You should use
|
||||
sd_StripLocalLum() to strip the luminosity effect of
|
||||
anything shining on that space, create the new atom, then
|
||||
use sd_ApplyLocalLum() to reapply the luminosity effect.
|
||||
Examine the sd_SetOpacity() proc for an example of the
|
||||
procedure.
|
||||
|
||||
All areas will automatically use the sd_DynamicAreaLighting
|
||||
library when it is included in your project. You may disable
|
||||
lighting effect in an area by specifically setting the area's
|
||||
sd_lighting var to 0. For example:
|
||||
|
||||
area/always_lit
|
||||
luminosity = 1
|
||||
sd_lighting = 0
|
||||
|
||||
This library chops areas into 5 separate areas of differing
|
||||
light effect, so you may want to modify area Enter(), Exit(),
|
||||
Entered(), and Exited() procs to make sure the atom has moved
|
||||
from a different area instead of a different light zone of the
|
||||
same area.
|
||||
|
||||
IMPORTANT NOTE: Since sd_DynamicAreaLighting uses the view()
|
||||
proc, large luminosity settings may cause strange effect. You
|
||||
should limit luminosity to (world.view * 2) or less.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
CUSTOM DARKNESS ICONS
|
||||
sd_DynamicAreaLighting was designed in a barbaric age when BYOND
|
||||
did not support alpha transperency. Thankfully that age is over.
|
||||
I left the old icon as the default, since not everyone has
|
||||
upgraded to BYOND 4.0 or in some cases like software graphics
|
||||
mode, in which case the old dithered icon is the better choice.
|
||||
|
||||
The dithered icon used 4 standard dithers for the darkness shades
|
||||
and I saw little reason to allow variation. Starting with sd_DAL
|
||||
version 10, the library can support more or less shades of
|
||||
darkness as well.
|
||||
|
||||
To change the icon and/or number of shades of darkness for your
|
||||
game, just call the sd_SetDarkIcon(dark_icon, num_shades) proc,
|
||||
where dark_icon is the new icon and num_shades is the number of
|
||||
shades of darkness in the icon. This is best done in the
|
||||
world.New() proc, to set it once for the entire game instance.
|
||||
|
||||
For example, to make the included 7 shade alpha transparency icon
|
||||
your game's darkness icon, use the following code in your game.
|
||||
|
||||
world
|
||||
New()
|
||||
..()
|
||||
sd_SetDarkIcon('sd_dark_alpha7.dmi', 7)
|
||||
|
||||
There are several demo icons included with this library:
|
||||
sd_darkstates.dmi - the original 4 shade dithered icon
|
||||
sd_dark_dither3.dmi - 3 shade dithered icon
|
||||
sd_dark_alpha4.dmi - 4 shade alpha transparency icon
|
||||
sd_dark_alpha4b.dmi - lighter version 4 shade alpha
|
||||
transparency icon
|
||||
sd_dark_alpha7.dmi - 7 shade alpha transparency icon
|
||||
|
||||
If you want to design your own custom darkness icons, they
|
||||
have to follow a specific format for the library to use them
|
||||
properly. The shades of darkness should have be numbered from 0
|
||||
as the darkest shade to the number of shades minus one as the
|
||||
lightest shade.
|
||||
|
||||
For example, the four shade 4 shade transparent icon
|
||||
sd_dark_alpha4.dmi has 4 icon states:
|
||||
"0" is black with 204 alpha (80% darkness)
|
||||
"1" is black with 153 alpha (60% darkness)
|
||||
"2" is black with 102 alpha (40% darkness)
|
||||
"3" is black with 51 alpha (20% darkness)
|
||||
|
||||
|
||||
The lightest shade ("3" in this case) is NOT completely clear.
|
||||
There will be no darkness overlay for completely lit areas. The
|
||||
lightest shade will only be used for places that are just beginning
|
||||
to get dark.
|
||||
|
||||
The darkest shade ("0") likewise is not 100% obscured. "0" will
|
||||
be used in completely dark areas, but by leaving it slightly
|
||||
transparent, characters will be able to barely make out their
|
||||
immediate surroundings in the darkness (based on the mob
|
||||
see_in_dark var.) You might prefer to lighten the darkness for
|
||||
this purpose, like in demo icon sd_dark_alpha4b.dmi.
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
DAY/NIGHT CYCLES
|
||||
|
||||
sd_DynamicAreaLighting allows for separate indoor and outdoor
|
||||
lighting. Areas used for outdoor light cycles should be
|
||||
designated by setting the area's sd_outside var to 1. For example:
|
||||
|
||||
area/outside
|
||||
sd_outside = 1
|
||||
|
||||
You will need to write your own routine for the day/night
|
||||
cycle so that you can control the timing and degree of lighting
|
||||
changes. There is an example routine in lightingdemo.dm.
|
||||
|
||||
After your routine determines the amount of light outdoors,
|
||||
call sd_OutsideLight(light_level) to update the light levels in
|
||||
all outside areas. light_level should be a value from 0 to
|
||||
sd_dark_shades, where 0 is darkest and sd_dark_shades is full
|
||||
light.
|
||||
|
||||
The sd_OutsideLight() proc does not automatically detect a
|
||||
range out of bounds in case you want to use nonstandard values
|
||||
for interesting effect. For instance, you could use a negative
|
||||
value to dampen light sources.
|
||||
|
||||
If you want daylight to spill indoors:
|
||||
|
||||
You will need to add turfs to sd_light_spill_turfs. The
|
||||
library will automatically add any turf created with
|
||||
sd_light_spill set, or you may add the turfs yourself at
|
||||
runtime.
|
||||
|
||||
The turfs in this list act as a source of daylight, shining
|
||||
into the any areas that are not flagged with sd_outside.
|
||||
|
||||
**********************************************************************
|
||||
LIBRARY PROCS:
|
||||
Except in the cases noted above, you shouldn't need to use the procs
|
||||
in this library. This reference is provided for advanced users.
|
||||
|
||||
Global vars and procs:
|
||||
var
|
||||
sd_dark_icon
|
||||
This is the icon used for the darkness in your world.
|
||||
DEFAULT VALUE: 'sd_darkstates.dmi' (A dithered icon
|
||||
designed for BYOND releases before 4.0.)
|
||||
|
||||
sd_dark_shades
|
||||
The number of darkness icon states in your sd_dark_icon.
|
||||
DEFAULT VALUE: 4
|
||||
|
||||
sd_light_layer
|
||||
The graphic layer that darkness overlays appear on.
|
||||
This should be higher than anything on the map, but
|
||||
lower than any HUD displays.
|
||||
DEFAULT VALUE: 50
|
||||
|
||||
sd_light_outside
|
||||
This var is how bright it currently is outside. It
|
||||
should be a number between 0 and sd_dark_shades.
|
||||
DEFAULT VALUE: 0
|
||||
|
||||
sd_top_luminosity
|
||||
keeps track of the highest luminosity in the world to
|
||||
prevent getting larger lists than necessary.
|
||||
|
||||
list/sd_outside
|
||||
A list of outside areas.
|
||||
|
||||
list/sd_light_spill_turfs
|
||||
A list of turfs where light spills from outside areas into
|
||||
inside areas.
|
||||
|
||||
proc/sd_OutsideLight(n as num)
|
||||
Changes the level of light outside (sd_light_outside) to n
|
||||
and updates all the atoms in sd_outside.
|
||||
|
||||
proc/sd_SetDarkIcon(icon, shades)
|
||||
Changes the darkness icon and the number shades of darkness
|
||||
in that icon.
|
||||
|
||||
All atoms have the following procs:
|
||||
sd_ApplyLum(list/V = view(luminosity,src), center = src)
|
||||
This proc adds a value to the sd_lumcount of all the
|
||||
turfs in V, depending on src.luminosity and the
|
||||
distance between the turf and center.
|
||||
|
||||
sd_StripLum(list/V = view(luminosity,src), center = src)
|
||||
The reverse of sd_ApplyLum(), sd_StripLum removes luminosity
|
||||
effect.
|
||||
|
||||
sd_ApplyLocalLum(list/affected = viewers(20,src))
|
||||
Applies the lighting effect of all atoms in affected. This
|
||||
proc is used with sd_StripLocalLum() for effect that may
|
||||
change the opacity of a turf.
|
||||
|
||||
sd_StripLocalLum()
|
||||
Strips effect of all local luminous atoms.
|
||||
RETURNS: list of all the luminous atoms stripped
|
||||
IMPORTANT! Each sd_StripLocalLum() call should have a matching
|
||||
sd_ApplyLocalLum() to restore the local effect.
|
||||
|
||||
sd_SetLuminosity(new_luminosity as num)
|
||||
Sets the atom's luminosity, making adjustments to the
|
||||
sd_lumcount of local turfs.
|
||||
|
||||
sd_SetOpacity(new_opacity as num)
|
||||
Sets the atom's opacity, making adjustments to the
|
||||
sd_lumcount of local turfs.
|
||||
|
||||
Areas have one additional proc and 4 variables:
|
||||
var
|
||||
sd_lighting
|
||||
Turn this flag off to prevent sd_DynamicAreaLighting
|
||||
from effecting this area.
|
||||
DEFAULT VALUE: 1 (allow dynamic lighting)
|
||||
|
||||
sd_outside
|
||||
Set this flag to automatically add this area to the
|
||||
list of outside areas.
|
||||
DEAFAULT VALUE: 0 (not an outside area)
|
||||
|
||||
sd_light_level
|
||||
The current light level of the area. You should use
|
||||
the sd_LightLevel() proc to set this value, so the
|
||||
darkness overlays will be changed as well.
|
||||
DEFAULT VALUE: 0
|
||||
|
||||
sd_darkimage
|
||||
Tracks the darkness image of the area for easy
|
||||
removal in the sd_LightLevel() proc
|
||||
|
||||
proc
|
||||
sd_LightLevel(level = sd_light_level as num,keep = 1)
|
||||
Updates the darkness overlay of the area.
|
||||
If keep = 1, it also updates the area's
|
||||
sd_light_level var.
|
||||
|
||||
Turfs have these additional procs and vars:
|
||||
var
|
||||
sd_lumcount
|
||||
Used to track the brightness of a turf.
|
||||
|
||||
sd_light_spill
|
||||
If set, the turf will automatically be added to the
|
||||
global list sd_light_spill_turfs when created.
|
||||
DEFAULT VALUE: 0
|
||||
|
||||
proc
|
||||
sd_LumUpdate()
|
||||
Places the turf in the appropriate sd_dark area,
|
||||
depending on its brightness (sd_lumcount).
|
||||
|
||||
sd_LumReset()
|
||||
Resets a turf's lumcount by stripping local luminosity,
|
||||
zeroing the lumcount, then reapplying local luminosity.
|
||||
|
||||
sd_ApplySpill()
|
||||
Applies to effect of daylight spilling into inside
|
||||
areas in view of this turf.
|
||||
|
||||
sd_StripSpill()
|
||||
Removes to effect of daylight spilling into inside
|
||||
areas in view of this turf.
|
||||
|
||||
\********************************************************************/
|
||||
|
||||
var/const/sd_dark_icon = 'icons/effects/ss13_dark_alpha7.dmi' // icon used for darkness
|
||||
var/const/sd_dark_shades = 7 // number of icon state in sd_dark_icon
|
||||
var/const/sd_light_layer = 10 // graphics layer for light effect
|
||||
var/sd_top_luminosity = 0
|
||||
|
||||
// since we're not using these, comment out all occurances to save CPU
|
||||
/*
|
||||
list
|
||||
sd_outside_areas = list() // list of outside areas
|
||||
sd_light_spill_turfs = list() // list of turfs to calculate light spill from
|
||||
*/
|
||||
|
||||
// slog = file("DALlog.txt")
|
||||
|
||||
/*
|
||||
proc
|
||||
sd_OutsideLight(n as num)
|
||||
// set the brightness of the outside sunlight
|
||||
if(sd_light_outside == n) return // same level, no update
|
||||
if(sd_light_outside)
|
||||
for(var/turf/T in sd_light_spill_turfs)
|
||||
T.sd_StripSpill()
|
||||
sd_light_outside = n
|
||||
|
||||
// make all the outside areas update themselves
|
||||
for(var/area/A in sd_outside_areas)
|
||||
A.sd_LightLevel(sd_light_outside + A.sd_light_level,0)
|
||||
if(n)
|
||||
for(var/turf/T in sd_light_spill_turfs)
|
||||
T.sd_ApplySpill()
|
||||
*/
|
||||
/*
|
||||
proc/sd_SetDarkIcon(icon, shades)
|
||||
// reset the darkness icon and number of shades of darkness
|
||||
sd_dark_icon = icon
|
||||
sd_dark_shades = shades
|
||||
// change existing areas
|
||||
for(var/area/A)
|
||||
if(A.sd_darkimage) A.sd_LightLevel(A.sd_light_level,0)
|
||||
*/
|
||||
|
||||
atom/New()
|
||||
..()
|
||||
// if this is not an area and is luminous
|
||||
if(!isarea(src)&&(luminosity>0))
|
||||
spawn(1) // delay to allow map load
|
||||
sd_ApplyLum()
|
||||
|
||||
atom/Del()
|
||||
// if this is not an area and is luminous
|
||||
if(!isarea(src)&&(luminosity>0))
|
||||
sd_StripLum()
|
||||
..()
|
||||
|
||||
atom/proc/sd_ApplyLum(list/V = view(luminosity,src), center = src)
|
||||
if(src.luminosity>sd_top_luminosity)
|
||||
sd_top_luminosity = src.luminosity
|
||||
// loop through all the turfs in V
|
||||
for(var/turf/T in V)
|
||||
/* increase the turf's brightness depending on the
|
||||
brightness and distance of the lightsource */
|
||||
T.sd_lumcount += (luminosity-get_dist(center,T))
|
||||
T.sd_LumUpdate()
|
||||
|
||||
atom/proc/sd_StripLum(list/V = view(luminosity,src), center = src)
|
||||
// loop through all the turfs in V
|
||||
for(var/turf/T in V)
|
||||
/* increase the turf's brightness depending on the
|
||||
brightness and distance of the lightsource */
|
||||
T.sd_lumcount -= (luminosity-get_dist(center,T))
|
||||
// T.sd_lumcount = max(0, T.sd_lumcount)
|
||||
// update the turf's area
|
||||
T.sd_LumUpdate()
|
||||
|
||||
atom/proc/sd_ApplyLocalLum(list/affected = view(sd_top_luminosity,src))
|
||||
// Reapplies the lighting effect of all atoms in affected.
|
||||
for(var/atom/A in affected)
|
||||
if(A.luminosity) A.sd_ApplyLum()
|
||||
|
||||
atom/proc/sd_StripLocalLum()
|
||||
/* strips all local luminosity
|
||||
|
||||
RETURNS: list of all the luminous atoms stripped
|
||||
|
||||
IMPORTANT! Each sd_StripLocalLum() call should have a matching
|
||||
sd_ApplyLocalLum() to restore the local effect. */
|
||||
var/list/affected = list()
|
||||
for(var/atom/A in view(sd_top_luminosity,src))
|
||||
var/turfflag = (isturf(src)?1:0)
|
||||
if(A.luminosity && (get_dist(src,A) <= A.luminosity + turfflag))
|
||||
A.sd_StripLum()
|
||||
affected += A
|
||||
return affected
|
||||
|
||||
atom/proc/sd_SetLuminosity(new_luminosity as num)
|
||||
/* This proc should be called everytime you want to change the
|
||||
luminosity of an atom instead of setting it directly.
|
||||
|
||||
new_luminosity is the new value for luminosity. */
|
||||
if(luminosity>0)
|
||||
sd_StripLum()
|
||||
luminosity = new_luminosity
|
||||
if(luminosity>0)
|
||||
sd_ApplyLum()
|
||||
|
||||
|
||||
atom/proc/sd_SetOpacity(new_opacity as num)
|
||||
if(opacity == (new_opacity ? 1 : 0)) return
|
||||
|
||||
var/list/affected = new
|
||||
var/atom/A
|
||||
var/turf/T
|
||||
var/turf/ATurf
|
||||
|
||||
for(A in range(sd_top_luminosity,src))
|
||||
T = A
|
||||
while(T && !istype(T)) T = T.loc
|
||||
if(T)
|
||||
var/list/V = view(A.luminosity,T)
|
||||
if(!(src in V)) continue
|
||||
var/turfflag = 0
|
||||
if(A == T) turfflag = 1
|
||||
if(A.luminosity && get_dist(A,src)<=A.luminosity+turfflag)
|
||||
affected[A] = V
|
||||
opacity = new_opacity
|
||||
if(opacity)
|
||||
for(A in affected)
|
||||
ATurf = A
|
||||
while(ATurf && !istype(ATurf)) ATurf = ATurf.loc
|
||||
if(ATurf)
|
||||
for(T in affected[A]-view(A.luminosity, ATurf))
|
||||
T.sd_lumcount -= (A.luminosity-get_dist(A,T))
|
||||
// T.sd_lumcount = max(0, T.sd_lumcount)
|
||||
T.sd_LumUpdate()
|
||||
|
||||
|
||||
else
|
||||
for(A in affected)
|
||||
ATurf = A
|
||||
while(ATurf && !istype(ATurf)) ATurf = ATurf.loc
|
||||
if(ATurf)
|
||||
for(T in view(A.luminosity, ATurf) - affected[A])
|
||||
T.sd_lumcount += (A.luminosity-get_dist(A,T))
|
||||
T.sd_LumUpdate()
|
||||
|
||||
///
|
||||
|
||||
atom/proc/sd_NewOpacity(var/new_opacity)
|
||||
if(opacity != new_opacity)
|
||||
var/list/affected = sd_StripLocalLum()
|
||||
opacity = new_opacity
|
||||
var/atom/T = src
|
||||
while(T && !isturf(T))
|
||||
T = T.loc
|
||||
if(T)
|
||||
T:sd_lumcount = 0
|
||||
|
||||
sd_ApplyLocalLum(affected)
|
||||
|
||||
///
|
||||
|
||||
turf
|
||||
var/tmp/sd_lumcount = 0 // the brightness of the turf
|
||||
|
||||
|
||||
turf/proc/sd_LumReset()
|
||||
/* Clear local lum, reset this turf's sd_lumcount, and
|
||||
re-apply local lum*/
|
||||
var/list/affected = sd_StripLocalLum()
|
||||
sd_lumcount = 0
|
||||
sd_ApplyLocalLum(affected)
|
||||
|
||||
turf/proc/sd_LumUpdate()
|
||||
set background = 1
|
||||
var/area/Loc = loc
|
||||
if(!istype(Loc) || !Loc.sd_lighting) return
|
||||
|
||||
// change the turf's area depending on its brightness
|
||||
// restrict light to valid levels
|
||||
var/light = min(max(sd_lumcount,0),sd_dark_shades)
|
||||
var/ltag = copytext(Loc.tag,1,findtext(Loc.tag,"sd_L")) + "sd_L[light]"
|
||||
|
||||
if(Loc.tag!=ltag) //skip if already in this area
|
||||
var/area/A = locate(ltag) // find an appropriate area
|
||||
if(!A)
|
||||
A = new Loc.type() // create area if it wasn't found
|
||||
// replicate vars
|
||||
for(var/V in Loc.vars-"contents")
|
||||
if(issaved(Loc.vars[V])) A.vars[V] = Loc.vars[V]
|
||||
|
||||
A.tag = ltag
|
||||
A.sd_LightLevel(light)
|
||||
|
||||
A.contents += src // move the turf into the area
|
||||
|
||||
atom/movable/Move() // when something moves
|
||||
|
||||
var/turf/oldloc = loc // remember for range calculations
|
||||
// list turfs in view and luminosity range of old loc
|
||||
var/list/oldview
|
||||
if(luminosity>0) // if atom is luminous
|
||||
if(isturf(loc))
|
||||
oldview = view(luminosity,loc)
|
||||
else
|
||||
oldview = list()
|
||||
|
||||
. = ..()
|
||||
|
||||
if(.&&(luminosity>0)) // if the atom actually moved
|
||||
if(istype(oldloc))
|
||||
sd_StripLum(oldview,oldloc)
|
||||
oldloc.sd_lumcount++ // correct "off by 1" error in oldloc
|
||||
sd_ApplyLum()
|
||||
|
||||
area
|
||||
var/sd_lighting = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area
|
||||
var/sd_light_level = 0 //This is the current light level of the area
|
||||
var/sd_darkimage //This tracks the darkness image of the area for easy removal
|
||||
|
||||
|
||||
area/proc/sd_LightLevel(slevel = sd_light_level as num, keep = 1)
|
||||
if(!src) return
|
||||
overlays -= sd_darkimage
|
||||
|
||||
if(keep) sd_light_level = slevel
|
||||
|
||||
// slevel = min(max(slevel,0),sd_dark_shades) // restrict range
|
||||
|
||||
if(slevel > 0)
|
||||
luminosity = 1
|
||||
else
|
||||
luminosity = 0
|
||||
|
||||
sd_darkimage = image(sd_dark_icon,,num2text(slevel),sd_light_layer)
|
||||
overlays += sd_darkimage
|
||||
|
||||
area/proc/sd_New(sd_created)
|
||||
|
||||
if(!tag) tag = "[type]"
|
||||
spawn(1) // wait a tick
|
||||
if(sd_lighting)
|
||||
// see if this area was created by the library
|
||||
if(!sd_created)
|
||||
/* show the dark overlay so areas outside of luminous regions
|
||||
won't be bright as day when they should be dark. */
|
||||
sd_LightLevel()
|
||||
|
||||
area/Del()
|
||||
..()
|
||||
related -= src
|
||||
|
||||
|
||||
/* extend the mob procs to compensate for sight settings. */
|
||||
mob/sd_ApplyLum(list/V, center = src)
|
||||
if(!V)
|
||||
if(isturf(loc))
|
||||
V = view(luminosity,loc)
|
||||
else
|
||||
V = view(luminosity,get_turf(src))
|
||||
. = ..(V, center)
|
||||
|
||||
mob/sd_StripLum(list/V, center = src)
|
||||
if(!V)
|
||||
if(isturf(loc))
|
||||
V = view(luminosity,loc)
|
||||
else
|
||||
V = view(luminosity,get_turf(src))
|
||||
. = ..(V, center)
|
||||
|
||||
mob/sd_ApplyLocalLum(list/affected)
|
||||
if(!affected)
|
||||
if(isturf(loc))
|
||||
affected = view(sd_top_luminosity,loc)
|
||||
else
|
||||
affected = view(sd_top_luminosity,src)
|
||||
. = ..(affected)
|
||||
@@ -9,15 +9,11 @@
|
||||
density = 0
|
||||
unacidable = 1
|
||||
use_power = 0
|
||||
luminosity = 4
|
||||
var/obj/machinery/field_generator/FG1 = null
|
||||
var/obj/machinery/field_generator/FG2 = null
|
||||
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
|
||||
|
||||
/obj/machinery/containment_field/New()
|
||||
spawn(1)
|
||||
src.sd_SetLuminosity(5)
|
||||
|
||||
|
||||
/obj/machinery/containment_field/Del()
|
||||
if(FG1 && !FG1.clean_up)
|
||||
FG1.cleanup()
|
||||
|
||||
@@ -13,6 +13,7 @@ var/global/list/uneatable = list(
|
||||
anchored = 1
|
||||
density = 1
|
||||
layer = 6
|
||||
luminosity = 6
|
||||
unacidable = 1 //Don't comment this out.
|
||||
use_power = 0
|
||||
var/current_size = 1
|
||||
@@ -279,7 +280,7 @@ var/global/list/uneatable = list(
|
||||
continue
|
||||
if(O.invisibility == 101)
|
||||
src.consume(O)
|
||||
A:ReplaceWithSpace()
|
||||
T.ReplaceWithSpace()
|
||||
gain = 2
|
||||
src.energy += gain
|
||||
return
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
obj/item/weapon/gun/energy/staff
|
||||
name = "staff of change"
|
||||
desc = "an artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
|
||||
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "staffofchange"
|
||||
item_state = "staffofchange"
|
||||
@@ -66,7 +66,7 @@ obj/item/weapon/gun/energy/staff
|
||||
name = "floral somatoray"
|
||||
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
|
||||
icon_state = "floramut100"
|
||||
item_state = "gun"
|
||||
item_state = "obj/item/gun.dmi"
|
||||
fire_sound = 'sound/effects/stealthoff.ogg'
|
||||
charge_cost = 100
|
||||
projectile_type = "/obj/item/projectile/energy/floramut"
|
||||
@@ -109,4 +109,45 @@ obj/item/weapon/gun/energy/staff
|
||||
projectile_type = "/obj/item/projectile/energy/floramut"
|
||||
modifystate = "floramut"
|
||||
update_icon()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun
|
||||
name = "meteor gun"
|
||||
desc = "For the love of god, make sure you're aiming this the right way!"
|
||||
icon_state = "riotgun"
|
||||
item_state = "c20r"
|
||||
w_class = 4
|
||||
projectile_type = "/obj/item/projectile/meteor"
|
||||
charge_cost = 100
|
||||
cell_type = "/obj/item/weapon/cell/potato"
|
||||
clumsy_check = 0 //Admin spawn only, might as well let clowns use it.
|
||||
var/charge_tick = 0
|
||||
var/recharge_time = 5 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
|
||||
Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
process()
|
||||
charge_tick++
|
||||
if(charge_tick < recharge_time) return 0
|
||||
charge_tick = 0
|
||||
if(!power_supply) return 0
|
||||
power_supply.give(100)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/meteorgun/pen
|
||||
name = "meteor pen"
|
||||
desc = "The pen is mightier than the sword."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "pen"
|
||||
item_state = "pen"
|
||||
w_class = 1
|
||||
@@ -17,7 +17,7 @@
|
||||
projectile_type = "/obj/item/projectile/energy/electrode"
|
||||
cell_type = "/obj/item/weapon/cell/secborg"
|
||||
var/charge_tick = 0
|
||||
var/recharge_time = 10 //Time it takes for shots to recharge (in seconds)
|
||||
var/recharge_time = 10 //Time it takes for shots to recharge (in ticks)
|
||||
|
||||
New()
|
||||
..()
|
||||
@@ -28,7 +28,7 @@
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
process() //Every [recharge_time] seconds, recharge a shot for the cyborg
|
||||
process() //Every [recharge_time] ticks, recharge a shot for the cyborg
|
||||
charge_tick++
|
||||
if(charge_tick < recharge_time) return 0
|
||||
charge_tick = 0
|
||||
|
||||
@@ -105,6 +105,10 @@
|
||||
|
||||
/obj/item/weapon/gun/projectile/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj)
|
||||
|
||||
if(!loaded.len)
|
||||
user.visible_message("\red *click*", "\red *click*")
|
||||
return
|
||||
|
||||
if(isliving(target) && isliving(user))
|
||||
if(target == user)
|
||||
var/datum/organ/external/affecting = user.zone_sel.selecting
|
||||
|
||||
@@ -39,6 +39,36 @@
|
||||
M.bodytemperature = temperature
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/meteor
|
||||
name = "meteor"
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "smallf"
|
||||
damage = 0
|
||||
damage_type = BRUTE
|
||||
nodamage = 1
|
||||
flag = "bullet"
|
||||
|
||||
Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return
|
||||
|
||||
sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits
|
||||
|
||||
if(src)//Do not add to this if() statement, otherwise the meteor won't delete them
|
||||
if(A)
|
||||
|
||||
A.meteorhit(src)
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||
|
||||
for(var/mob/M in range(10, src))
|
||||
if(!M.stat && !istype(M, /mob/living/silicon/ai))\
|
||||
shake_camera(M, 3, 1)
|
||||
del(src)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/projectile/energy/floramut
|
||||
name = "alpha somatoray"
|
||||
icon_state = "energy"
|
||||
@@ -50,7 +80,7 @@
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
var/mob/living/M = target
|
||||
if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //Plantmen possibly get mutated and damaged by the rays.
|
||||
var/mob/living/L as mob
|
||||
var/mob/living/L = target
|
||||
if(prob(15))
|
||||
L.apply_effect((rand(30,80)),IRRADIATE)
|
||||
L.Weaken(5)
|
||||
|
||||
@@ -3102,7 +3102,7 @@ datum
|
||||
brave_bull
|
||||
name = "Brave Bull"
|
||||
id = "bravebull"
|
||||
description = "A strange yet pleasurable mixture made of vodka, tomato and lime juice. Or at least you THINK the red stuff is tomato juice."
|
||||
description = "It's just as effective as Dutch-Courage!."
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3140,7 +3140,7 @@ datum
|
||||
toxins_special
|
||||
name = "Toxins Special"
|
||||
id = "toxinsspecial"
|
||||
description = "This thing is FLAMING!. CALL THE DAMN SHUTTLE!"
|
||||
description = "This thing is ON FIRE!. CALL THE DAMN SHUTTLE!"
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3390,7 +3390,7 @@ datum
|
||||
whiskeysoda
|
||||
name = "Whiskey Soda"
|
||||
id = "whiskeysoda"
|
||||
description = "Ultimate refreshment."
|
||||
description = "For the more refined griffon."
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3525,7 +3525,7 @@ datum
|
||||
bahama_mama
|
||||
name = "Bahama mama"
|
||||
id = "bahama_mama"
|
||||
description = "Tropic cocktail."
|
||||
description = "Tropical cocktail."
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3731,7 +3731,7 @@ datum
|
||||
alliescocktail
|
||||
name = "Allies Cocktail"
|
||||
id = "alliescocktail"
|
||||
description = "A drink made from your allies."
|
||||
description = "A drink made from your allies, not as sweet as when made from your enemies."
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3790,7 +3790,7 @@ datum
|
||||
acid_spit
|
||||
name = "Acid Spit"
|
||||
id = "acidspit"
|
||||
description = "A drink by Nanotrasen. Made from live aliens."
|
||||
description = "A drink for the daring, can be deadly if incorrectly prepared!"
|
||||
reagent_state = LIQUID
|
||||
color = "#365000" // rgb: 54, 80, 0
|
||||
|
||||
@@ -3809,12 +3809,12 @@ datum
|
||||
amasec
|
||||
name = "Amasec"
|
||||
id = "amasec"
|
||||
description = "Official drink of the Imperium."
|
||||
description = "Official drink of the Nanotrasen Gun-Club!"
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
on_mob_life(var/mob/living/M as mob)
|
||||
M.stunned = 4
|
||||
M.stunned = 1
|
||||
if(!data) data = 1
|
||||
data++
|
||||
M.dizziness +=4
|
||||
@@ -3835,10 +3835,7 @@ datum
|
||||
|
||||
on_mob_life(var/mob/living/carbon/M as mob)
|
||||
if(!M) M = holder.my_atom
|
||||
M.adjustOxyLoss(0.5)
|
||||
M.adjustOxyLoss(0.5)
|
||||
M.weakened = max(M.weakened, 15)
|
||||
M.silent = max(M.silent, 15)
|
||||
M.weakened = max(M.weakened, 3)
|
||||
if(!data) data = 1
|
||||
data++
|
||||
M.dizziness +=6
|
||||
@@ -3857,7 +3854,7 @@ datum
|
||||
hippies_delight
|
||||
name = "Hippie's Delight"
|
||||
id = "hippiesdelight"
|
||||
description = "A drink enjoyed by people during the 1960's."
|
||||
description = "You just don't get it maaaan."
|
||||
reagent_state = LIQUID
|
||||
color = "#664300" // rgb: 102, 67, 0
|
||||
|
||||
@@ -3948,7 +3945,7 @@ datum
|
||||
changelingsting
|
||||
name = "Changeling Sting"
|
||||
id = "changelingsting"
|
||||
description = "A stingy drink."
|
||||
description = "You take a tiny sip and feel a burning sensation..."
|
||||
reagent_state = LIQUID
|
||||
color = "#2E6671" // rgb: 46, 102, 113
|
||||
|
||||
@@ -3986,7 +3983,7 @@ datum
|
||||
syndicatebomb
|
||||
name = "Syndicate Bomb"
|
||||
id = "syndicatebomb"
|
||||
description = "A Syndicate bomb"
|
||||
description = "Tastes like terrorism!"
|
||||
reagent_state = LIQUID
|
||||
color = "#2E6671" // rgb: 46, 102, 113
|
||||
|
||||
|
||||
@@ -61,6 +61,6 @@
|
||||
log_game("[key_name_admin(user)] used a grenade ([src.name]).")
|
||||
F.active = 1
|
||||
F.icon_state = initial(icon_state) + "_active"
|
||||
playsound(user.loc, 'armbomb.ogg', 75, 1, -3)
|
||||
playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
|
||||
spawn(15)
|
||||
F.prime()
|
||||
@@ -61,7 +61,7 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user as mob)
|
||||
playsound(src.loc, 'pop.ogg', 50, 0) //Change the mode
|
||||
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) //Change the mode
|
||||
if(mode == 1)
|
||||
mode = 2
|
||||
charge_tick = 0 //Prevents wasted chems/cell charge if you're cycling through modes.
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
spawn(5)
|
||||
reagents.trans_to(M, 10)
|
||||
|
||||
playsound(M.loc,'drink.ogg', rand(10,50), 1)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
else if( istype(M, /mob/living/carbon/human) )
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
spawn(5)
|
||||
reagents.trans_to(M, 10)
|
||||
|
||||
playsound(M.loc,'drink.ogg', rand(10,50), 1)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
spawn(5)
|
||||
reagents.trans_to(M, gulp_size)
|
||||
|
||||
playsound(M.loc,'drink.ogg', rand(10,50), 1)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
else if( istype(M, /mob/living/carbon/human) )
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
spawn(600)
|
||||
R.add_reagent(refill, fillevel)
|
||||
|
||||
playsound(M.loc,'drink.ogg', rand(10,50), 1)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
return
|
||||
|
||||
if(reagents) //Handle ingestion of the reagent.
|
||||
playsound(M.loc,'eatfood.ogg', rand(10,50), 1)
|
||||
playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
|
||||
@@ -146,7 +146,9 @@
|
||||
W:amount -= 5
|
||||
if(!W:amount) del(W)
|
||||
user << "<span class='notice'>You add some cable to the potato and slide it inside the battery encasing.</span>"
|
||||
new /obj/item/weapon/cell/potato(user.loc)
|
||||
var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(user.loc)
|
||||
pocell.maxcharge = src.potency * 10
|
||||
pocell.charge = pocell.maxcharge
|
||||
del(src)
|
||||
return
|
||||
|
||||
@@ -214,16 +216,16 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/Del()
|
||||
if(istype(loc,/mob))
|
||||
loc.sd_SetLuminosity(loc.luminosity - potency/5)
|
||||
loc.SetLuminosity(round(loc.luminosity - potency/5,1))
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/pickup(mob/user)
|
||||
src.sd_SetLuminosity(0)
|
||||
user.total_luminosity += potency/5
|
||||
src.SetLuminosity(0)
|
||||
user.SetLuminosity(round(user.luminosity + (potency/5),1))
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/dropped(mob/user)
|
||||
user.total_luminosity -= potency/5
|
||||
src.sd_SetLuminosity(potency/5)
|
||||
user.SetLuminosity(round(user.luminosity - (potency/5),1))
|
||||
src.SetLuminosity(round(potency/5,1))
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod
|
||||
seed = "/obj/item/seeds/cocoapodseed"
|
||||
@@ -769,7 +771,7 @@
|
||||
if(istype(src.loc,/mob))
|
||||
pickup(src.loc)
|
||||
else
|
||||
src.sd_SetLuminosity(potency/10)
|
||||
src.SetLuminosity(round(potency/10,1))
|
||||
lifespan = 120 //ten times that is the delay
|
||||
endurance = 30
|
||||
maturation = 15
|
||||
@@ -793,16 +795,16 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/Del()
|
||||
if(istype(loc,/mob))
|
||||
loc.sd_SetLuminosity(loc.luminosity - potency/10)
|
||||
loc.SetLuminosity(round(loc.luminosity - potency/10,1))
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/pickup(mob/user)
|
||||
src.sd_SetLuminosity(0)
|
||||
user.total_luminosity += potency/10
|
||||
SetLuminosity(0)
|
||||
user.SetLuminosity(round(user.luminosity + (potency/10),1))
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/dropped(mob/user)
|
||||
user.total_luminosity -= potency/10
|
||||
src.sd_SetLuminosity(potency/10)
|
||||
user.SetLuminosity(round(user.luminosity + (potency/10),1))
|
||||
SetLuminosity(round(potency/10,1))
|
||||
|
||||
// *************************************
|
||||
// Complex Grown Object Defines -
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
sleep(3)
|
||||
del(D)
|
||||
|
||||
playsound(src.loc, 'spray2.ogg', 50, 1, -6)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
|
||||
if(reagents.has_reagent("sacid"))
|
||||
message_admins("[key_name_admin(user)] fired sulphuric acid from a spray bottle.")
|
||||
@@ -181,7 +181,7 @@
|
||||
sleep(2)
|
||||
del(D)
|
||||
|
||||
playsound(src.loc, 'spray2.ogg', 50, 1, -6)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
|
||||
if(reagents.has_reagent("sacid"))
|
||||
message_admins("[key_name_admin(user)] fired sulphuric acid from a chem sprayer.")
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
del(S)
|
||||
D.icon_state = "syringeproj"
|
||||
D.name = "syringe"
|
||||
playsound(user.loc, 'syringeproj.ogg', 50, 1)
|
||||
playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
|
||||
for(var/i=0, i<6, i++)
|
||||
if(!D) break
|
||||
|
||||
Reference in New Issue
Block a user