mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 12:07:27 +01:00
conflicts? apparently?
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
|
||||
/obj/effect/hotspot
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
unacidable = 1//So you can't melt fire with acid.
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "1"
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
var/atmos_overlay = get_atmos_overlay_by_name(atmos_overlay_type)
|
||||
if(atmos_overlay)
|
||||
overlays -= atmos_overlay
|
||||
mouse_opacity = 1
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
|
||||
atmos_overlay = get_atmos_overlay_by_name(new_overlay_type)
|
||||
if(atmos_overlay)
|
||||
@@ -267,12 +267,12 @@
|
||||
|
||||
/turf/simulated/proc/tile_graphic()
|
||||
if(air.toxins > MOLES_PLASMA_VISIBLE)
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
return "plasma"
|
||||
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
return "sleeping_agent"
|
||||
return null
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
// LAVA_PROTECT used on the flags_2 variable for both SUIT and HEAD items, and stops lava damage. Must be present in both to stop lava damage.
|
||||
#define LAVA_PROTECT_2 2048
|
||||
|
||||
#define OVERLAY_QUEUED_2 4096
|
||||
|
||||
//Reagent flags
|
||||
#define REAGENT_NOREACT 1
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define GAS_PIPE_VISIBLE_LAYER 2.47
|
||||
#define GAS_FILTER_LAYER 2.48
|
||||
#define GAS_PUMP_LAYER 2.49
|
||||
#define CONVEYOR_LAYER 2.495
|
||||
#define LOW_OBJ_LAYER 2.5
|
||||
#define LOW_SIGIL_LAYER 2.52
|
||||
#define SIGIL_LAYER 2.54
|
||||
|
||||
+10
-1
@@ -373,4 +373,13 @@
|
||||
#define RETURN_TO_LOBBY 2
|
||||
|
||||
//Melting Temperatures for various specific objects
|
||||
#define GIRDER_MELTING_TEMP 5000
|
||||
#define GIRDER_MELTING_TEMP 5000
|
||||
|
||||
// Area selection defines
|
||||
#define AREASELECT_CORNERA "corner A"
|
||||
#define AREASELECT_CORNERB "corner B"
|
||||
|
||||
//https://secure.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
|
||||
#define MOUSE_OPACITY_TRANSPARENT 0
|
||||
#define MOUSE_OPACITY_ICON 1
|
||||
#define MOUSE_OPACITY_OPAQUE 2
|
||||
|
||||
@@ -132,6 +132,18 @@
|
||||
#define EMOTE_VISUAL 1 //A mob emote is visual
|
||||
#define EMOTE_SOUND 2 //A mob emote is sound
|
||||
|
||||
#define STATUS_UPDATE_HEALTH 1
|
||||
#define STATUS_UPDATE_STAT 2
|
||||
#define STATUS_UPDATE_CANMOVE 4
|
||||
#define STATUS_UPDATE_STAMINA 8
|
||||
#define STATUS_UPDATE_BLIND 16
|
||||
#define STATUS_UPDATE_BLURRY 32
|
||||
#define STATUS_UPDATE_NEARSIGHTED 64
|
||||
#define STATUS_UPDATE_DRUGGY 128
|
||||
|
||||
#define STATUS_UPDATE_NONE 0
|
||||
#define STATUS_UPDATE_ALL (~0)
|
||||
|
||||
//Human sub-species
|
||||
#define isshadowling(A) (is_species(A, /datum/species/shadow/ling))
|
||||
#define isshadowlinglesser(A) (is_species(A, /datum/species/shadow/ling/lesser))
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define SOLID 1
|
||||
#define LIQUID 2
|
||||
#define GAS 3
|
||||
#define GAS 3
|
||||
|
||||
#define REAGENT_OVERDOSE_EFFECT 1
|
||||
#define REAGENT_OVERDOSE_FLAGS 2
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
//prevents distinguishing identical timers with the wait variable
|
||||
#define TIMER_NO_HASH_WAIT 16
|
||||
|
||||
//Loops the timer repeatedly until qdeleted
|
||||
//In most cases you want a subsystem instead
|
||||
#define TIMER_LOOP 32
|
||||
|
||||
#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something
|
||||
|
||||
#define TIMER_ID_NULL -1
|
||||
@@ -120,3 +124,22 @@
|
||||
#define RUNLEVEL_POSTGAME 8
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
#define COMPILE_OVERLAYS(A)\
|
||||
if (TRUE) {\
|
||||
var/list/ad = A.add_overlays;\
|
||||
var/list/rm = A.remove_overlays;\
|
||||
var/list/po = A.priority_overlays;\
|
||||
if(LAZYLEN(rm)){\
|
||||
A.overlays -= rm;\
|
||||
rm.Cut();\
|
||||
}\
|
||||
if(LAZYLEN(ad)){\
|
||||
A.overlays |= ad;\
|
||||
ad.Cut();\
|
||||
}\
|
||||
if(LAZYLEN(po)){\
|
||||
A.overlays |= po;\
|
||||
}\
|
||||
A.flags_2 &= ~OVERLAY_QUEUED_2;\
|
||||
}
|
||||
@@ -185,4 +185,4 @@
|
||||
return "[key_name(src)] ([mob.x],[mob.y],[mob.z])"
|
||||
|
||||
//this is only used here (for now)
|
||||
#undef RUST_G
|
||||
#undef RUST_G
|
||||
|
||||
@@ -9,6 +9,35 @@
|
||||
* Misc
|
||||
*/
|
||||
|
||||
// binary search sorted insert
|
||||
// IN: Object to be inserted
|
||||
// LIST: List to insert object into
|
||||
// TYPECONT: The typepath of the contents of the list
|
||||
// COMPARE: The variable on the objects to compare
|
||||
#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \
|
||||
var/__BIN_CTTL = length(LIST);\
|
||||
if(!__BIN_CTTL) {\
|
||||
LIST += IN;\
|
||||
} else {\
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var/##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\
|
||||
__BIN_LEFT = __BIN_MID + 1;\
|
||||
} else {\
|
||||
__BIN_RIGHT = __BIN_MID;\
|
||||
};\
|
||||
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
};\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
__BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\
|
||||
LIST.Insert(__BIN_MID, IN);\
|
||||
}
|
||||
|
||||
|
||||
//Returns a list in plain english as a string
|
||||
/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
var/total = input.len
|
||||
|
||||
@@ -255,8 +255,8 @@ This is always put in the attack log.
|
||||
add_attack_logs(user, M, what_done, custom_level)
|
||||
return
|
||||
|
||||
var/user_str = key_name_log(user)
|
||||
var/target_str = key_name_log(target)
|
||||
var/user_str = key_name_log(user) + COORD(user)
|
||||
var/target_str = key_name_log(target) + COORD(target)
|
||||
|
||||
if(istype(user))
|
||||
user.create_attack_log("<font color='red'>Attacked [target_str]: [what_done]</font>")
|
||||
@@ -265,7 +265,6 @@ This is always put in the attack log.
|
||||
log_attack(user_str, target_str, what_done)
|
||||
|
||||
var/loglevel = ATKLOG_MOST
|
||||
|
||||
if(!isnull(custom_level))
|
||||
loglevel = custom_level
|
||||
else if(istype(target))
|
||||
@@ -503,4 +502,4 @@ This is always put in the attack log.
|
||||
var/list/viewrangelist = splittext(view, "x")
|
||||
viewX = text2num(viewrangelist[1])
|
||||
viewY = text2num(viewrangelist[2])
|
||||
return list(viewX, viewY)
|
||||
return list(viewX, viewY)
|
||||
|
||||
+87
-16
@@ -1785,28 +1785,99 @@ var/mob/dview/dview_mob = new
|
||||
for(var/type in types)
|
||||
var/typename = "[type]"
|
||||
var/static/list/TYPES_SHORTCUTS = list(
|
||||
//longest paths comes first - otherwise they get shadowed by the more generic ones
|
||||
/obj/effect/decal/cleanable = "CLEANABLE",
|
||||
/obj/item/radio/headset = "HEADSET",
|
||||
/obj/item/clothing/head/helmet/space = "SPESSHELMET",
|
||||
/obj/item/book/manual = "MANUAL",
|
||||
/obj/item/reagent_containers/food/drinks = "DRINK", //longest paths comes first
|
||||
/obj/item/reagent_containers/food = "FOOD",
|
||||
/obj/item/reagent_containers = "REAGENT_CONTAINERS",
|
||||
/obj/item = "WEAPON",
|
||||
/obj/machinery/atmospherics = "ATMOS_MECH",
|
||||
/obj/machinery/portable_atmospherics = "PORT_ATMOS",
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK",
|
||||
/obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP",
|
||||
/obj/item/organ = "ORGAN",
|
||||
/obj/item = "ITEM",
|
||||
/obj/machinery = "MACHINERY",
|
||||
/obj/effect = "EFFECT",
|
||||
/obj/item/ammo_casing = "AMMO",
|
||||
/obj/item/book/manual = "MANUAL",
|
||||
/obj/item/borg/upgrade = "BORG_UPGRADE",
|
||||
/obj/item/cartridge = "PDA_CART",
|
||||
/obj/item/clothing/head/helmet/space = "SPESSHELMET",
|
||||
/obj/item/clothing/head = "HEAD",
|
||||
/obj/item/clothing/under = "UNIFORM",
|
||||
/obj/item/clothing/shoes = "SHOES",
|
||||
/obj/item/clothing/suit = "SUIT",
|
||||
/obj/item/clothing/gloves = "GLOVES",
|
||||
/obj/item/clothing/mask/cigarette = "CIGARRETE", // oof
|
||||
/obj/item/clothing/mask = "MASK",
|
||||
/obj/item/clothing/glasses = "GLASSES",
|
||||
/obj/item/clothing = "CLOTHING",
|
||||
/obj/item/grenade/clusterbuster = "CLUSTERBUSTER",
|
||||
/obj/item/grenade = "GRENADE",
|
||||
/obj/item/gun = "GUN",
|
||||
/obj/item/implant = "IMPLANT",
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK",
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon = "MECHA_WEAPON",
|
||||
/obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP",
|
||||
/obj/item/melee = "MELEE",
|
||||
/obj/item/mmi = "MMI",
|
||||
/obj/item/nullrod = "NULLROD",
|
||||
/obj/item/organ/external = "EXT_ORG",
|
||||
/obj/item/organ/internal/cyberimp = "CYBERIMP",
|
||||
/obj/item/organ/internal = "INT_ORG",
|
||||
/obj/item/organ = "ORGAN",
|
||||
/obj/item/pda = "PDA",
|
||||
/obj/item/projectile = "PROJ",
|
||||
/obj/item/radio/headset = "HEADSET",
|
||||
/obj/item/reagent_containers/glass/beaker = "BEAKER",
|
||||
/obj/item/reagent_containers/glass/bottle = "BOTTLE",
|
||||
/obj/item/reagent_containers/food/pill/patch = "PATCH",
|
||||
/obj/item/reagent_containers/food/pill = "PILL",
|
||||
/obj/item/reagent_containers/food/drinks = "DRINK",
|
||||
/obj/item/reagent_containers/food = "FOOD",
|
||||
/obj/item/reagent_containers/syringe = "SYRINGE",
|
||||
/obj/item/reagent_containers = "REAGENT_CONTAINERS",
|
||||
/obj/item/robot_parts = "ROBOT_PARTS",
|
||||
/obj/item/seeds = "SEED",
|
||||
/obj/item/slime_extract = "SLIME_CORE",
|
||||
/obj/item/spacepod_equipment/weaponry = "POD_WEAPON",
|
||||
/obj/item/spacepod_equipment = "POD_EQUIP",
|
||||
/obj/item/stack/sheet/mineral = "MINERAL",
|
||||
/obj/item/stack/sheet = "SHEET",
|
||||
/obj/item/stack/tile = "TILE",
|
||||
/obj/item/stack = "STACK",
|
||||
/obj/item/stock_parts/cell = "POWERCELL",
|
||||
/obj/item/stock_parts = "STOCK_PARTS",
|
||||
/obj/item/storage/firstaid = "FIRSTAID",
|
||||
/obj/item/storage = "STORAGE",
|
||||
/obj/item/tank = "GAS_TANK",
|
||||
/obj/item/toy/crayon = "CRAYON",
|
||||
/obj/item/toy = "TOY",
|
||||
/obj/item = "ITEM",
|
||||
/obj/machinery/atmospherics = "ATMOS_MACH",
|
||||
/obj/machinery/computer = "CONSOLE",
|
||||
/obj/machinery/door/airlock = "AIRLOCK",
|
||||
/obj/machinery/door = "DOOR",
|
||||
/obj/machinery/kitchen_machine = "KITCHEN",
|
||||
/obj/machinery/portable_atmospherics/canister = "CANISTER",
|
||||
/obj/machinery/portable_atmospherics = "PORT_ATMOS",
|
||||
/obj/machinery/power = "POWER",
|
||||
/obj/machinery/telecomms = "TCOMMS",
|
||||
/obj/machinery = "MACHINERY",
|
||||
/obj/mecha = "MECHA",
|
||||
/obj/structure/closet/crate = "CRATE",
|
||||
/obj/structure/closet = "CLOSET",
|
||||
/obj/structure/statue = "STATUE",
|
||||
/obj/structure/chair = "CHAIR", // oh no
|
||||
/obj/structure/stool/bed = "BED",
|
||||
/obj/structure/stool = "STOOL",
|
||||
/obj/structure/table = "TABLE",
|
||||
/obj/structure = "STRUCTURE",
|
||||
/obj/vehicle = "VEHICLE",
|
||||
/obj = "O",
|
||||
/datum = "D",
|
||||
/turf/simulated/floor = "FLOOR",
|
||||
/turf/simulated/wall = "WALL",
|
||||
/turf/simulated/floor = "SIM_FLOOR",
|
||||
/turf/simulated/wall = "SIM_WALL",
|
||||
/turf/unsimulated/floor = "UNSIM_FLOOR",
|
||||
/turf/unsimulated/wall = "UNSIM_WALL",
|
||||
/turf = "T",
|
||||
/mob/living/carbon/alien = "XENO",
|
||||
/mob/living/carbon/human = "HUMAN",
|
||||
/mob/living/carbon = "CARBON",
|
||||
/mob/living/silicon/robot = "CYBORG",
|
||||
/mob/living/silicon/ai = "AI",
|
||||
/mob/living/silicon = "SILICON",
|
||||
/mob/living/simple_animal/bot = "BOT",
|
||||
/mob/living/simple_animal = "SIMPLE",
|
||||
/mob/living = "LIVING",
|
||||
/mob = "M"
|
||||
|
||||
+2
-1
@@ -11,7 +11,8 @@
|
||||
*/
|
||||
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
// Not doing a click intercept here, because otherwise we double-tap with the `ClickOn` proc.
|
||||
// But we return here since we don't want to do regular dblclick handling
|
||||
return
|
||||
|
||||
if(control_disabled || stat) return
|
||||
|
||||
@@ -392,7 +392,7 @@
|
||||
icon = 'icons/mob/screen_full.dmi'
|
||||
icon_state = "passage0"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
mouse_opacity = 2
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
icon_state = "default"
|
||||
name = "Alert"
|
||||
desc = "Something seems to have gone wrong with this alert, so report this bug please"
|
||||
mouse_opacity = 1
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
|
||||
var/severity = 0
|
||||
var/alerttooltipstyle = ""
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
icon_state = "default"
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
layer = FULLSCREEN_LAYER
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/severity = 0
|
||||
|
||||
/obj/screen/fullscreen/Destroy()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/obj/screen/text
|
||||
icon = null
|
||||
icon_state = null
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
maptext_height = 480
|
||||
maptext_width = 480
|
||||
@@ -275,8 +275,38 @@
|
||||
|
||||
/obj/screen/inventory
|
||||
var/slot_id //The indentifier for the slot. It has nothing to do with ID cards.
|
||||
var/list/object_overlays = list()
|
||||
layer = 19
|
||||
|
||||
/obj/screen/inventory/MouseEntered()
|
||||
..()
|
||||
add_overlays()
|
||||
|
||||
/obj/screen/inventory/MouseExited()
|
||||
..()
|
||||
cut_overlay(object_overlays)
|
||||
object_overlays.Cut()
|
||||
|
||||
/obj/screen/inventory/proc/add_overlays()
|
||||
var/mob/user = hud.mymob
|
||||
|
||||
if(hud && user && slot_id)
|
||||
var/obj/item/holding = user.get_active_hand()
|
||||
|
||||
if(!holding || user.get_item_by_slot(slot_id))
|
||||
return
|
||||
|
||||
var/image/item_overlay = image(holding)
|
||||
item_overlay.alpha = 92
|
||||
|
||||
if(!user.can_equip(holding, slot_id, disable_warning = TRUE))
|
||||
item_overlay.color = "#ff0000"
|
||||
else
|
||||
item_overlay.color = "#00ff00"
|
||||
|
||||
object_overlays += item_overlay
|
||||
add_overlay(object_overlays)
|
||||
|
||||
/obj/screen/inventory/Click()
|
||||
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
||||
// We don't even know if it's a middle click
|
||||
@@ -379,7 +409,7 @@
|
||||
icon = 'icons/mob/guardian.dmi'
|
||||
icon_state = "base"
|
||||
screen_loc = ui_health
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/screen/healthdoll
|
||||
name = "health doll"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
// Not doing a click intercept here, because otherwise we double-tap with the `ClickOn` proc.
|
||||
// But we return here since we don't want to do regular dblclick handling
|
||||
return
|
||||
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
|
||||
@@ -2,7 +2,6 @@ var/global/datum/controller/process/npcai/npcai_master
|
||||
|
||||
/datum/controller/process/npcai
|
||||
var/current_cycle
|
||||
var/saved_voice = 0
|
||||
|
||||
/datum/controller/process/npcai/setup()
|
||||
name = "npc ai"
|
||||
@@ -36,25 +35,6 @@ var/global/datum/controller/process/npcai/npcai_master
|
||||
catchBadType(M)
|
||||
simple_animal_list -= M
|
||||
|
||||
if(ticker.current_state == GAME_STATE_FINISHED && !saved_voice)
|
||||
var/mob/living/carbon/human/interactive/M = safepick(snpc_list)
|
||||
if(M)
|
||||
M.saveVoice()
|
||||
saved_voice = 1
|
||||
|
||||
for(last_object in snpc_list)
|
||||
var/mob/living/carbon/human/interactive/M = last_object
|
||||
if(istype(M) && !QDELETED(M))
|
||||
try
|
||||
if(!M.alternateProcessing || M.forceProcess)
|
||||
M.doProcess()
|
||||
catch(var/exception/e)
|
||||
catchException(e, M)
|
||||
SCHECK
|
||||
else
|
||||
catchBadType(M)
|
||||
snpc_list -= M
|
||||
|
||||
current_cycle++
|
||||
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
var/global/datum/controller/process/npcpool/npc_master
|
||||
|
||||
/datum/controller/process/npcpool
|
||||
var/list/canBeUsed = list()
|
||||
var/list/canBeUsed_non = list()
|
||||
var/list/needsDelegate = list()
|
||||
var/list/needsAssistant = list()
|
||||
var/list/needsHelp_non = list()
|
||||
var/list/botPool_l = list() //list of all npcs using the pool
|
||||
var/list/botPool_l_non = list() //list of all non SNPC mobs using the pool
|
||||
|
||||
/datum/controller/process/npcpool/setup()
|
||||
name = "npc pool"
|
||||
schedule_interval = 100
|
||||
start_delay = 17
|
||||
log_startup_progress("NPC pool ticker starting up.")
|
||||
|
||||
/datum/controller/process/npcpool/copyStateFrom(var/datum/controller/process/npcpool/target)
|
||||
canBeUsed = target.canBeUsed
|
||||
canBeUsed_non = target.canBeUsed_non
|
||||
needsDelegate = target.needsDelegate
|
||||
needsAssistant = target.needsAssistant
|
||||
needsHelp_non = target.needsHelp_non
|
||||
botPool_l = target.botPool_l
|
||||
botPool_l_non = target.botPool_l_non
|
||||
|
||||
|
||||
DECLARE_GLOBAL_CONTROLLER(npcpool, npc_master)
|
||||
|
||||
/datum/controller/process/npcpool/proc/insertBot(toInsert)
|
||||
if(istype(toInsert, /mob/living/carbon/human/interactive))
|
||||
botPool_l |= toInsert
|
||||
|
||||
/datum/controller/process/npcpool/proc/removeBot(toRemove)
|
||||
botPool_l -= toRemove
|
||||
|
||||
/datum/controller/process/npcpool/statProcess()
|
||||
..()
|
||||
stat(null, "T [botPool_l.len + botPool_l_non.len] | D [needsDelegate.len] | A [needsAssistant.len + needsHelp_non.len] | U [canBeUsed.len + canBeUsed_non.len]")
|
||||
|
||||
/datum/controller/process/npcpool/doWork()
|
||||
//bot delegation and coordination systems
|
||||
//General checklist/Tasks for delegating a task or coordinating it (for SNPCs)
|
||||
// 1. Bot proximity to task target: if too far, delegate, if close, coordinate
|
||||
// 2. Bot Health/status: check health with bots in local area, if their health is higher, delegate task to them, else coordinate
|
||||
// 3. Process delegation: if a bot (or bots) has been delegated, assign them to the task.
|
||||
// 4. Process coordination: if a bot(or bots) has been asked to coordinate, assign them to help.
|
||||
// 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them.
|
||||
|
||||
listclearnulls(canBeUsed)
|
||||
|
||||
//SNPC handling
|
||||
for(var/mob/living/carbon/human/interactive/check in botPool_l)
|
||||
if(!check)
|
||||
botPool_l -= check
|
||||
continue
|
||||
var/checkInRange = view(SNPC_MAX_RANGE_FIND, check)
|
||||
if(!(locate(check.TARGET) in checkInRange))
|
||||
needsDelegate |= check
|
||||
|
||||
else if(check.IsDeadOrIncap(0))
|
||||
needsDelegate |= check
|
||||
|
||||
else if(check.doing & SNPC_FIGHTING)
|
||||
needsAssistant |= check
|
||||
|
||||
else
|
||||
canBeUsed |= check
|
||||
SCHECK
|
||||
|
||||
if(needsDelegate.len)
|
||||
needsDelegate -= pick(needsDelegate) // cheapo way to make sure stuff doesn't pingpong around in the pool forever. delegation runs seperately to each loop so it will work much smoother
|
||||
|
||||
for(var/mob/living/carbon/human/interactive/check in needsDelegate)
|
||||
if(!check)
|
||||
needsDelegate -= check
|
||||
continue
|
||||
if(canBeUsed.len)
|
||||
var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed)
|
||||
var/facCount = 0
|
||||
var/helpProb = 0
|
||||
for(var/C in check.faction)
|
||||
for(var/D in candidate.faction)
|
||||
if(D == C)
|
||||
helpProb = min(100, helpProb + 25)
|
||||
facCount++
|
||||
if(facCount == 1 && helpProb > 0)
|
||||
helpProb = 100
|
||||
if(prob(helpProb))
|
||||
if(candidate.takeDelegate(check))
|
||||
needsDelegate -= check
|
||||
canBeUsed -= candidate
|
||||
candidate.change_eye_color(255, 0, 0)
|
||||
SCHECK
|
||||
|
||||
if(needsAssistant.len)
|
||||
needsAssistant -= pick(needsAssistant)
|
||||
|
||||
for(var/mob/living/carbon/human/interactive/check in needsAssistant)
|
||||
if(!check)
|
||||
needsAssistant -= check
|
||||
continue
|
||||
if(canBeUsed.len)
|
||||
var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed)
|
||||
var/facCount = 0
|
||||
var/helpProb = 0
|
||||
for(var/C in check.faction)
|
||||
for(var/D in candidate.faction)
|
||||
if(D == C)
|
||||
helpProb = min(100, helpProb + 25)
|
||||
facCount++
|
||||
if(facCount == 1 && helpProb > 0)
|
||||
helpProb = 100
|
||||
if(prob(helpProb))
|
||||
if(candidate.takeDelegate(check, 0))
|
||||
needsAssistant -= check
|
||||
canBeUsed -= candidate
|
||||
candidate.change_eye_color(255, 255, 0)
|
||||
SCHECK
|
||||
@@ -363,19 +363,19 @@ SUBSYSTEM_DEF(air)
|
||||
plmaster.icon = 'icons/effects/tile_effects.dmi'
|
||||
plmaster.icon_state = "plasma"
|
||||
plmaster.layer = FLY_LAYER
|
||||
plmaster.mouse_opacity = 0
|
||||
plmaster.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
slmaster = new /obj/effect/overlay()
|
||||
slmaster.icon = 'icons/effects/tile_effects.dmi'
|
||||
slmaster.icon_state = "sleeping_agent"
|
||||
slmaster.layer = FLY_LAYER
|
||||
slmaster.mouse_opacity = 0
|
||||
slmaster.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
icemaster = new /obj/effect/overlay()
|
||||
icemaster.icon = 'icons/turf/overlays.dmi'
|
||||
icemaster.icon_state = "snowfloor"
|
||||
icemaster.layer = TURF_LAYER + 0.1
|
||||
icemaster.mouse_opacity = 0
|
||||
icemaster.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
#undef SSAIR_PIPENETS
|
||||
#undef SSAIR_ATMOSMACHINERY
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
SUBSYSTEM_DEF(npcai)
|
||||
name = "NPC AI" // Simple AI controller, isolated from the SNPC one (NPCPool).
|
||||
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_NPC
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
var/list/simple_animal_list = list()
|
||||
|
||||
/datum/controller/subsystem/npcai/stat_entry()
|
||||
..("SimAnimals:[simple_animal_list.len]")
|
||||
|
||||
/datum/controller/subsystem/npcai/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
src.simple_animal_list = simple_animal_list.Copy()
|
||||
for(var/mob/living/simple_animal/M in simple_animal_list)
|
||||
if(istype(M) && !QDELETED(M))
|
||||
if(!M.client && M.stat == CONSCIOUS)
|
||||
M.process_ai()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
else
|
||||
simple_animal_list -= M
|
||||
|
||||
/datum/controller/subsystem/npcai/Recover()
|
||||
simple_animal_list = SSnpcai.simple_animal_list
|
||||
@@ -0,0 +1,127 @@
|
||||
#define PROCESSING_NPCS 0
|
||||
#define PROCESSING_DELEGATES 1
|
||||
#define PROCESSING_ASSISTANTS 2
|
||||
|
||||
SUBSYSTEM_DEF(npcpool)
|
||||
name = "NPC Pool"
|
||||
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_NPC
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/canBeUsed = list()
|
||||
var/list/needsDelegate = list()
|
||||
var/list/needsAssistant = list()
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
var/stage
|
||||
|
||||
/datum/controller/subsystem/npcpool/stat_entry()
|
||||
..("NPCS:[processing.len]|D:[needsDelegate.len]|A:[needsAssistant.len]|U:[canBeUsed.len]")
|
||||
|
||||
/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/carbon/human/interactive/I)
|
||||
processing -= I
|
||||
currentrun -= I
|
||||
needsDelegate -= I
|
||||
canBeUsed -= I
|
||||
needsAssistant -= I
|
||||
|
||||
/datum/controller/subsystem/npcpool/fire(resumed = FALSE)
|
||||
//bot delegation and coordination systems
|
||||
//General checklist/Tasks for delegating a task or coordinating it (for SNPCs)
|
||||
// 1. Bot proximity to task target: if too far, delegate, if close, coordinate
|
||||
// 2. Bot Health/status: check health with bots in local area, if their health is higher, delegate task to them, else coordinate
|
||||
// 3. Process delegation: if a bot (or bots) has been delegated, assign them to the task.
|
||||
// 4. Process coordination: if a bot(or bots) has been asked to coordinate, assign them to help.
|
||||
// 5. Do all assignments: goes through the delegated/coordianted bots and assigns the right variables/tasks to them.
|
||||
|
||||
if (!resumed)
|
||||
currentrun = processing.Copy()
|
||||
stage = PROCESSING_NPCS
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/cachecurrentrun = currentrun
|
||||
var/list/cachecanBeUsed = canBeUsed
|
||||
|
||||
if(stage == PROCESSING_NPCS)
|
||||
while(cachecurrentrun.len)
|
||||
var/mob/living/carbon/human/interactive/thing = cachecurrentrun[cachecurrentrun.len]
|
||||
--cachecurrentrun.len
|
||||
|
||||
thing.InteractiveProcess()
|
||||
|
||||
var/checkInRange = view(SNPC_MAX_RANGE_FIND,thing)
|
||||
if(thing.IsDeadOrIncap(FALSE) || !(locate(thing.TARGET) in checkInRange))
|
||||
needsDelegate += thing
|
||||
else if(thing.doing & SNPC_FIGHTING)
|
||||
needsAssistant += thing
|
||||
else
|
||||
cachecanBeUsed += thing
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
stage = PROCESSING_DELEGATES
|
||||
cachecurrentrun = needsDelegate //localcache
|
||||
currentrun = cachecurrentrun
|
||||
|
||||
if(stage == PROCESSING_DELEGATES)
|
||||
while(cachecurrentrun.len && cachecanBeUsed.len)
|
||||
var/mob/living/carbon/human/interactive/check = cachecurrentrun[cachecurrentrun.len]
|
||||
var/mob/living/carbon/human/interactive/candidate = cachecanBeUsed[cachecanBeUsed.len]
|
||||
--cachecurrentrun.len
|
||||
|
||||
var/helpProb = 0
|
||||
var/list/chfac = check.faction
|
||||
var/list/canfac = candidate.faction
|
||||
var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac)
|
||||
|
||||
for(var/C in chfac)
|
||||
if(C in canfac)
|
||||
helpProb = min(100,helpProb + 25)
|
||||
if(helpProb >= 100)
|
||||
break
|
||||
|
||||
if(facCount == 1 && helpProb)
|
||||
helpProb = 100
|
||||
|
||||
if(prob(helpProb) && candidate.takeDelegate(check))
|
||||
--cachecanBeUsed.len
|
||||
candidate.change_eye_color(255, 0, 0)
|
||||
candidate.update_icons()
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
stage = PROCESSING_ASSISTANTS
|
||||
cachecurrentrun = needsAssistant //localcache
|
||||
currentrun = cachecurrentrun
|
||||
|
||||
//no need for the stage check
|
||||
|
||||
while(cachecurrentrun.len && cachecanBeUsed.len)
|
||||
var/mob/living/carbon/human/interactive/check = cachecurrentrun[cachecurrentrun.len]
|
||||
var/mob/living/carbon/human/interactive/candidate = cachecanBeUsed[cachecanBeUsed.len]
|
||||
--cachecurrentrun.len
|
||||
|
||||
var/helpProb = 0
|
||||
var/list/chfac = check.faction
|
||||
var/list/canfac = candidate.faction
|
||||
var/facCount = LAZYLEN(chfac) * LAZYLEN(canfac)
|
||||
|
||||
for(var/C in chfac)
|
||||
if(C in canfac)
|
||||
helpProb = min(100,helpProb + 25)
|
||||
if(helpProb >= 100)
|
||||
break
|
||||
|
||||
if(facCount == 1 && helpProb)
|
||||
helpProb = 100
|
||||
|
||||
if(prob(helpProb) && candidate.takeDelegate(check,FALSE))
|
||||
--cachecanBeUsed.len
|
||||
candidate.change_eye_color(255, 255, 0)
|
||||
candidate.update_icons()
|
||||
|
||||
if(!cachecurrentrun.len || MC_TICK_CHECK) //don't change SS state if it isn't necessary
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/npcpool/Recover()
|
||||
processing = SSnpcpool.processing
|
||||
@@ -0,0 +1,212 @@
|
||||
SUBSYSTEM_DEF(overlays)
|
||||
name = "Overlay"
|
||||
flags = SS_TICKER
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_OVERLAYS
|
||||
init_order = INIT_ORDER_OVERLAY
|
||||
|
||||
var/list/queue
|
||||
var/list/stats
|
||||
var/list/overlay_icon_state_caches
|
||||
var/list/overlay_icon_cache
|
||||
|
||||
/datum/controller/subsystem/overlays/PreInit()
|
||||
overlay_icon_state_caches = list()
|
||||
overlay_icon_cache = list()
|
||||
queue = list()
|
||||
stats = list()
|
||||
|
||||
/datum/controller/subsystem/overlays/Initialize()
|
||||
initialized = TRUE
|
||||
fire(mc_check = FALSE)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/stat_entry()
|
||||
..("Ov:[length(queue)]")
|
||||
|
||||
/datum/controller/subsystem/overlays/Recover()
|
||||
overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches
|
||||
overlay_icon_cache = SSoverlays.overlay_icon_cache
|
||||
queue = SSoverlays.queue
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE)
|
||||
var/list/queue = src.queue
|
||||
var/static/count = 0
|
||||
if(count)
|
||||
var/c = count
|
||||
count = 0 //so if we runtime on the Cut, we don't try again.
|
||||
queue.Cut(1, c + 1)
|
||||
|
||||
for(var/thing in queue)
|
||||
count++
|
||||
if(thing)
|
||||
var/atom/A = thing
|
||||
COMPILE_OVERLAYS(A)
|
||||
if(mc_check)
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
else
|
||||
CHECK_TICK
|
||||
|
||||
if(count)
|
||||
queue.Cut(1, count + 1)
|
||||
count = 0
|
||||
|
||||
/proc/iconstate2appearance(icon, iconstate)
|
||||
var/static/image/stringbro = new()
|
||||
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
|
||||
var/list/cached_icon = icon_states_cache[icon]
|
||||
if(cached_icon)
|
||||
var/cached_appearance = cached_icon["[iconstate]"]
|
||||
if(cached_appearance)
|
||||
return cached_appearance
|
||||
stringbro.icon = icon
|
||||
stringbro.icon_state = iconstate
|
||||
if(!cached_icon) //not using the macro to save an associated lookup
|
||||
cached_icon = list()
|
||||
icon_states_cache[icon] = cached_icon
|
||||
var/cached_appearance = stringbro.appearance
|
||||
cached_icon["[iconstate]"] = cached_appearance
|
||||
return cached_appearance
|
||||
|
||||
/proc/icon2appearance(icon)
|
||||
var/static/image/iconbro = new()
|
||||
var/list/icon_cache = SSoverlays.overlay_icon_cache
|
||||
. = icon_cache[icon]
|
||||
if(!.)
|
||||
iconbro.icon = icon
|
||||
. = iconbro.appearance
|
||||
icon_cache[icon] = .
|
||||
|
||||
/atom/proc/build_appearance_list(old_overlays)
|
||||
var/static/image/appearance_bro = new()
|
||||
var/list/new_overlays = list()
|
||||
if(!islist(old_overlays))
|
||||
old_overlays = list(old_overlays)
|
||||
for(var/overlay in old_overlays)
|
||||
if(!overlay)
|
||||
continue
|
||||
if(istext(overlay))
|
||||
new_overlays += iconstate2appearance(icon, overlay)
|
||||
else if(isicon(overlay))
|
||||
new_overlays += icon2appearance(overlay)
|
||||
else
|
||||
if(isloc(overlay))
|
||||
var/atom/A = overlay
|
||||
if(A.flags_2 & OVERLAY_QUEUED_2)
|
||||
COMPILE_OVERLAYS(A)
|
||||
appearance_bro.appearance = overlay //this works for images and atoms too!
|
||||
if(!ispath(overlay))
|
||||
var/image/I = overlay
|
||||
appearance_bro.dir = I.dir
|
||||
new_overlays += appearance_bro.appearance
|
||||
return new_overlays
|
||||
|
||||
#define NOT_QUEUED_ALREADY (!(flags_2 & OVERLAY_QUEUED_2))
|
||||
#define QUEUE_FOR_COMPILE flags_2 |= OVERLAY_QUEUED_2; SSoverlays.queue += src;
|
||||
/atom/proc/cut_overlays(priority = FALSE)
|
||||
LAZYINITLIST(priority_overlays)
|
||||
LAZYINITLIST(remove_overlays)
|
||||
LAZYINITLIST(add_overlays)
|
||||
remove_overlays = overlays.Copy()
|
||||
add_overlays.Cut()
|
||||
|
||||
if(priority)
|
||||
priority_overlays.Cut()
|
||||
|
||||
//If not already queued for work and there are overlays to remove
|
||||
if(NOT_QUEUED_ALREADY && remove_overlays.len)
|
||||
QUEUE_FOR_COMPILE
|
||||
|
||||
/atom/proc/cut_overlay(list/overlays, priority)
|
||||
if(!overlays)
|
||||
return
|
||||
overlays = build_appearance_list(overlays)
|
||||
LAZYINITLIST(add_overlays) //always initialized after this point
|
||||
LAZYINITLIST(priority_overlays)
|
||||
LAZYINITLIST(remove_overlays)
|
||||
var/a_len = add_overlays.len
|
||||
var/r_len = remove_overlays.len
|
||||
var/p_len = priority_overlays.len
|
||||
remove_overlays += overlays
|
||||
add_overlays -= overlays
|
||||
|
||||
if(priority)
|
||||
var/list/cached_priority = priority_overlays
|
||||
LAZYREMOVE(cached_priority, overlays)
|
||||
|
||||
var/fa_len = add_overlays.len
|
||||
var/fr_len = remove_overlays.len
|
||||
var/fp_len = priority_overlays.len
|
||||
|
||||
//If not already queued and there is work to be done
|
||||
if(NOT_QUEUED_ALREADY && (fa_len != a_len || fr_len != r_len || fp_len != p_len))
|
||||
QUEUE_FOR_COMPILE
|
||||
|
||||
/atom/proc/add_overlay(list/overlays, priority = FALSE)
|
||||
if(!overlays)
|
||||
return
|
||||
|
||||
overlays = build_appearance_list(overlays)
|
||||
|
||||
LAZYINITLIST(add_overlays) //always initialized after this point
|
||||
LAZYINITLIST(priority_overlays)
|
||||
var/a_len = add_overlays.len
|
||||
var/p_len = priority_overlays.len
|
||||
|
||||
if(priority)
|
||||
priority_overlays += overlays //or in the image. Can we use [image] = image?
|
||||
var/fp_len = priority_overlays.len
|
||||
if(NOT_QUEUED_ALREADY && fp_len != p_len)
|
||||
QUEUE_FOR_COMPILE
|
||||
else
|
||||
add_overlays += overlays
|
||||
var/fa_len = add_overlays.len
|
||||
if(NOT_QUEUED_ALREADY && fa_len != a_len)
|
||||
QUEUE_FOR_COMPILE
|
||||
|
||||
/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom
|
||||
if(!other)
|
||||
if(cut_old)
|
||||
cut_overlays()
|
||||
return
|
||||
|
||||
var/list/cached_other = other.overlays.Copy()
|
||||
if(cached_other)
|
||||
if(cut_old || !LAZYLEN(overlays))
|
||||
remove_overlays = overlays
|
||||
add_overlays = cached_other
|
||||
if(NOT_QUEUED_ALREADY)
|
||||
QUEUE_FOR_COMPILE
|
||||
else if(cut_old)
|
||||
cut_overlays()
|
||||
|
||||
#undef NOT_QUEUED_ALREADY
|
||||
#undef QUEUE_FOR_COMPILE
|
||||
|
||||
//TODO: Better solution for these?
|
||||
/image/proc/add_overlay(x)
|
||||
overlays |= x
|
||||
|
||||
/image/proc/cut_overlay(x)
|
||||
overlays -= x
|
||||
|
||||
/image/proc/cut_overlays(x)
|
||||
overlays.Cut()
|
||||
|
||||
/image/proc/copy_overlays(atom/other, cut_old)
|
||||
if(!other)
|
||||
if(cut_old)
|
||||
cut_overlays()
|
||||
return
|
||||
|
||||
var/list/cached_other = other.overlays.Copy()
|
||||
if(cached_other)
|
||||
if(cut_old || !overlays.len)
|
||||
overlays = cached_other
|
||||
else
|
||||
overlays |= cached_other
|
||||
else if(cut_old)
|
||||
cut_overlays()
|
||||
@@ -35,7 +35,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
message_adminTicket("<span class='adminticket'>Tickets [report] have been open for over [ADMIN_TICKET_TIMEOUT / 600] minutes. Changing status to stale.</span>")
|
||||
|
||||
/datum/controller/subsystem/tickets/stat_entry()
|
||||
..("Tickets: [allTickets.len]")
|
||||
..("Tickets: [LAZYLEN(allTickets)]")
|
||||
|
||||
/datum/controller/subsystem/tickets/proc/checkStaleness()
|
||||
var/stales = list()
|
||||
|
||||
+108
-102
@@ -1,5 +1,5 @@
|
||||
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
|
||||
#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN) + 1)
|
||||
#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN)||BUCKET_LEN)
|
||||
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
|
||||
#define TIMER_ID_MAX (2**24) //max float with integer precision
|
||||
|
||||
@@ -71,6 +71,7 @@ SUBSYSTEM_DEF(timer)
|
||||
for(var/I in second_queue)
|
||||
log_world(get_timer_debug_string(I))
|
||||
|
||||
var/cut_start_index = 1
|
||||
var/next_clienttime_timer_index = 0
|
||||
var/len = length(clienttime_timers)
|
||||
|
||||
@@ -90,11 +91,17 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
ctime_timer.spent = REALTIMEOFDAY
|
||||
callBack.InvokeAsync()
|
||||
qdel(ctime_timer)
|
||||
|
||||
if(ctime_timer.flags & TIMER_LOOP)
|
||||
ctime_timer.spent = 0
|
||||
clienttime_timers.Insert(ctime_timer, 1)
|
||||
cut_start_index++
|
||||
else
|
||||
qdel(ctime_timer)
|
||||
|
||||
|
||||
if(next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(1,next_clienttime_timer_index+1)
|
||||
clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
@@ -197,8 +204,22 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
bucket_count -= length(spent)
|
||||
|
||||
for(var/spent_timer in spent)
|
||||
qdel(spent_timer)
|
||||
for(var/i in spent)
|
||||
var/datum/timedevent/qtimer = i
|
||||
if(QDELETED(qtimer))
|
||||
bucket_count++
|
||||
continue
|
||||
if(!(qtimer.flags & TIMER_LOOP))
|
||||
qdel(qtimer)
|
||||
else
|
||||
bucket_count++
|
||||
qtimer.spent = 0
|
||||
qtimer.bucketEject()
|
||||
if(qtimer.flags & TIMER_CLIENT_TIME)
|
||||
qtimer.timeToRun = REALTIMEOFDAY + qtimer.wait
|
||||
else
|
||||
qtimer.timeToRun = world.time + qtimer.wait
|
||||
qtimer.bucketJoin()
|
||||
|
||||
spent.len = 0
|
||||
|
||||
@@ -294,6 +315,7 @@ SUBSYSTEM_DEF(timer)
|
||||
var/id
|
||||
var/datum/callback/callBack
|
||||
var/timeToRun
|
||||
var/wait
|
||||
var/hash
|
||||
var/list/flags
|
||||
var/spent = 0 //time we ran the timer.
|
||||
@@ -302,14 +324,19 @@ SUBSYSTEM_DEF(timer)
|
||||
var/datum/timedevent/next
|
||||
var/datum/timedevent/prev
|
||||
|
||||
/datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash)
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash)
|
||||
var/static/nextid = 1
|
||||
id = TIMER_ID_NULL
|
||||
src.callBack = callBack
|
||||
src.timeToRun = timeToRun
|
||||
src.wait = wait
|
||||
src.flags = flags
|
||||
src.hash = hash
|
||||
|
||||
if(flags & TIMER_CLIENT_TIME)
|
||||
timeToRun = REALTIMEOFDAY + wait
|
||||
else
|
||||
timeToRun = world.time + wait
|
||||
|
||||
if(flags & TIMER_UNIQUE)
|
||||
SStimer.hashes[hash] = src
|
||||
|
||||
@@ -321,68 +348,15 @@ SUBSYSTEM_DEF(timer)
|
||||
nextid++
|
||||
SStimer.timer_id_dict[id] = src
|
||||
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
|
||||
|
||||
if((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
|
||||
CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
|
||||
|
||||
if(callBack.object != GLOBAL_PROC)
|
||||
if(callBack.object != GLOBAL_PROC && !QDESTROYING(callBack.object))
|
||||
LAZYADD(callBack.object.active_timers, src)
|
||||
|
||||
|
||||
var/list/L
|
||||
|
||||
if(flags & TIMER_CLIENT_TIME)
|
||||
L = SStimer.clienttime_timers
|
||||
else if(timeToRun >= TIMER_MAX)
|
||||
L = SStimer.second_queue
|
||||
|
||||
|
||||
if(L)
|
||||
//binary search sorted insert
|
||||
var/cttl = length(L)
|
||||
if(cttl)
|
||||
var/left = 1
|
||||
var/right = cttl
|
||||
var/mid = (left+right) >> 1 //rounded divide by two for hedgehogs
|
||||
|
||||
var/datum/timedevent/item
|
||||
while(left < right)
|
||||
item = L[mid]
|
||||
if(item.timeToRun <= timeToRun)
|
||||
left = mid+1
|
||||
else
|
||||
right = mid
|
||||
mid = (left+right) >> 1
|
||||
|
||||
item = L[mid]
|
||||
mid = item.timeToRun > timeToRun ? mid : mid+1
|
||||
L.Insert(mid, src)
|
||||
|
||||
else
|
||||
L += src
|
||||
return
|
||||
|
||||
//get the list of buckets
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
|
||||
//calculate our place in the bucket list
|
||||
var/bucket_pos = BUCKET_POS(src)
|
||||
|
||||
//get the bucket for our tick
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
SStimer.bucket_count++
|
||||
//empty bucket, we will just add ourselves
|
||||
if(!bucket_head)
|
||||
bucket_list[bucket_pos] = src
|
||||
return
|
||||
//other wise, lets do a simplified linked list add.
|
||||
if(!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
next = bucket_head
|
||||
prev = bucket_head.prev
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
bucketJoin()
|
||||
|
||||
/datum/timedevent/Destroy()
|
||||
..()
|
||||
@@ -406,31 +380,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
if(!spent)
|
||||
spent = world.time
|
||||
var/bucketpos = BUCKET_POS(src)
|
||||
var/datum/timedevent/buckethead
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
if(bucketpos > 0)
|
||||
buckethead = bucket_list[bucketpos]
|
||||
|
||||
if(buckethead == src)
|
||||
bucket_list[bucketpos] = next
|
||||
SStimer.bucket_count--
|
||||
else if(timeToRun < TIMER_MAX || next || prev)
|
||||
SStimer.bucket_count--
|
||||
else
|
||||
var/l = length(SStimer.second_queue)
|
||||
SStimer.second_queue -= src
|
||||
if(l == length(SStimer.second_queue))
|
||||
SStimer.bucket_count--
|
||||
|
||||
if(prev == next && next)
|
||||
next.prev = null
|
||||
prev.next = null
|
||||
else
|
||||
if(prev)
|
||||
prev.next = next
|
||||
if(next)
|
||||
next.prev = prev
|
||||
bucketEject()
|
||||
else
|
||||
if(prev && prev.next == src)
|
||||
prev.next = next
|
||||
@@ -440,6 +390,66 @@ SUBSYSTEM_DEF(timer)
|
||||
prev = null
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/datum/timedevent/proc/bucketEject()
|
||||
var/bucketpos = BUCKET_POS(src)
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
var/list/second_queue = SStimer.second_queue
|
||||
var/datum/timedevent/buckethead
|
||||
if(bucketpos > 0)
|
||||
buckethead = bucket_list[bucketpos]
|
||||
if(buckethead == src)
|
||||
bucket_list[bucketpos] = next
|
||||
SStimer.bucket_count--
|
||||
else if(timeToRun < TIMER_MAX || next || prev)
|
||||
SStimer.bucket_count--
|
||||
else
|
||||
var/l = length(second_queue)
|
||||
second_queue -= src
|
||||
if(l == length(second_queue))
|
||||
SStimer.bucket_count--
|
||||
if(prev != next)
|
||||
prev.next = next
|
||||
next.prev = prev
|
||||
else
|
||||
if(prev)
|
||||
prev.next = null
|
||||
if(next)
|
||||
next.prev = null
|
||||
prev = next = null
|
||||
|
||||
/datum/timedevent/proc/bucketJoin()
|
||||
var/list/L
|
||||
|
||||
if(flags & TIMER_CLIENT_TIME)
|
||||
L = SStimer.clienttime_timers
|
||||
else if(timeToRun >= TIMER_MAX)
|
||||
L = SStimer.second_queue
|
||||
|
||||
if(L)
|
||||
BINARY_INSERT(src, L, datum/timedevent, timeToRun)
|
||||
return
|
||||
|
||||
//get the list of buckets
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
|
||||
//calculate our place in the bucket list
|
||||
var/bucket_pos = BUCKET_POS(src)
|
||||
|
||||
//get the bucket for our tick
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
SStimer.bucket_count++
|
||||
//empty bucket, we will just add ourselves
|
||||
if(!bucket_head)
|
||||
bucket_list[bucket_pos] = src
|
||||
return
|
||||
//other wise, lets do a simplified linked list add.
|
||||
if(!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
next = bucket_head
|
||||
prev = bucket_head.prev
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
|
||||
/datum/timedevent/proc/getcallingtype()
|
||||
. = "ERROR"
|
||||
if(callBack.object == GLOBAL_PROC)
|
||||
@@ -452,13 +462,12 @@ SUBSYSTEM_DEF(timer)
|
||||
CRASH("addtimer called without a callback")
|
||||
|
||||
if(wait < 0)
|
||||
stack_trace("addtimer called with a negative wait. Converting to 0")
|
||||
stack_trace("addtimer called with a negative wait. Converting to [world.tick_lag]")
|
||||
|
||||
//alot of things add short timers on themselves in their destroy, we ignore those cases
|
||||
if(wait >= 1 && callback && callback.object && callback.object != GLOBAL_PROC && QDELETED(callback.object))
|
||||
stack_trace("addtimer called with a callback assigned to a qdeleted object")
|
||||
if(callback.object != GLOBAL_PROC && QDELETED(callback.object) && !QDESTROYING(callback.object))
|
||||
stack_trace("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not be supported and may refuse to run or run with a 0 wait")
|
||||
|
||||
wait = max(wait, 0)
|
||||
wait = max(CEILING(wait, world.tick_lag), world.tick_lag)
|
||||
|
||||
if(wait >= INFINITY)
|
||||
CRASH("Attempted to create timer with INFINITY delay")
|
||||
@@ -468,9 +477,9 @@ SUBSYSTEM_DEF(timer)
|
||||
if(flags & TIMER_UNIQUE)
|
||||
var/list/hashlist
|
||||
if(flags & TIMER_NO_HASH_WAIT)
|
||||
hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
else
|
||||
hashlist = list(callback.object, "([callback.object.UID()])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
hashlist += callback.arguments
|
||||
hash = hashlist.Join("|||||||")
|
||||
|
||||
@@ -486,13 +495,10 @@ SUBSYSTEM_DEF(timer)
|
||||
if(hash_timer.flags & TIMER_STOPPABLE)
|
||||
. = hash_timer.id
|
||||
return
|
||||
else if(flags & TIMER_OVERRIDE)
|
||||
stack_trace("TIMER_OVERRIDE used without TIMER_UNIQUE")
|
||||
|
||||
|
||||
var/timeToRun = world.time + wait
|
||||
if(flags & TIMER_CLIENT_TIME)
|
||||
timeToRun = REALTIMEOFDAY + wait
|
||||
|
||||
var/datum/timedevent/timer = new(callback, timeToRun, flags, hash)
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash)
|
||||
return timer.id
|
||||
|
||||
/proc/deltimer(id)
|
||||
@@ -515,4 +521,4 @@ SUBSYSTEM_DEF(timer)
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
#undef TIMER_MAX
|
||||
#undef TIMER_ID_MAX
|
||||
#undef TIMER_ID_MAX
|
||||
@@ -85,7 +85,7 @@
|
||||
debug_variables(SSmobs)
|
||||
feedback_add_details("admin_verb","DMob")
|
||||
if("NPC AI")
|
||||
debug_variables(npcai_master)
|
||||
debug_variables(SSnpcai)
|
||||
feedback_add_details("admin_verb","DNPCAI")
|
||||
if("Shuttle")
|
||||
debug_variables(SSshuttle)
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@
|
||||
X.pixel_y = Pixel_y
|
||||
|
||||
/obj/effect/ebeam
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = 1
|
||||
var/datum/beam/owner
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum/click_intercept
|
||||
var/client/holder = null
|
||||
var/list/obj/screen/buttons = list()
|
||||
|
||||
/datum/click_intercept/New(client/C)
|
||||
create_buttons()
|
||||
enter(C)
|
||||
return ..()
|
||||
|
||||
/datum/click_intercept/Destroy()
|
||||
holder.screen -= buttons
|
||||
holder.click_intercept = null
|
||||
holder.show_popup_menus = TRUE
|
||||
holder = null
|
||||
QDEL_LIST(buttons)
|
||||
return ..()
|
||||
|
||||
/datum/click_intercept/proc/enter(client/C)
|
||||
holder = C
|
||||
holder.click_intercept = src
|
||||
holder.show_popup_menus = FALSE
|
||||
holder.screen += buttons
|
||||
|
||||
/datum/click_intercept/proc/quit()
|
||||
qdel(src)
|
||||
|
||||
/datum/click_intercept/proc/create_buttons()
|
||||
return
|
||||
|
||||
/datum/click_intercept/proc/InterceptClickOn(user,params,atom/object)
|
||||
return
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
/datum/proc/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
if("attack_log")
|
||||
if("attack_log", "debug_log")
|
||||
return debug_variable(var_name, vars[var_name], 0, src, sanitize = FALSE)
|
||||
if("vars")
|
||||
return debug_variable(var_name, list(), 0, src)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
to_chat(affected_mob, "<span class='danger'>Your stomach stings painfully.</span>")
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(4)
|
||||
if(prob(10))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] buzzes.</span>", \
|
||||
@@ -37,4 +36,4 @@
|
||||
new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc)
|
||||
//if(5)
|
||||
//Plus if you die, you explode into bees
|
||||
return
|
||||
return
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
to_chat(affected_mob, "<span class='danger'>You don't feel like yourself.</span>")
|
||||
if(prob(5))
|
||||
affected_mob.adjustBrainLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
if(3)
|
||||
if(prob(2))
|
||||
affected_mob.emote("stare")
|
||||
@@ -33,7 +32,6 @@
|
||||
affected_mob.emote("drool")
|
||||
if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now
|
||||
affected_mob.adjustBrainLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Your try to remember something important...but can't.</span>")
|
||||
|
||||
@@ -44,7 +42,6 @@
|
||||
affected_mob.emote("drool")
|
||||
if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now
|
||||
affected_mob.adjustBrainLoss(3)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>Strange buzzing fills your head, removing all thoughts.</span>")
|
||||
if(prob(3))
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
to_chat(affected_mob, "<span class='danger'>Your stomach hurts.</span>")
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(4)
|
||||
if(!transformed && !carrier)
|
||||
//Save original dna for when the disease is cured.
|
||||
@@ -69,4 +68,4 @@
|
||||
affected_mob.domutcheck()
|
||||
|
||||
to_chat(affected_mob, "<span class='notice'>You feel more like yourself.</span>")
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
to_chat(affected_mob, "<span class='danger'>Your stomach hurts.</span>")
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
|
||||
if(3)
|
||||
if(affected_mob.lying && prob(15))
|
||||
@@ -50,5 +49,4 @@
|
||||
to_chat(affected_mob, "<span class='danger'>Your stomach hurts.</span>")
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
return
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
if(2)
|
||||
if(prob(45))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(3)
|
||||
@@ -32,7 +31,6 @@
|
||||
if(prob(10))
|
||||
affected_mob.emote("cough")
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(5)
|
||||
to_chat(affected_mob, "<span class='danger'>Your body feels as if it's trying to rip itself open...</span>")
|
||||
if(prob(50))
|
||||
@@ -50,4 +48,4 @@
|
||||
cure_chance = 10
|
||||
agent = "gibbis"
|
||||
spread_flags = NON_CONTAGIOUS
|
||||
disease_flags = CURABLE
|
||||
disease_flags = CURABLE
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
if(2)
|
||||
if(prob(45))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(1))
|
||||
to_chat(affected_mob, "<span class='danger'>You feel strange...</span>")
|
||||
if(3)
|
||||
@@ -35,8 +34,7 @@
|
||||
to_chat(affected_mob, "<span class='danger'>You feel a burning beat inside...</span>")
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(5)
|
||||
affected_mob.updatehealth()
|
||||
if(5)
|
||||
to_chat(affected_mob, "<span class='danger'>Your body is unable to contain the Rhumba Beat...</span>")
|
||||
if(prob(50))
|
||||
affected_mob.gib()
|
||||
affected_mob.gib()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
for(var/I in callees)
|
||||
var/obj/machinery/hologram/holopad/H = I
|
||||
if(!QDELETED(H) && !(H.stat & NOPOWER))
|
||||
if(!QDELETED(H) && !(H.stat & NOPOWER) && H.anchored)
|
||||
dialed_holopads += H
|
||||
var/area/area = get_area(H)
|
||||
LAZYADD(H.holo_calls, src)
|
||||
@@ -159,7 +159,7 @@
|
||||
/datum/holocall/proc/Check()
|
||||
for(var/I in dialed_holopads)
|
||||
var/obj/machinery/hologram/holopad/H = I
|
||||
if((H.stat & NOPOWER))
|
||||
if((H.stat & NOPOWER) || !H.anchored)
|
||||
ConnectionFailure(H)
|
||||
|
||||
if(QDELETED(src))
|
||||
|
||||
+233
-274
@@ -47,7 +47,7 @@
|
||||
var/role_alt_title
|
||||
|
||||
var/datum/job/assigned_job
|
||||
var/list/kills=list()
|
||||
var/list/kills = list()
|
||||
var/list/datum/objective/objectives = list()
|
||||
var/list/datum/objective/special_verbs = list()
|
||||
|
||||
@@ -78,9 +78,8 @@
|
||||
//zealot_master is a reference to the mob that converted them into a zealot (for ease of investigation and such)
|
||||
var/mob/living/carbon/human/zealot_master = null
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
src.key = key
|
||||
|
||||
/datum/mind/New(new_key)
|
||||
key = new_key
|
||||
|
||||
/datum/mind/Destroy()
|
||||
ticker.minds -= src
|
||||
@@ -122,19 +121,15 @@
|
||||
/datum/mind/proc/wipe_memory()
|
||||
memory = null
|
||||
|
||||
/datum/mind/proc/show_memory(mob/recipient, window=1)
|
||||
/datum/mind/proc/show_memory(mob/recipient, window = 1)
|
||||
if(!recipient)
|
||||
recipient = current
|
||||
var/output = "<B>[current.real_name]'s Memories:</B><HR>"
|
||||
output += memory
|
||||
|
||||
if(objectives.len)
|
||||
output += "<HR><B>Objectives:</B>"
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
output += "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
||||
obj_count++
|
||||
output += "<HR><B>Objectives:</B><BR>"
|
||||
output += gen_objective_text()
|
||||
|
||||
if(job_objectives.len)
|
||||
output += "<HR><B>Job Objectives:</B><UL>"
|
||||
@@ -145,17 +140,213 @@
|
||||
obj_count++
|
||||
output += "</UL>"
|
||||
if(window)
|
||||
recipient << browse(output,"window=memory")
|
||||
recipient << browse(output, "window=memory")
|
||||
else
|
||||
to_chat(recipient, "<i>[output]</i>")
|
||||
|
||||
/datum/mind/proc/gen_objective_text(admin = FALSE)
|
||||
. = ""
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
. += "<b>Objective #[obj_count]</b>: [objective.explanation_text]"
|
||||
if(admin)
|
||||
. += " <a href='?src=[UID()];obj_edit=\ref[objective]'>Edit</a> " // Edit
|
||||
. += "<a href='?src=[UID()];obj_delete=\ref[objective]'>Delete</a> " // Delete
|
||||
|
||||
. += "<a href='?src=[UID()];obj_completed=\ref[objective]'>" // Mark Completed
|
||||
. += "<font color=[objective.completed ? "green" : "red"]>Toggle Completion</font>"
|
||||
. += "</a>"
|
||||
. += "<br>"
|
||||
obj_count++
|
||||
|
||||
/datum/mind/proc/_memory_edit_header(gamemode, list/alt)
|
||||
. = gamemode
|
||||
if(ticker.mode.config_tag == gamemode || (LAZYLEN(alt) && (ticker.mode.config_tag in alt)))
|
||||
. = uppertext(.)
|
||||
. = "<i><b>[.]</b></i>: "
|
||||
|
||||
/datum/mind/proc/_memory_edit_role_enabled(role)
|
||||
. = "|Disabled in Prefs"
|
||||
if(current && current.client && (role in current.client.prefs.be_special))
|
||||
. = "|Enabled in Prefs"
|
||||
|
||||
/datum/mind/proc/memory_edit_implant(mob/living/carbon/human/H)
|
||||
if(ismindshielded(H))
|
||||
. = "Mindshield Implant:<a href='?src=[UID()];implant=remove'>Remove</a>|<b><font color='green'>Implanted</font></b></br>"
|
||||
else
|
||||
. = "Mindshield Implant:<b>No Implant</b>|<a href='?src=[UID()];implant=add'>Implant [H.p_them()]!</a></br>"
|
||||
|
||||
|
||||
/datum/mind/proc/memory_edit_revolution(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("revolution")
|
||||
if(ismindshielded(H))
|
||||
. += "<b>NO</b>|headrev|rev"
|
||||
else if(src in ticker.mode.head_revolutionaries)
|
||||
. += "<a href='?src=[UID()];revolution=clear'>no</a>|<b><font color='red'>HEADREV</font></b>|<a href='?src=[UID()];revolution=rev'>rev</a>"
|
||||
. += "<br>Flash: <a href='?src=[UID()];revolution=flash'>give</a>"
|
||||
|
||||
var/list/L = current.get_contents()
|
||||
var/obj/item/flash/flash = locate() in L
|
||||
if(flash)
|
||||
if(!flash.broken)
|
||||
. += "|<a href='?src=[UID()];revolution=takeflash'>take</a>."
|
||||
else
|
||||
. += "|<a href='?src=[UID()];revolution=takeflash'>take</a>|<a href='?src=[UID()];revolution=repairflash'>repair</a>."
|
||||
else
|
||||
. += "."
|
||||
|
||||
. += " <a href='?src=[UID()];revolution=reequip'>Reequip</a> (gives traitor uplink)."
|
||||
if(objectives.len==0)
|
||||
. += "<br>Objectives are empty! <a href='?src=[UID()];revolution=autoobjectives'>Set to kill all heads</a>."
|
||||
else if(src in ticker.mode.revolutionaries)
|
||||
. += "<a href='?src=[UID()];revolution=clear'>no</a>|<a href='?src=[UID()];revolution=headrev'>headrev</a>|<b><font color='red'>REV</font></b>"
|
||||
else
|
||||
. += "<b>NO</b>|<a href='?src=[UID()];revolution=headrev'>headrev</a>|<a href='?src=[UID()];revolution=rev'>rev</a>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_REV)
|
||||
|
||||
/datum/mind/proc/memory_edit_cult(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("cult")
|
||||
if(ismindshielded(H))
|
||||
. += "<B>NO</B>|cultist"
|
||||
else if(src in ticker.mode.cult)
|
||||
. += "<a href='?src=[UID()];cult=clear'>no</a>|<b><font color='red'>CULTIST</font></b>"
|
||||
. += "<br>Give <a href='?src=[UID()];cult=tome'>tome</a>|<a href='?src=[UID()];cult=equip'>equip</a>."
|
||||
else
|
||||
. += "<b>NO</b>|<a href='?src=[UID()];cult=cultist'>cultist</a>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_CULTIST)
|
||||
|
||||
/datum/mind/proc/memory_edit_wizard(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("wizard")
|
||||
if(src in ticker.mode.wizards)
|
||||
. += "<b><font color='red'>WIZARD</font></b>|<a href='?src=[UID()];wizard=clear'>no</a>"
|
||||
. += "<br><a href='?src=[UID()];wizard=lair'>To lair</a>, <a href='?src=[UID()];common=undress'>undress</a>, <a href='?src=[UID()];wizard=dressup'>dress up</a>, <a href='?src=[UID()];wizard=name'>let choose name</a>."
|
||||
if(objectives.len==0)
|
||||
. += "<br>Objectives are empty! <a href='?src=[UID()];wizard=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];wizard=wizard'>wizard</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_WIZARD)
|
||||
|
||||
/datum/mind/proc/memory_edit_changeling(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("changeling", list("traitorchan"))
|
||||
if(src in ticker.mode.changelings)
|
||||
. += "<b><font color='red'>CHANGELING</font></b>|<a href='?src=[UID()];changeling=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
. += "<br>Objectives are empty! <a href='?src=[UID()];changeling=autoobjectives'>Randomize!</a>"
|
||||
if(changeling && changeling.absorbed_dna.len && (current.real_name != changeling.absorbed_dna[1]))
|
||||
. += "<br><a href='?src=[UID()];changeling=initialdna'>Transform to initial appearance.</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];changeling=changeling'>changeling</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_CHANGELING)
|
||||
|
||||
/datum/mind/proc/memory_edit_vampire(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("vampire", list("traitorvamp"))
|
||||
if(src in ticker.mode.vampires)
|
||||
. += "<b><font color='red'>VAMPIRE</font></b>|<a href='?src=[UID()];vampire=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
. += "<br>Objectives are empty! <a href='?src=[UID()];vampire=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];vampire=vampire'>vampire</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_VAMPIRE)
|
||||
/** Enthralled ***/
|
||||
. += "<br><b><i>enthralled</i></b>: "
|
||||
if(src in ticker.mode.vampire_enthralled)
|
||||
. += "<b><font color='red'>THRALL</font></b>|<a href='?src=[UID()];vampthrall=clear'>no</a>"
|
||||
else
|
||||
. += "thrall|<b>NO</b>"
|
||||
|
||||
/datum/mind/proc/memory_edit_nuclear(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("nuclear")
|
||||
if(src in ticker.mode.syndicates)
|
||||
. += "<b><font color='red'>OPERATIVE</b></font>|<a href='?src=[UID()];nuclear=clear'>no</a>"
|
||||
. += "<br><a href='?src=[UID()];nuclear=lair'>To shuttle</a>, <a href='?src=[UID()];common=undress'>undress</a>, <a href='?src=[UID()];nuclear=dressup'>dress up</a>."
|
||||
var/code
|
||||
for(var/obj/machinery/nuclearbomb/bombue in machines)
|
||||
if(length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
|
||||
code = bombue.r_code
|
||||
break
|
||||
if(code)
|
||||
. += " Code is [code]. <a href='?src=[UID()];nuclear=tellcode'>tell the code.</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];nuclear=nuclear'>operative</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_OPERATIVE)
|
||||
|
||||
/datum/mind/proc/memory_edit_shadowling(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("shadowling")
|
||||
if(src in ticker.mode.shadows)
|
||||
. += "<b><font color='red'>SHADOWLING</font></b>|thrall|<a href='?src=[UID()];shadowling=clear'>no</a>"
|
||||
else if(src in ticker.mode.shadowling_thralls)
|
||||
. += "Shadowling|<b><font color='red'>THRALL</font></b>|<a href='?src=[UID()];shadowling=clear'>no</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];shadowling=shadowling'>shadowling</a>|<a href='?src=[UID()];shadowling=thrall'>thrall</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_SHADOWLING)
|
||||
|
||||
/datum/mind/proc/memory_edit_abductor(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("abductor")
|
||||
if(src in ticker.mode.abductors)
|
||||
. += "<b><font color='red'>ABDUCTOR</font></b>|<a href='?src=[UID()];abductor=clear'>no</a>"
|
||||
. += "|<a href='?src=[UID()];common=undress'>undress</a>|<a href='?src=[UID()];abductor=equip'>equip</a>"
|
||||
else
|
||||
. += "<a href='?src=[UID()];abductor=abductor'>abductor</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_ABDUCTOR)
|
||||
|
||||
/datum/mind/proc/memory_edit_traitor()
|
||||
. = _memory_edit_header("traitor", list("traitorchan", "traitorvamp"))
|
||||
if(src in ticker.mode.traitors)
|
||||
. += "<b><font color='red'>TRAITOR</font></b>|<a href='?src=[UID()];traitor=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
. += "<br>Objectives are empty! <a href='?src=[UID()];traitor=autoobjectives'>Randomize</a>!"
|
||||
else
|
||||
. += "<a href='?src=[UID()];traitor=traitor'>traitor</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_TRAITOR)
|
||||
|
||||
/datum/mind/proc/memory_edit_silicon()
|
||||
. = "<i><b>Silicon</b></i>: "
|
||||
var/mob/living/silicon/robot/robot = current
|
||||
if(istype(robot) && robot.emagged)
|
||||
. += "<br>Cyborg: <b><font color='red'>Is emagged!</font></b> <a href='?src=[UID()];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth_law]"
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
if(istype(ai) && ai.connected_robots.len)
|
||||
var/n_e_robots = 0
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
if(R.emagged)
|
||||
n_e_robots++
|
||||
. += "<br>[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. <a href='?src=[UID()];silicon=unemagcyborgs'>Unemag</a>"
|
||||
|
||||
/datum/mind/proc/memory_edit_uplink()
|
||||
. = ""
|
||||
if(ishuman(current) && ((src in ticker.mode.head_revolutionaries) || \
|
||||
(src in ticker.mode.traitors) || \
|
||||
(src in ticker.mode.syndicates)))
|
||||
. = "Uplink: <a href='?src=[UID()];common=uplink'>give</a>"
|
||||
var/obj/item/uplink/hidden/suplink = find_syndicate_uplink()
|
||||
var/crystals
|
||||
if(suplink)
|
||||
crystals = suplink.uses
|
||||
if(suplink)
|
||||
. += "|<a href='?src=[UID()];common=takeuplink'>take</a>"
|
||||
if(usr.client.holder.rights & (R_SERVER|R_EVENT))
|
||||
. += ", <a href='?src=[UID()];common=crystals'>[crystals]</a> crystals"
|
||||
else
|
||||
. += ", [crystals] crystals"
|
||||
. += "." //hiel grammar
|
||||
// ^ whoever left this comment is literally a grammar nazi. stalin better. in russia grammar correct you.
|
||||
|
||||
/datum/mind/proc/edit_memory()
|
||||
if(!ticker || !ticker.mode)
|
||||
alert("Not before round-start!", "Alert")
|
||||
return
|
||||
|
||||
var/out = "<B>[name]</B>[(current&&(current.real_name!=name))?" (as [current.real_name])":""]<br>"
|
||||
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
|
||||
var/out = "<B>[name]</B>[(current && (current.real_name != name))?" (as [current.real_name])" : ""]<br>"
|
||||
out += "Mind currently owned by key: [key] [active ? "(synced)" : "(not synced)"]<br>"
|
||||
out += "Assigned role: [assigned_role]. <a href='?src=[UID()];role_edit=1'>Edit</a><br>"
|
||||
out += "Factions and special roles:<br>"
|
||||
|
||||
@@ -169,284 +360,60 @@
|
||||
"nuclear",
|
||||
"traitor", // "traitorchan",
|
||||
)
|
||||
var/text = ""
|
||||
var/mob/living/carbon/human/H = current
|
||||
if(ishuman(current))
|
||||
/** Impanted**/
|
||||
if(ismindshielded(H))
|
||||
text = "Mindshield Implant:<a href='?src=[UID()];implant=remove'>Remove</a>|<b><font color='green'>Implanted</font></b></br>"
|
||||
else
|
||||
text = "Mindshield Implant:<b>No Implant</b>|<a href='?src=[UID()];implant=add'>Implant [H.p_them()]!</a></br>"
|
||||
sections["implant"] = text
|
||||
sections["implant"] = memory_edit_implant(H)
|
||||
/** REVOLUTION ***/
|
||||
text = "revolution"
|
||||
if(ticker.mode.config_tag=="revolution")
|
||||
text += uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(ismindshielded(H))
|
||||
text += "<b>NO</b>|headrev|rev"
|
||||
else if(src in ticker.mode.head_revolutionaries)
|
||||
text += "<a href='?src=[UID()];revolution=clear'>no</a>|<b><font color='red'>HEADREV</font></b>|<a href='?src=[UID()];revolution=rev'>rev</a>"
|
||||
text += "<br>Flash: <a href='?src=[UID()];revolution=flash'>give</a>"
|
||||
|
||||
var/list/L = current.get_contents()
|
||||
var/obj/item/flash/flash = locate() in L
|
||||
if(flash)
|
||||
if(!flash.broken)
|
||||
text += "|<a href='?src=[UID()];revolution=takeflash'>take</a>."
|
||||
else
|
||||
text += "|<a href='?src=[UID()];revolution=takeflash'>take</a>|<a href='?src=[UID()];revolution=repairflash'>repair</a>."
|
||||
else
|
||||
text += "."
|
||||
|
||||
text += " <a href='?src=[UID()];revolution=reequip'>Reequip</a> (gives traitor uplink)."
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=[UID()];revolution=autoobjectives'>Set to kill all heads</a>."
|
||||
else if(src in ticker.mode.revolutionaries)
|
||||
text += "<a href='?src=[UID()];revolution=clear'>no</a>|<a href='?src=[UID()];revolution=headrev'>headrev</a>|<b><font color='red'>REV</font></b>"
|
||||
else
|
||||
text += "<b>NO</b>|<a href='?src=[UID()];revolution=headrev'>headrev</a>|<a href='?src=[UID()];revolution=rev'>rev</a>"
|
||||
|
||||
if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["revolution"] = text
|
||||
|
||||
sections["revolution"] = memory_edit_revolution(H)
|
||||
/** CULT ***/
|
||||
text = "cult"
|
||||
if(ticker.mode.config_tag=="cult")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(ismindshielded(H))
|
||||
text += "<B>NO</B>|cultist"
|
||||
else if(src in ticker.mode.cult)
|
||||
text += "<a href='?src=[UID()];cult=clear'>no</a>|<b><font color='red'>CULTIST</font></b>"
|
||||
text += "<br>Give <a href='?src=[UID()];cult=tome'>tome</a>|<a href='?src=[UID()];cult=equip'>equip</a>."
|
||||
/*
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! Set to sacrifice and <a href='?src=[UID()];cult=escape'>escape</a> or <a href='?src=[UID()];cult=summon'>summon</a>."
|
||||
*/
|
||||
else
|
||||
text += "<b>NO</b>|<a href='?src=[UID()];cult=cultist'>cultist</a>"
|
||||
|
||||
|
||||
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["cult"] = text
|
||||
|
||||
sections["cult"] = memory_edit_cult(H)
|
||||
/** WIZARD ***/
|
||||
text = "wizard"
|
||||
if(ticker.mode.config_tag=="wizard")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.wizards)
|
||||
text += "<b><font color='red'>WIZARD</font></b>|<a href='?src=[UID()];wizard=clear'>no</a>"
|
||||
text += "<br><a href='?src=[UID()];wizard=lair'>To lair</a>, <a href='?src=[UID()];common=undress'>undress</a>, <a href='?src=[UID()];wizard=dressup'>dress up</a>, <a href='?src=[UID()];wizard=name'>let choose name</a>."
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=[UID()];wizard=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];wizard=wizard'>wizard</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["wizard"] = text
|
||||
|
||||
sections["wizard"] = memory_edit_wizard(H)
|
||||
/** CHANGELING ***/
|
||||
text = "changeling"
|
||||
if(ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.changelings)
|
||||
text += "<b><font color='red'>CHANGELING</font></b>|<a href='?src=[UID()];changeling=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=[UID()];changeling=autoobjectives'>Randomize!</a>"
|
||||
if( changeling && changeling.absorbed_dna.len && (current.real_name != changeling.absorbed_dna[1]) )
|
||||
text += "<br><a href='?src=[UID()];changeling=initialdna'>Transform to initial appearance.</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];changeling=changeling'>changeling</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["changeling"] = text
|
||||
|
||||
sections["changeling"] = memory_edit_changeling(H)
|
||||
/** VAMPIRE ***/
|
||||
text = "vampire"
|
||||
if(ticker.mode.config_tag=="vampire" || ticker.mode.config_tag=="traitorvamp")
|
||||
text = uppertext(text)
|
||||
text = "<b><i>[text]</i></b>: "
|
||||
if(src in ticker.mode.vampires)
|
||||
text += "<b><font color='red'>VAMPIRE</font></b>|<a href='?src=[UID()];vampire=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=[UID()];vampire=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];vampire=vampire'>vampire</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_VAMPIRE in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
/** Enthralled ***/
|
||||
text += "<br><b><i>enthralled</i></b>: "
|
||||
if(src in ticker.mode.vampire_enthralled)
|
||||
text += "<b><font color='red'>THRALL</font></b>|<a href='?src=[UID()];vampthrall=clear'>no</a>"
|
||||
else
|
||||
text += "thrall|<b>NO</b>"
|
||||
|
||||
sections["vampire"] = text
|
||||
|
||||
|
||||
sections["vampire"] = memory_edit_vampire(H)
|
||||
/** NUCLEAR ***/
|
||||
text = "nuclear"
|
||||
if(ticker.mode.config_tag=="nuclear")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.syndicates)
|
||||
text += "<b><font color='red'>OPERATIVE</b></font>|<a href='?src=[UID()];nuclear=clear'>no</a>"
|
||||
text += "<br><a href='?src=[UID()];nuclear=lair'>To shuttle</a>, <a href='?src=[UID()];common=undress'>undress</a>, <a href='?src=[UID()];nuclear=dressup'>dress up</a>."
|
||||
var/code
|
||||
for(var/obj/machinery/nuclearbomb/bombue in machines)
|
||||
if(length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
|
||||
code = bombue.r_code
|
||||
break
|
||||
if(code)
|
||||
text += " Code is [code]. <a href='?src=[UID()];nuclear=tellcode'>tell the code.</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];nuclear=nuclear'>operative</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["nuclear"] = text
|
||||
|
||||
sections["nuclear"] = memory_edit_nuclear(H)
|
||||
/** SHADOWLING **/
|
||||
text = "shadowling"
|
||||
if(ticker.mode.config_tag == "shadowling")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.shadows)
|
||||
text += "<b><font color='red'>SHADOWLING</font></b>|thrall|<a href='?src=[UID()];shadowling=clear'>no</a>"
|
||||
else if(src in ticker.mode.shadowling_thralls)
|
||||
text += "Shadowling|<b><font color='red'>THRALL</font></b>|<a href='?src=[UID()];shadowling=clear'>no</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];shadowling=shadowling'>shadowling</a>|<a href='?src=[UID()];shadowling=thrall'>thrall</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_SHADOWLING in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["shadowling"] = text
|
||||
|
||||
sections["shadowling"] = memory_edit_shadowling(H)
|
||||
/** Abductors **/
|
||||
|
||||
text = "abductor"
|
||||
if(ticker.mode.config_tag == "abductor")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.abductors)
|
||||
text += "<b><font color='red'>ABDUCTOR</font></b>|<a href='?src=[UID()];abductor=clear'>no</a>"
|
||||
text += "|<a href='?src=[UID()];common=undress'>undress</a>|<a href='?src=[UID()];abductor=equip'>equip</a>"
|
||||
else
|
||||
text += "<a href='?src=[UID()];abductor=abductor'>abductor</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
|
||||
sections["Abductor"] = text
|
||||
|
||||
sections["abductor"] = memory_edit_abductor(H)
|
||||
/** TRAITOR ***/
|
||||
text = "traitor"
|
||||
if(ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan" || ticker.mode.config_tag=="traitorvamp")
|
||||
text = uppertext(text)
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if(src in ticker.mode.traitors)
|
||||
text += "<b><font color='red'>TRAITOR</font></b>|<a href='?src=[UID()];traitor=clear'>no</a>"
|
||||
if(objectives.len==0)
|
||||
text += "<br>Objectives are empty! <a href='?src=[UID()];traitor=autoobjectives'>Randomize</a>!"
|
||||
else
|
||||
text += "<a href='?src=[UID()];traitor=traitor'>traitor</a>|<b>NO</b>"
|
||||
|
||||
if(current && current.client && (ROLE_TRAITOR in current.client.prefs.be_special))
|
||||
text += "|Enabled in Prefs"
|
||||
else
|
||||
text += "|Disabled in Prefs"
|
||||
|
||||
sections["traitor"] = text
|
||||
|
||||
sections["traitor"] = memory_edit_traitor()
|
||||
/** SILICON ***/
|
||||
|
||||
if(issilicon(current))
|
||||
text = "silicon"
|
||||
var/mob/living/silicon/robot/robot = current
|
||||
if(istype(robot) && robot.emagged)
|
||||
text += "<br>Cyborg: <b><font color='red'>Is emagged!</font></b> <a href='?src=[UID()];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth_law]"
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
if(istype(ai) && ai.connected_robots.len)
|
||||
var/n_e_robots = 0
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
if(R.emagged)
|
||||
n_e_robots++
|
||||
text += "<br>[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. <a href='?src=[UID()];silicon=unemagcyborgs'>Unemag</a>"
|
||||
|
||||
sections["silicon"] = memory_edit_silicon()
|
||||
/*
|
||||
This prioritizes antags relevant to the current round to make them appear at the top of the panel.
|
||||
Traitorchan and traitorvamp are snowflaked in because they have multiple sections.
|
||||
*/
|
||||
if(ticker.mode.config_tag == "traitorchan")
|
||||
if(sections["traitor"])
|
||||
out += sections["traitor"]+"<br>"
|
||||
out += sections["traitor"] + "<br>"
|
||||
if(sections["changeling"])
|
||||
out += sections["changeling"]+"<br>"
|
||||
out += sections["changeling"] + "<br>"
|
||||
sections -= "traitor"
|
||||
sections -= "changeling"
|
||||
|
||||
if(ticker.mode.config_tag == "traitorvamp")
|
||||
// Elif technically unnecessary but it makes the following else look better
|
||||
else if(ticker.mode.config_tag == "traitorvamp")
|
||||
if(sections["traitor"])
|
||||
out += sections["traitor"]+"<br>"
|
||||
out += sections["traitor"] + "<br>"
|
||||
if(sections["vampire"])
|
||||
out += sections["vampire"]+"<br>"
|
||||
out += sections["vampire"] + "<br>"
|
||||
sections -= "traitor"
|
||||
sections -= "vampire"
|
||||
else
|
||||
if(sections[ticker.mode.config_tag])
|
||||
out += sections[ticker.mode.config_tag]+"<br>"
|
||||
out += sections[ticker.mode.config_tag] + "<br>"
|
||||
sections -= ticker.mode.config_tag
|
||||
|
||||
for(var/i in sections)
|
||||
if(sections[i])
|
||||
out += sections[i]+"<br>"
|
||||
|
||||
|
||||
if(((src in ticker.mode.head_revolutionaries) || \
|
||||
(src in ticker.mode.traitors) || \
|
||||
(src in ticker.mode.syndicates)) && \
|
||||
ishuman(current) )
|
||||
|
||||
text = "Uplink: <a href='?src=[UID()];common=uplink'>give</a>"
|
||||
var/obj/item/uplink/hidden/suplink = find_syndicate_uplink()
|
||||
var/crystals
|
||||
if(suplink)
|
||||
crystals = suplink.uses
|
||||
if(suplink)
|
||||
text += "|<a href='?src=[UID()];common=takeuplink'>take</a>"
|
||||
if(usr.client.holder.rights & (R_SERVER|R_EVENT))
|
||||
text += ", <a href='?src=[UID()];common=crystals'>[crystals]</a> crystals"
|
||||
else
|
||||
text += ", [crystals] crystals"
|
||||
text += "." //hiel grammar
|
||||
out += text
|
||||
out += sections[i] + "<br>"
|
||||
|
||||
out += memory_edit_uplink()
|
||||
out += "<br>"
|
||||
|
||||
out += "<b>Memory:</b><br>"
|
||||
@@ -456,14 +423,9 @@
|
||||
if(objectives.len == 0)
|
||||
out += "EMPTY<br>"
|
||||
else
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
out += "<B>[obj_count]</B>: [objective.explanation_text] <a href='?src=[UID()];obj_edit=\ref[objective]'>Edit</a> <a href='?src=[UID()];obj_delete=\ref[objective]'>Delete</a> <a href='?src=[UID()];obj_completed=\ref[objective]'><font color=[objective.completed ? "green" : "red"]>Toggle Completion</font></a><br>"
|
||||
obj_count++
|
||||
out += gen_objective_text(admin = TRUE)
|
||||
out += "<a href='?src=[UID()];obj_add=1'>Add objective</a><br><br>"
|
||||
|
||||
out += "<a href='?src=[UID()];obj_announce=1'>Announce objectives</a><br><br>"
|
||||
|
||||
usr << browse(out, "window=edit_memory[src];size=400x500")
|
||||
|
||||
/datum/mind/Topic(href, href_list)
|
||||
@@ -1284,12 +1246,9 @@
|
||||
return A
|
||||
|
||||
/datum/mind/proc/announce_objectives()
|
||||
var/obj_count = 1
|
||||
to_chat(current, "<span class='notice'>Your current objectives:</span>")
|
||||
for(var/objective in objectives)
|
||||
var/datum/objective/O = objective
|
||||
to_chat(current, "<B>Objective #[obj_count]</B>: [O.explanation_text]")
|
||||
obj_count++
|
||||
for(var/line in splittext(gen_objective_text(), "<br>"))
|
||||
to_chat(current, line)
|
||||
|
||||
/datum/mind/proc/find_syndicate_uplink()
|
||||
var/list/L = current.get_contents()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
for(var/i in 1 to number)
|
||||
H.equip_to_slot_or_del(new path(H), slot_in_backpack)
|
||||
H.equip_or_collect(new path(H), slot_in_backpack)
|
||||
|
||||
for(var/path in cybernetic_implants)
|
||||
var/obj/item/organ/internal/O = new path(H)
|
||||
|
||||
@@ -65,12 +65,12 @@
|
||||
lakey = sanitizeSQL(H.lastattacker:key)
|
||||
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
|
||||
var/coord = "[H.x], [H.y], [H.z]"
|
||||
// to_chat(world, "INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
|
||||
// to_chat(world, "INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.getBrainLoss()], [H.getOxyLoss()])")
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
log_game("SQL ERROR during death reporting. Failed to connect.")
|
||||
else
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.getBrainLoss()], [H.getOxyLoss()], '[coord]')")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
@@ -105,7 +105,7 @@
|
||||
if(!dbcon.IsConnected())
|
||||
log_game("SQL ERROR during death reporting. Failed to connect.")
|
||||
else
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.getBrainLoss()], [H.getOxyLoss()], '[coord]')")
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
|
||||
@@ -27,7 +27,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "unknown"
|
||||
layer = AREA_LAYER
|
||||
luminosity = 0
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
var/valid_territory = TRUE //used for cult summoning areas on station zlevel
|
||||
var/map_name // Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
|
||||
|
||||
@@ -132,14 +132,14 @@
|
||||
if(!fire)
|
||||
fire = 1 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_close()
|
||||
|
||||
/area/proc/fire_reset()
|
||||
if(fire)
|
||||
fire = 0 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_open()
|
||||
|
||||
return
|
||||
@@ -165,7 +165,7 @@
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = 1
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/area/proc/readyalert()
|
||||
if(!eject)
|
||||
@@ -181,12 +181,12 @@
|
||||
if(!party)
|
||||
party = 1
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/area/proc/partyreset()
|
||||
if(party)
|
||||
party = 0
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
updateicon()
|
||||
|
||||
/area/proc/updateicon()
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
|
||||
var/initialized = FALSE
|
||||
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
var/list/remove_overlays // a very temporary list of overlays to remove
|
||||
var/list/add_overlays // a very temporary list of overlays to add
|
||||
|
||||
/atom/New(loc, ...)
|
||||
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
_preloader.load(src)
|
||||
@@ -83,6 +87,9 @@
|
||||
if(opacity && isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways.
|
||||
|
||||
if(loc)
|
||||
loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs.
|
||||
|
||||
ComponentInitialize()
|
||||
|
||||
@@ -97,6 +104,8 @@
|
||||
/atom/proc/ComponentInitialize()
|
||||
return
|
||||
|
||||
/atom/proc/InitializedOn(atom/A) // Proc for when something is initialized on a atom - Optional to call. Useful for observer pattern etc.
|
||||
return
|
||||
|
||||
/atom/proc/onCentcom()
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -137,6 +146,8 @@
|
||||
|
||||
QDEL_NULL(reagents)
|
||||
invisibility = 101
|
||||
LAZYCLEARLIST(overlays)
|
||||
LAZYCLEARLIST(priority_overlays)
|
||||
return ..()
|
||||
|
||||
//Hook for running code when a dir change occurs
|
||||
|
||||
@@ -159,6 +159,14 @@
|
||||
/datum/dna/gene/disability/nearsighted/New()
|
||||
block=GLASSESBLOCK
|
||||
|
||||
/datum/dna/gene/disability/nearsighted/activate(mob/living/M, connected, flags)
|
||||
. = ..()
|
||||
M.update_nearsighted_effects()
|
||||
|
||||
/datum/dna/gene/disability/nearsighted/deactivate(mob/living/M, connected, flags)
|
||||
. = ..()
|
||||
M.update_nearsighted_effects()
|
||||
|
||||
/datum/dna/gene/disability/lisp
|
||||
name = "Lisp"
|
||||
desc = "I wonder wath thith doeth."
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
affecting = H.bodyparts_by_name[name]
|
||||
if(!istype(affecting, /obj/item/organ/external))
|
||||
continue
|
||||
affecting.heal_damage(4, 0)
|
||||
affecting.heal_damage(4, 0, updating_health = FALSE)
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
|
||||
|
||||
@@ -97,7 +97,10 @@
|
||||
loc.visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed)
|
||||
..()
|
||||
// Only execute the below if we successfuly died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
// On death, create a small smoke of harmful gas (s-Acid)
|
||||
var/datum/effect_system/smoke_spread/chem/S = new
|
||||
var/turf/location = get_turf(src)
|
||||
@@ -178,5 +181,8 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed)
|
||||
..()
|
||||
// Only execute the below if we successfully died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
flick("blobbernaut_death", src)
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
if(!D)
|
||||
return
|
||||
|
||||
H.set_species(D.species.type)
|
||||
H.set_species(D.species.type, retain_damage = TRUE)
|
||||
H.dna = D.Clone()
|
||||
H.real_name = D.real_name
|
||||
domutcheck(H, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
user.emote("deathgasp")
|
||||
user.timeofdeath = world.time
|
||||
user.status_flags |= FAKEDEATH //play dead
|
||||
user.update_stat("fakedeath sting")
|
||||
user.update_canmove()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME)
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
for(var/i in 1 to healing_ticks)
|
||||
if(user)
|
||||
var/healpertick = -(total_healing / healing_ticks)
|
||||
user.heal_overall_damage((-healpertick/recent_uses), (-healpertick/recent_uses))
|
||||
user.adjustOxyLoss(healpertick/recent_uses)
|
||||
user.heal_overall_damage((-healpertick/recent_uses), (-healpertick/recent_uses), updating_health = FALSE)
|
||||
user.adjustOxyLoss(healpertick/recent_uses, FALSE)
|
||||
user.blood_volume = min(user.blood_volume + 30, BLOOD_VOLUME_NORMAL)
|
||||
user.updatehealth()
|
||||
else
|
||||
|
||||
@@ -6,22 +6,22 @@
|
||||
|
||||
//Revive from regenerative stasis
|
||||
/obj/effect/proc_holder/changeling/revive/sting_action(var/mob/living/carbon/user)
|
||||
user.setToxLoss(0)
|
||||
user.setOxyLoss(0)
|
||||
user.setCloneLoss(0)
|
||||
user.setBrainLoss(0)
|
||||
user.SetParalysis(0)
|
||||
user.SetStunned(0)
|
||||
user.SetWeakened(0)
|
||||
user.setToxLoss(0, FALSE)
|
||||
user.setOxyLoss(0, FALSE)
|
||||
user.setCloneLoss(0, FALSE)
|
||||
user.setBrainLoss(0, FALSE)
|
||||
user.SetParalysis(0, FALSE)
|
||||
user.SetStunned(0, FALSE)
|
||||
user.SetWeakened(0, FALSE)
|
||||
user.radiation = 0
|
||||
user.SetEyeBlind(0)
|
||||
user.SetEyeBlurry(0)
|
||||
user.SetEyeBlind(0, FALSE)
|
||||
user.SetEyeBlurry(0, FALSE)
|
||||
user.SetEarDamage(0)
|
||||
user.SetEarDeaf(0)
|
||||
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss())
|
||||
user.CureBlind()
|
||||
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss(), updating_health = FALSE)
|
||||
user.CureBlind(FALSE)
|
||||
user.CureDeaf()
|
||||
user.CureNearsighted()
|
||||
user.CureNearsighted(FALSE)
|
||||
user.reagents.clear_reagents()
|
||||
user.germ_level = 0
|
||||
user.timeofdeath = 0
|
||||
@@ -52,7 +52,9 @@
|
||||
IO.rejuvenate()
|
||||
IO.trace_chemicals.Cut()
|
||||
H.remove_all_embedded_objects()
|
||||
H.updatehealth()
|
||||
user.updatehealth()
|
||||
user.update_blind_effects()
|
||||
user.update_blurry_effects()
|
||||
|
||||
to_chat(user, "<span class='notice'>We have regenerated.</span>")
|
||||
|
||||
|
||||
@@ -210,9 +210,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
L.adjustBruteLoss(-1)
|
||||
L.adjustFireLoss(-1)
|
||||
L.updatehealth()
|
||||
L.heal_overall_damage(1, 1)
|
||||
if(istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct))
|
||||
var/mob/living/simple_animal/M = L
|
||||
if(M.health < M.maxHealth)
|
||||
|
||||
@@ -487,7 +487,7 @@ var/list/teleport_runes = list()
|
||||
icon_state = "rune_large"
|
||||
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
|
||||
pixel_y = -32
|
||||
mouse_opacity = 1 //we're huge and easy to click
|
||||
mouse_opacity = MOUSE_OPACITY_ICON //we're huge and easy to click
|
||||
scribe_delay = 450 //how long the rune takes to create
|
||||
scribe_damage = 40.1 //how much damage you take doing it
|
||||
var/used
|
||||
@@ -1031,7 +1031,7 @@ var/list/teleport_runes = list()
|
||||
N.desc = "A weak shield summoned by cultists to protect them while they carry out delicate rituals"
|
||||
N.color = "red"
|
||||
N.health = 20
|
||||
N.mouse_opacity = 0
|
||||
N.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
new_human.key = ghost_to_spawn.key
|
||||
ticker.mode.add_cultist(new_human.mind, 0)
|
||||
summoned_guys |= new_human
|
||||
|
||||
@@ -256,7 +256,7 @@ var/round_start_time = 0
|
||||
cinematic.icon = 'icons/effects/station_explosion.dmi'
|
||||
cinematic.icon_state = "station_intact"
|
||||
cinematic.layer = 21
|
||||
cinematic.mouse_opacity = 0
|
||||
cinematic.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
cinematic.screen_loc = "1,0"
|
||||
|
||||
var/obj/structure/stool/bed/temp_buckle = new(src)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
to_chat(src, "<span class='danger'>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</span>")
|
||||
to_chat(B.host, "<span class='danger'>You feel the captive mind of [src] begin to resist your control.</span>")
|
||||
|
||||
var/delay = (rand(350,450) + B.host.brainloss)
|
||||
var/delay = (rand(350,450) + B.host.getBrainLoss())
|
||||
addtimer(CALLBACK(src, .proc/return_control, B), delay)
|
||||
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@
|
||||
anchored = 1
|
||||
unacidable = 1
|
||||
light_range = 1
|
||||
mouse_opacity = 1
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
var/health = 30
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
var/lon_range = 1
|
||||
|
||||
@@ -90,7 +90,10 @@
|
||||
snapback()
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/death(gibbed)
|
||||
..()
|
||||
// Only execute the below if we successfully died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
to_chat(summoner, "<span class='danger'>Your [name] died somehow!</span>")
|
||||
summoner.death()
|
||||
|
||||
|
||||
@@ -124,16 +124,19 @@
|
||||
morph_time = world.time + MORPH_COOLDOWN
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/death(gibbed)
|
||||
if(morphed)
|
||||
visible_message("<span class='warning'>[src] twists and dissolves into a pile of green flesh!</span>", \
|
||||
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
|
||||
restore()
|
||||
if(gibbed)
|
||||
. = ..()
|
||||
if(stat == DEAD && gibbed)
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(loc)
|
||||
if(prob(90))
|
||||
step(AM, pick(alldirs))
|
||||
..(gibbed)
|
||||
// Only execute the below if we successfully died
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(morphed)
|
||||
visible_message("<span class='warning'>[src] twists and dissolves into a pile of green flesh!</span>", \
|
||||
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
|
||||
restore()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/Aggro() // automated only
|
||||
..()
|
||||
|
||||
@@ -161,15 +161,18 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/dust()
|
||||
death()
|
||||
. = death()
|
||||
|
||||
/mob/living/simple_animal/revenant/gib()
|
||||
death()
|
||||
. = death()
|
||||
|
||||
/mob/living/simple_animal/revenant/death()
|
||||
..()
|
||||
if(!revealed)
|
||||
return
|
||||
return FALSE
|
||||
// Only execute the below if we successfully died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
ghost_darkness_images -= ghostimage
|
||||
updateallghostimages()
|
||||
|
||||
@@ -190,7 +193,6 @@
|
||||
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
|
||||
ghostize()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/nullrod))
|
||||
|
||||
@@ -96,10 +96,15 @@
|
||||
desc = "A repulsive pile of guts and gore."
|
||||
|
||||
/mob/living/simple_animal/slaughter/death(gibbed)
|
||||
// Only execute the below if we successfully died
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
for(var/mob/living/M in consumed_mobs)
|
||||
M.forceMove(get_turf(src))
|
||||
..()
|
||||
release_consumed(M)
|
||||
|
||||
/mob/living/simple_animal/slaughter/proc/release_consumed(mob/living/M)
|
||||
M.forceMove(get_turf(src))
|
||||
|
||||
/mob/living/simple_animal/slaughter/phasein()
|
||||
. = ..()
|
||||
@@ -297,13 +302,12 @@
|
||||
deathmessage = "fades out, as all of its friends are released from its prison of hugs."
|
||||
loot = list(/mob/living/simple_animal/pet/cat/kitten{name = "Laughter"})
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/death(gibbed)
|
||||
for(var/mob/living/M in consumed_mobs)
|
||||
if(M.revive())
|
||||
M.grab_ghost(force = TRUE)
|
||||
playsound(get_turf(src), feast_sound, 50, 1, -1)
|
||||
to_chat(M, "<span class='clown'>You leave the [src]'s warm embrace, and feel ready to take on the world.</span>")
|
||||
..()
|
||||
/mob/living/simple_animal/slaughter/laughter/release_consumed(mob/living/M)
|
||||
if(M.revive())
|
||||
M.grab_ghost(force = TRUE)
|
||||
playsound(get_turf(src), feast_sound, 50, 1, -1)
|
||||
to_chat(M, "<span class='clown'>You leave the [src]'s warm embrace, and feel ready to take on the world.</span>")
|
||||
..(M)
|
||||
|
||||
|
||||
//Objectives and helpers.
|
||||
@@ -345,4 +349,4 @@
|
||||
..()
|
||||
|
||||
/datum/objective/demonFluff/check_completion()
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -493,18 +493,19 @@
|
||||
metabolization_rate = 100 //lel
|
||||
|
||||
/datum/reagent/shadowling_blindness_smoke/on_mob_life(mob/living/M)
|
||||
var/update_flags = STATUS_UPDATE_NONE
|
||||
if(!is_shadow_or_thrall(M))
|
||||
to_chat(M, "<span class='warning'><b>You breathe in the black smoke, and your eyes burn horribly!</b></span>")
|
||||
M.EyeBlind(5)
|
||||
update_flags |= M.EyeBlind(5, FALSE)
|
||||
if(prob(25))
|
||||
M.visible_message("<b>[M]</b> claws at [M.p_their()] eyes!")
|
||||
M.Stun(3)
|
||||
else
|
||||
to_chat(M, "<span class='notice'><b>You breathe in the black smoke, and you feel revitalized!</b></span>")
|
||||
M.heal_organ_damage(2,2)
|
||||
M.adjustOxyLoss(-2)
|
||||
M.adjustToxLoss(-2)
|
||||
..()
|
||||
update_flags |= M.heal_organ_damage(2, 2, updating_health = FALSE)
|
||||
update_flags |= M.adjustOxyLoss(-2, FALSE)
|
||||
update_flags |= M.adjustToxLoss(-2, FALSE)
|
||||
return ..() | update_flags
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech
|
||||
name = "Sonic Screech"
|
||||
|
||||
@@ -264,9 +264,6 @@
|
||||
maim_clone(H)
|
||||
H.Paralyse(4)
|
||||
|
||||
//Here let's calculate their health so the pod doesn't immediately eject them!!!
|
||||
H.updatehealth()
|
||||
|
||||
if(grab_ghost_when == CLONER_FRESH_CLONE)
|
||||
clonemind.transfer_to(H)
|
||||
H.ckey = R.ckey
|
||||
@@ -555,7 +552,7 @@
|
||||
qdel(i)
|
||||
missing_organs.Cut()
|
||||
|
||||
H.setCloneLoss(CLONE_INITIAL_DAMAGE)
|
||||
H.setCloneLoss(CLONE_INITIAL_DAMAGE, FALSE)
|
||||
H.setBrainLoss(BRAIN_INITIAL_DAMAGE)
|
||||
|
||||
for(var/o in H.internal_organs)
|
||||
@@ -578,6 +575,7 @@
|
||||
missing_organs += I
|
||||
|
||||
organs_number = LAZYLEN(missing_organs)
|
||||
H.updatehealth()
|
||||
|
||||
/obj/machinery/clonepod/proc/check_brine()
|
||||
// Clones are in a pickled bath of mild chemicals, keeping
|
||||
|
||||
@@ -64,21 +64,19 @@
|
||||
return 1
|
||||
|
||||
if(href_list["fix"])
|
||||
src.active = 1
|
||||
while(src.occupant.health < 100)
|
||||
src.occupant.adjustOxyLoss(-1)
|
||||
src.occupant.adjustFireLoss(-1)
|
||||
src.occupant.adjustToxLoss(-1)
|
||||
src.occupant.adjustBruteLoss(-1)
|
||||
src.occupant.updatehealth()
|
||||
if(src.occupant.health >= 0 && src.occupant.stat == 2)
|
||||
src.occupant.stat = 0
|
||||
src.occupant.lying = 0
|
||||
dead_mob_list -= src.occupant
|
||||
living_mob_list += src.occupant
|
||||
active = 1
|
||||
while(occupant.health < 100)
|
||||
occupant.adjustOxyLoss(-1, FALSE)
|
||||
occupant.adjustFireLoss(-1, FALSE)
|
||||
occupant.adjustToxLoss(-1, FALSE)
|
||||
occupant.adjustBruteLoss(-1, FALSE)
|
||||
occupant.updatehealth()
|
||||
if(occupant.health >= 0 && occupant.stat == DEAD)
|
||||
occupant.update_revive()
|
||||
occupant.lying = 0
|
||||
sleep(10)
|
||||
src.active = 0
|
||||
src.add_fingerprint(usr)
|
||||
active = 0
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["wireless"])
|
||||
var/wireless = text2num(href_list["wireless"])
|
||||
|
||||
@@ -296,6 +296,15 @@
|
||||
/obj/item/circuitboard/white_ship
|
||||
name = "circuit Board (White Ship)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship
|
||||
/obj/item/circuitboard/shuttle/syndicate
|
||||
name = "circuit board (Syndicate Shuttle)"
|
||||
build_path = /obj/machinery/computer/shuttle/syndicate
|
||||
/obj/item/circuitboard/shuttle/syndicate/recall
|
||||
name = "circuit board (Syndicate Shuttle Recall Terminal)"
|
||||
build_path = /obj/machinery/computer/shuttle/syndicate/recall
|
||||
/obj/item/circuitboard/shuttle/syndicate/drop_pod
|
||||
name = "circuit board (Syndicate Drop Pod)"
|
||||
build_path = /obj/machinery/computer/shuttle/syndicate/drop_pod
|
||||
|
||||
|
||||
/obj/item/circuitboard/HolodeckControl
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
// Check if camera is accessible when jumping
|
||||
/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C, var/mob/M)
|
||||
if(CanUseTopic(M, default_state) != STATUS_INTERACTIVE || M.incapacitated() || M.blinded)
|
||||
if(CanUseTopic(M, default_state) != STATUS_INTERACTIVE || M.incapacitated() || !M.has_vision())
|
||||
return 0
|
||||
|
||||
if(isrobot(M))
|
||||
@@ -361,4 +361,4 @@
|
||||
icon_screen = "engie_cams"
|
||||
light_color = "#FAC54B"
|
||||
network = list("Power Alarms","Atmosphere Alarms","Fire Alarms")
|
||||
circuit = /obj/item/circuitboard/camera/engineering
|
||||
circuit = /obj/item/circuitboard/camera/engineering
|
||||
|
||||
@@ -385,7 +385,7 @@
|
||||
occupant.adjustToxLoss(max(-efficiency, (-20*(efficiency ** 2)) / occupant.getToxLoss()))
|
||||
var/heal_brute = occupant.getBruteLoss() ? min(efficiency, 20*(efficiency**2) / occupant.getBruteLoss()) : 0
|
||||
var/heal_fire = occupant.getFireLoss() ? min(efficiency, 20*(efficiency**2) / occupant.getFireLoss()) : 0
|
||||
occupant.heal_organ_damage(heal_brute,heal_fire)
|
||||
occupant.heal_organ_damage(heal_brute, heal_fire)
|
||||
if(beaker && next_trans == 0)
|
||||
var/proportion = 10 * min(1/beaker.volume, 1)
|
||||
// Yes, this means you can get more bang for your buck with a beaker of SF vs a patch
|
||||
|
||||
@@ -313,15 +313,14 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/update_icon(state=0, override=0)
|
||||
if(operating && !override)
|
||||
return
|
||||
icon_state = density ? "closed" : "open"
|
||||
switch(state)
|
||||
if(0)
|
||||
if(density)
|
||||
state = AIRLOCK_CLOSED
|
||||
else
|
||||
state = AIRLOCK_OPEN
|
||||
icon_state = ""
|
||||
if(AIRLOCK_OPEN, AIRLOCK_CLOSED)
|
||||
icon_state = ""
|
||||
if(AIRLOCK_DENY, AIRLOCK_OPENING, AIRLOCK_CLOSING, AIRLOCK_EMAG)
|
||||
icon_state = "nonexistenticonstate" //MADNESS
|
||||
set_airlock_overlays(state)
|
||||
@@ -670,12 +669,12 @@ About the new airlock wires panel:
|
||||
return FALSE
|
||||
|
||||
//For the tools being used on the door. Since you don't want to call the attack_hand method if you're using hands. That would be silly
|
||||
//Also it's a bit inconsistent that when you access the panel you headbutt it. But not while crowbarring
|
||||
//Also it's a bit inconsistent that when you access the panel you headbutt it. But not while crowbarring
|
||||
//Try to interact with the panel. If the user can't it'll try activating the door
|
||||
/obj/machinery/door/airlock/proc/interact_with_panel(mob/user)
|
||||
if(shock_user(user, 100))
|
||||
return
|
||||
|
||||
|
||||
if(panel_open)
|
||||
if(security_level)
|
||||
to_chat(user, "<span class='warning'>Wires are protected!</span>")
|
||||
@@ -1325,7 +1324,7 @@ About the new airlock wires panel:
|
||||
user.visible_message("<span class='notice'>[user] removes [note] from [src].</span>", "<span class='notice'>You remove [note] from [src].</span>")
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 50, 1)
|
||||
else return FALSE
|
||||
else
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] cuts down [note] from [src].</span>", "<span class='notice'>You remove [note] from [src].</span>")
|
||||
playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
note.forceMove(get_turf(user))
|
||||
|
||||
@@ -55,6 +55,7 @@ var/list/holopads = list()
|
||||
var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
|
||||
var/obj/effect/overlay/holoray/ray
|
||||
var/ringing = FALSE
|
||||
var/dialling_input = FALSE //The user is currently selecting where to send their call
|
||||
|
||||
/obj/machinery/hologram/holopad/New()
|
||||
..()
|
||||
@@ -133,6 +134,8 @@ var/list/holopads = list()
|
||||
/obj/machinery/hologram/holopad/interact(mob/living/carbon/human/user) //Carn: hologram requests.
|
||||
if(!istype(user))
|
||||
return
|
||||
if(!anchored)
|
||||
return
|
||||
|
||||
var/dat
|
||||
if(temp)
|
||||
@@ -191,7 +194,9 @@ var/list/holopads = list()
|
||||
else if(href_list["Holocall"])
|
||||
if(outgoing_call)
|
||||
return
|
||||
|
||||
if(dialling_input)
|
||||
to_chat(usr, "<span class='notice'>Finish dialling first!</span>")
|
||||
return
|
||||
temp = "You must stand on the holopad to make a call!<br>"
|
||||
temp += "<a href='?src=[UID()];mainmenu=1'>Main Menu</a>"
|
||||
if(usr.loc == loc)
|
||||
@@ -201,9 +206,9 @@ var/list/holopads = list()
|
||||
if(A)
|
||||
LAZYADD(callnames[A], I)
|
||||
callnames -= get_area(src)
|
||||
|
||||
dialling_input = TRUE
|
||||
var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames
|
||||
|
||||
dialling_input = FALSE
|
||||
if(QDELETED(usr) || !result || outgoing_call)
|
||||
return
|
||||
|
||||
@@ -250,7 +255,7 @@ var/list/holopads = list()
|
||||
/obj/machinery/hologram/holopad/process()
|
||||
for(var/I in masters)
|
||||
var/mob/living/master = I
|
||||
if((stat & NOPOWER) || !validate_user(master))
|
||||
if((stat & NOPOWER) || !validate_user(master) || !anchored)
|
||||
clear_holo(master)
|
||||
|
||||
if(outgoing_call)
|
||||
@@ -348,7 +353,7 @@ var/list/holopads = list()
|
||||
hologram.alpha = 100
|
||||
hologram.Impersonation = user
|
||||
|
||||
hologram.mouse_opacity = 0//So you can't click on it.
|
||||
hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||
hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
hologram.anchored = 1//So space wind cannot drag it.
|
||||
hologram.name = "[user.name] (hologram)"//If someone decides to right click.
|
||||
@@ -481,7 +486,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
layer = FLY_LAYER
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
mouse_opacity = 1
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
alpha = 100
|
||||
|
||||
@@ -11,18 +11,21 @@
|
||||
icon_state = "airlock_control_standby"
|
||||
anchored = 1 //this is what I get for assuming /obj/machinery has anchored set to 1 by default
|
||||
var/list/linkedturfs = list() //List contains all of the linked pool turfs to this controller, assignment happens on New()
|
||||
var/mobinpool = list() //List contains all of the mob in the pool, to prevent looping through the entire area to find mobs inside..
|
||||
var/decalinpool = list() // List containing all of the cleanable decals in pool
|
||||
var/linked_area = null
|
||||
var/temperature = NORMAL //The temperature of the pool, starts off on normal, which has no effects.
|
||||
var/temperaturecolor = "" //used for nanoUI fancyness
|
||||
var/srange = 5 //The range of the search for pool turfs, change this for bigger or smaller pools.
|
||||
var/list/linkedmist = list() //Used to keep track of created mist
|
||||
var/deep_water = 0 //set to 1 to drown even standing people
|
||||
var/deep_water = FALSE //set to 1 to drown even standing people
|
||||
|
||||
|
||||
/obj/machinery/poolcontroller/New() //This proc automatically happens on world start
|
||||
if(!linked_area)
|
||||
for(var/turf/simulated/floor/beach/water/W in range(srange,src)) //Search for /turf/simulated/floor/beach/water in the range of var/srange
|
||||
linkedturfs += W //Add found pool turfs to the central list.
|
||||
W.linkedcontroller = src // And add the linked controller to itself.
|
||||
..() //Changed to call parent as per MarkvA's recommendation
|
||||
|
||||
/obj/machinery/poolcontroller/emag_act(user as mob) //Emag_act, this is called when it is hit with a cryptographic sequencer.
|
||||
@@ -48,21 +51,24 @@
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/poolcontroller/process()
|
||||
updatePool() //Call the mob affecting/decal cleaning proc
|
||||
processMob() //Call the mob affecting proc
|
||||
cleanPool() //Call the decal cleaning proc
|
||||
|
||||
/obj/machinery/poolcontroller/proc/updatePool()
|
||||
for(var/turf/T in linkedturfs) //Check for pool-turfs linked to the controller.
|
||||
for(var/mob/M in T) //Check for mobs in the linked pool-turfs.
|
||||
handleTemp(M) //handles pool temp effects on the swimmers
|
||||
/obj/machinery/poolcontroller/proc/processMob()
|
||||
for(var/M in mobinpool) //They're already typecasted when entering the turf
|
||||
// Following two are sanity check. If the mob is no longer in the pool for whatever reason (Looking at you teleport), remove them
|
||||
if(!istype(get_turf(M), /turf/simulated/floor/beach/water) && !istype(get_turf(M), /turf/unsimulated/beach/water)) // Water component when?
|
||||
mobinpool -= M
|
||||
continue
|
||||
handleTemp(M) //handles pool temp effects on the swimmers
|
||||
if(ishuman(M)) //Only human types will drown, to keep things simple for non-human mobs that live in the water
|
||||
handleDrowning(M)
|
||||
|
||||
if(ishuman(M)) //Make sure they are human before typecasting.
|
||||
var/mob/living/carbon/human/drownee = M //Typecast them as human.
|
||||
handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water
|
||||
|
||||
for(var/obj/effect/decal/cleanable/decal in T) //Cleans up cleanable decals like blood and such
|
||||
/obj/machinery/poolcontroller/proc/cleanPool()
|
||||
for(var/obj/effect/decal/cleanable/decal in decalinpool) //Cleans up cleanable decals like blood and such
|
||||
if(!QDELETED(decal))
|
||||
animate(decal, alpha = 10, time = 20)
|
||||
spawn(25)
|
||||
qdel(decal)
|
||||
QDEL_IN(decal, 25)
|
||||
|
||||
/obj/machinery/poolcontroller/proc/handleTemp(var/mob/M)
|
||||
if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD)
|
||||
@@ -187,29 +193,17 @@
|
||||
/obj/machinery/poolcontroller/seacontroller
|
||||
invisibility = 101
|
||||
unacidable = 1
|
||||
|
||||
name = "Sea Controller"
|
||||
desc = "A controller for the underwater portion of the sea. Players shouldn't see this."
|
||||
deep_water = 1 //deep sea is deep water
|
||||
deep_water = TRUE //deep sea is deep water
|
||||
|
||||
/obj/machinery/poolcontroller/seacontroller/New()
|
||||
/obj/machinery/poolcontroller/seacontroller/Initialize()
|
||||
linked_area = get_area(src)
|
||||
for(var/turf/unsimulated/beach/water/W in linked_area)
|
||||
linkedturfs += W //Add found pool turfs to the central list.
|
||||
W.linkedcontroller = src // And add the linked controller to itself.
|
||||
..()
|
||||
|
||||
/obj/machinery/poolcontroller/seacontroller/updatePool()
|
||||
for(var/turf/T in linked_area)
|
||||
for(var/mob/M in T)
|
||||
handleTemp(M) //handles pool temp effects on the swimmers
|
||||
|
||||
if(ishuman(M)) //Make sure they are human before typecasting.
|
||||
var/mob/living/carbon/human/drownee = M //Typecast them as human.
|
||||
handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water
|
||||
|
||||
for(var/obj/effect/decal/cleanable/decal in T)
|
||||
animate(decal, alpha = 10, time = 20)
|
||||
spawn(25)
|
||||
qdel(decal)
|
||||
|
||||
#undef FRIGID
|
||||
#undef COOL
|
||||
#undef NORMAL
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 250
|
||||
var/obj/item/charging = null
|
||||
var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs)
|
||||
var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer)
|
||||
var/icon_state_off = "rechargeroff"
|
||||
var/icon_state_charged = "recharger2"
|
||||
var/icon_state_charging = "recharger1"
|
||||
@@ -115,6 +115,13 @@
|
||||
if(R.rcell.give(R.rcell.chargerate))
|
||||
use_power(200)
|
||||
using_power = 1
|
||||
|
||||
if(istype(charging, /obj/item/bodyanalyzer))
|
||||
var/obj/item/bodyanalyzer/B = charging
|
||||
if(B.power_supply)
|
||||
if(B.power_supply.give(B.power_supply.chargerate))
|
||||
use_power(200)
|
||||
using_power = 1
|
||||
|
||||
update_icon(using_power)
|
||||
|
||||
|
||||
@@ -158,9 +158,7 @@
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
restock_modules()
|
||||
if(repairs)
|
||||
R.adjustBruteLoss(-(repairs))
|
||||
R.adjustFireLoss(-(repairs))
|
||||
R.updatehealth()
|
||||
R.heal_overall_damage(repairs, repairs)
|
||||
if(R.cell)
|
||||
R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
|
||||
else if(istype(occupant, /mob/living/carbon/human))
|
||||
@@ -168,8 +166,7 @@
|
||||
if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450)
|
||||
H.nutrition = min(H.nutrition+recharge_speed_nutrition, 450)
|
||||
if(repairs)
|
||||
H.heal_overall_damage(repairs, repairs, 0, 1)
|
||||
H.updatehealth()
|
||||
H.heal_overall_damage(repairs, repairs, TRUE, 0, 1)
|
||||
|
||||
/obj/machinery/recharge_station/proc/go_out()
|
||||
if(!occupant)
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
|
||||
H.emote("scream") // It is painful
|
||||
H.adjustBruteLoss(max(0, 80 - H.getBruteLoss())) // Hurt the human, don't try to kill them though.
|
||||
H.handle_regular_hud_updates() // Make sure they see the pain.
|
||||
|
||||
// Sleep for a couple of ticks to allow the human to see the pain
|
||||
sleep(5)
|
||||
|
||||
@@ -228,7 +228,6 @@
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.updatehealth()
|
||||
M.AdjustStunned(-4)
|
||||
M.AdjustWeakened(-4)
|
||||
M.AdjustStunned(-4)
|
||||
@@ -520,4 +519,3 @@
|
||||
for(var/reagent in processed_reagents)
|
||||
reagents.add_reagent(reagent,amount)
|
||||
chassis.use_power(energy_drain)
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
|
||||
if(target)
|
||||
target.Paralyse(10)
|
||||
target.updatehealth()
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
if(!M)
|
||||
return
|
||||
M.adjustOxyLoss(round(dam_force/2))
|
||||
M.updatehealth()
|
||||
target.visible_message("<span class='danger'>[chassis] squeezes [target].</span>", \
|
||||
"<span class='userdanger'>[chassis] squeezes [target].</span>",\
|
||||
"<span class='italics'>You hear something crack.</span>")
|
||||
@@ -451,4 +450,3 @@
|
||||
//NC.mergeConnectedNetworksOnTurf()
|
||||
last_piece = NC
|
||||
return 1
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
color = "#EBEBEB"
|
||||
|
||||
/obj/effect/decal/cleanable/flour/foam/Initialize()
|
||||
. = ..()
|
||||
QDEL_IN(src, 15 SECONDS)
|
||||
. = ..()
|
||||
QDEL_IN(src, 15 SECONDS)
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow
|
||||
name = "glowing goo"
|
||||
@@ -77,8 +77,8 @@
|
||||
icon_state = "greenglow"
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
|
||||
. = ..()
|
||||
QDEL_IN(src, 2 MINUTES)
|
||||
. = ..()
|
||||
QDEL_IN(src, 2 MINUTES)
|
||||
|
||||
/obj/effect/decal/cleanable/cobweb
|
||||
name = "cobweb"
|
||||
@@ -201,4 +201,3 @@
|
||||
icon_state = "confetti1"
|
||||
random_icon_states = list("confetti1", "confetti2", "confetti3")
|
||||
anchored = TRUE
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
|
||||
/obj/effect/particle_effect
|
||||
name = "particle effect"
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
unacidable = 1//So effects are not targeted by alien acid.
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
icon_state = "explosion"
|
||||
opacity = 1
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
anchored = 1
|
||||
layer = 99
|
||||
plane = HUD_PLANE
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
unacidable = 1//Just to be sure.
|
||||
|
||||
/obj/effect/beam
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
anchored = 1
|
||||
density = 1
|
||||
layer = 5
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/overlay/wall_rot/New()
|
||||
..()
|
||||
|
||||
@@ -42,3 +42,8 @@
|
||||
name = "reinforced window spawner"
|
||||
icon_state = "rwindow_spawner"
|
||||
windowtospawn = /obj/structure/window/reinforced
|
||||
|
||||
/obj/effect/spawner/window/reinforced/plasma
|
||||
name = "reinforced plasma window spawner"
|
||||
icon_state = "pwindow_spawner"
|
||||
windowtospawn = /obj/structure/window/plasmareinforced
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
name = mimiced_atom.name
|
||||
appearance = mimiced_atom.appearance
|
||||
setDir(mimiced_atom.dir)
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/temp_visual/decoy/fading/New(loc, atom/mimiced_atom)
|
||||
..()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/obj/effect/temp_visual
|
||||
anchored = 1
|
||||
layer = ABOVE_MOB_LAYER
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/duration = 10
|
||||
var/randomdir = TRUE
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
|
||||
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0, cause = null)
|
||||
if(!epicenter) return
|
||||
|
||||
if(!istype(epicenter, /turf))
|
||||
epicenter = get_turf(epicenter.loc)
|
||||
|
||||
if(log)
|
||||
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [ADMIN_COORDJMP(epicenter)]</a>")
|
||||
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [COORD(epicenter)]")
|
||||
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])": ] [ADMIN_COORDJMP(epicenter)]</a>")
|
||||
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [COORD(epicenter)]")
|
||||
|
||||
if(heavy_range > 1)
|
||||
new/obj/effect/temp_visual/emp/pulse(epicenter)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//TODO: Flash range does nothing currently
|
||||
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1)
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1, cause = null)
|
||||
src = null //so we don't abort once src is deleted
|
||||
epicenter = get_turf(epicenter)
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
var/list/cached_exp_block = list()
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[epicenter.x];Y=[epicenter.y];Z=[epicenter.z]'>JMP</a>)")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [ADMIN_COORDJMP(epicenter)] ")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [COORD(epicenter)] ")
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
@@ -232,7 +232,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm")
|
||||
if(affecting && affecting.receive_damage(0, 5)) // 5 burn damage
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
return
|
||||
else
|
||||
extinguish()
|
||||
@@ -554,4 +553,4 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
return TRUE
|
||||
|
||||
/obj/item/attack_hulk(mob/living/carbon/human/user)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
to_chat(AI, "Your core files are being wiped!")
|
||||
while(AI && AI.stat != DEAD)
|
||||
AI.adjustOxyLoss(2)
|
||||
AI.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
|
||||
@@ -632,3 +632,253 @@ REAGENT SCANNER
|
||||
if(T.cores > 1)
|
||||
user.show_message("Anomalous slime core amount detected", 1)
|
||||
user.show_message("Growth progress: [T.amount_grown]/10", 1)
|
||||
|
||||
/obj/item/bodyanalyzer
|
||||
name = "handheld body analyzer"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "bodyanalyzer_0"
|
||||
item_state = "healthanalyser"
|
||||
desc = "A handheld scanner capable of deep-scanning an entire body."
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 3
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 5
|
||||
throw_range = 10
|
||||
origin_tech = "magnets=6;biotech=6"
|
||||
var/obj/item/stock_parts/cell/power_supply
|
||||
var/cell_type = /obj/item/stock_parts/cell/upgraded
|
||||
var/ready = TRUE // Ready to scan
|
||||
var/time_to_use = 0 // How much time remaining before next scan is available.
|
||||
var/usecharge = 750
|
||||
|
||||
/obj/item/bodyanalyzer/advanced
|
||||
cell_type = /obj/item/stock_parts/cell/upgraded/plus
|
||||
|
||||
/obj/item/bodyanalyzer/New()
|
||||
..()
|
||||
power_supply = new cell_type(src)
|
||||
power_supply.give(power_supply.maxcharge)
|
||||
update_icon()
|
||||
|
||||
/obj/item/bodyanalyzer/proc/setReady()
|
||||
ready = TRUE
|
||||
playsound(src, 'sound/machines/defib_saftyOn.ogg', 50, 0)
|
||||
update_icon()
|
||||
|
||||
/obj/item/bodyanalyzer/update_icon(printing = FALSE)
|
||||
overlays.Cut()
|
||||
var/percent = power_supply.percent()
|
||||
if(ready)
|
||||
icon_state = "bodyanalyzer_1"
|
||||
else
|
||||
icon_state = "bodyanalyzer_2"
|
||||
|
||||
var/overlayid = round(percent / 10)
|
||||
overlayid = "bodyanalyzer_charge[overlayid]"
|
||||
overlays += icon(icon, overlayid)
|
||||
|
||||
if(printing)
|
||||
overlays += icon(icon, "bodyanalyzer_printing")
|
||||
|
||||
/obj/item/bodyanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
|
||||
if(user.incapacitated() || !user.Adjacent(M))
|
||||
return
|
||||
|
||||
if(!ready)
|
||||
to_chat(user, "<span class='notice'>The scanner beeps angrily at you! It's currently recharging - [round((time_to_use - world.time) * 0.1)] seconds remaining.</span>")
|
||||
playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
return
|
||||
|
||||
if(power_supply.charge >= usecharge)
|
||||
mobScan(M, user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The scanner beeps angrily at you! It's out of charge!</span>")
|
||||
playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
|
||||
/obj/item/bodyanalyzer/proc/mobScan(mob/living/M, mob/user)
|
||||
if(ishuman(M))
|
||||
var/report = generate_printing_text(M, user)
|
||||
user.visible_message("[user] begins scanning [M] with [src].", "You begin scanning [M].")
|
||||
if(do_after(user, 100, target = M))
|
||||
var/obj/item/paper/printout = new
|
||||
printout.info = report
|
||||
printout.name = "Scan report - [M.name]"
|
||||
playsound(user.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
|
||||
user.put_in_hands(printout)
|
||||
time_to_use = world.time + 600
|
||||
power_supply.use(usecharge)
|
||||
ready = FALSE
|
||||
update_icon(TRUE)
|
||||
addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/setReady), 600)
|
||||
addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/update_icon), 20)
|
||||
|
||||
else if(iscorgi(M) && M.stat == DEAD)
|
||||
to_chat(user, "<span class='notice'>You wonder if [M.p_they()] was a good dog. <b>[src] tells you they were the best...</b></span>") // :'(
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/setReady), 600)
|
||||
time_to_use = world.time + 600
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Scanning error detected. Invalid specimen.</span>")
|
||||
|
||||
//Unashamedly ripped from adv_med.dm
|
||||
/obj/item/bodyanalyzer/proc/generate_printing_text(mob/living/M, mob/user)
|
||||
var/dat = ""
|
||||
var/mob/living/carbon/human/target = M
|
||||
|
||||
dat = "<font color='blue'><b>Target Statistics:</b></font><br>"
|
||||
var/t1
|
||||
switch(target.stat) // obvious, see what their status is
|
||||
if(CONSCIOUS)
|
||||
t1 = "Conscious"
|
||||
if(UNCONSCIOUS)
|
||||
t1 = "Unconscious"
|
||||
else
|
||||
t1 = "*dead*"
|
||||
dat += "[target.health > 50 ? "<font color='blue'>" : "<font color='red'>"]\tHealth %: [target.health], ([t1])</font><br>"
|
||||
|
||||
var/found_disease = FALSE
|
||||
for(var/thing in target.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.visibility_flags) //If any visibility flags are on.
|
||||
continue
|
||||
found_disease = TRUE
|
||||
break
|
||||
if(found_disease)
|
||||
dat += "<font color='red'>Disease detected in target.</font><BR>"
|
||||
|
||||
var/extra_font = null
|
||||
extra_font = (target.getBruteLoss() < 60 ? "<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\t-Brute Damage %: [target.getBruteLoss()]</font><br>"
|
||||
|
||||
extra_font = (target.getOxyLoss() < 60 ? "<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\t-Respiratory Damage %: [target.getOxyLoss()]</font><br>"
|
||||
|
||||
extra_font = (target.getToxLoss() < 60 ? "<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\t-Toxin Content %: [target.getToxLoss()]</font><br>"
|
||||
|
||||
extra_font = (target.getFireLoss() < 60 ? "<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\t-Burn Severity %: [target.getFireLoss()]</font><br>"
|
||||
|
||||
extra_font = (target.radiation < 10 ?"<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tRadiation Level %: [target.radiation]</font><br>"
|
||||
|
||||
extra_font = (target.getCloneLoss() < 1 ?"<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tGenetic Tissue Damage %: [target.getCloneLoss()]<br>"
|
||||
|
||||
extra_font = (target.getBrainLoss() < 1 ?"<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tApprox. Brain Damage %: [target.getBrainLoss()]<br>"
|
||||
|
||||
dat += "Paralysis Summary %: [target.paralysis] ([round(target.paralysis / 4)] seconds left!)<br>"
|
||||
dat += "Body Temperature: [target.bodytemperature-T0C]°C ([target.bodytemperature*1.8-459.67]°F)<br>"
|
||||
|
||||
dat += "<hr>"
|
||||
|
||||
if(target.has_brain_worms())
|
||||
dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.<br>"
|
||||
|
||||
var/blood_percent = round((target.blood_volume / BLOOD_VOLUME_NORMAL))
|
||||
blood_percent *= 100
|
||||
|
||||
extra_font = (target.blood_volume > 448 ? "<font color='blue'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tBlood Level %: [blood_percent] ([target.blood_volume] units)</font><br>"
|
||||
|
||||
if(target.reagents)
|
||||
dat += "Epinephrine units: [target.reagents.get_reagent_amount("Epinephrine")] units<BR>"
|
||||
dat += "Ether: [target.reagents.get_reagent_amount("ether")] units<BR>"
|
||||
|
||||
extra_font = (target.reagents.get_reagent_amount("silver_sulfadiazine") < 30 ? "<font color='black'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tSilver Sulfadiazine: [target.reagents.get_reagent_amount("silver_sulfadiazine")]</font><br>"
|
||||
|
||||
extra_font = (target.reagents.get_reagent_amount("styptic_powder") < 30 ? "<font color='black'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tStyptic Powder: [target.reagents.get_reagent_amount("styptic_powder")] units<BR>"
|
||||
|
||||
extra_font = (target.reagents.get_reagent_amount("salbutamol") < 30 ? "<font color='black'>" : "<font color='red'>")
|
||||
dat += "[extra_font]\tSalbutamol: [target.reagents.get_reagent_amount("salbutamol")] units<BR>"
|
||||
|
||||
dat += "<hr><table border='1'>"
|
||||
dat += "<tr>"
|
||||
dat += "<th>Organ</th>"
|
||||
dat += "<th>Burn Damage</th>"
|
||||
dat += "<th>Brute Damage</th>"
|
||||
dat += "<th>Other Wounds</th>"
|
||||
dat += "</tr>"
|
||||
|
||||
for(var/obj/item/organ/external/e in target.bodyparts)
|
||||
dat += "<tr>"
|
||||
var/AN = ""
|
||||
var/open = ""
|
||||
var/infected = ""
|
||||
var/robot = ""
|
||||
var/imp = ""
|
||||
var/bled = ""
|
||||
var/splint = ""
|
||||
var/internal_bleeding = ""
|
||||
var/lung_ruptured = ""
|
||||
if(e.internal_bleeding)
|
||||
internal_bleeding = "<br>Internal bleeding"
|
||||
if(istype(e, /obj/item/organ/external/chest) && target.is_lung_ruptured())
|
||||
lung_ruptured = "Lung ruptured:"
|
||||
if(e.status & ORGAN_SPLINTED)
|
||||
splint = "Splinted:"
|
||||
if(e.status & ORGAN_BROKEN)
|
||||
AN = "[e.broken_description]:"
|
||||
if(e.is_robotic())
|
||||
robot = "Robotic:"
|
||||
if(e.open)
|
||||
open = "Open:"
|
||||
switch(e.germ_level)
|
||||
if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200)
|
||||
infected = "Mild Infection:"
|
||||
if(INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
|
||||
infected = "Mild Infection+:"
|
||||
if(INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
|
||||
infected = "Mild Infection++:"
|
||||
if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
|
||||
infected = "Acute Infection:"
|
||||
if(INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
|
||||
infected = "Acute Infection+:"
|
||||
if(INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400)
|
||||
infected = "Acute Infection++:"
|
||||
if(INFECTION_LEVEL_THREE to INFINITY)
|
||||
infected = "Septic:"
|
||||
|
||||
var/unknown_body = 0
|
||||
for(var/I in e.embedded_objects)
|
||||
unknown_body++
|
||||
|
||||
if(unknown_body || e.hidden)
|
||||
imp += "Unknown body present:"
|
||||
if(!AN && !open && !infected & !imp)
|
||||
AN = "None:"
|
||||
dat += "<td>[e.name]</td><td>[e.burn_dam]</td><td>[e.brute_dam]</td><td>[robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]</td>"
|
||||
dat += "</tr>"
|
||||
for(var/obj/item/organ/internal/i in target.internal_organs)
|
||||
var/mech = i.desc
|
||||
var/infection = "None"
|
||||
switch(i.germ_level)
|
||||
if(1 to INFECTION_LEVEL_ONE + 200)
|
||||
infection = "Mild Infection:"
|
||||
if(INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
|
||||
infection = "Mild Infection+:"
|
||||
if(INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
|
||||
infection = "Mild Infection++:"
|
||||
if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
|
||||
infection = "Acute Infection:"
|
||||
if(INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
|
||||
infection = "Acute Infection+:"
|
||||
if(INFECTION_LEVEL_TWO + 300 to INFINITY)
|
||||
infection = "Acute Infection++:"
|
||||
|
||||
dat += "<tr>"
|
||||
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech]</td><td></td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
if(target.disabilities & BLIND)
|
||||
dat += "<font color='red'>Cataracts detected.</font><BR>"
|
||||
if(target.disabilities & COLOURBLIND)
|
||||
dat += "<font color='red'>Photoreceptor abnormalities detected.</font><BR>"
|
||||
if(target.disabilities & NEARSIGHTED)
|
||||
dat += "<font color='red'>Retinal misalignment detected.</font><BR>"
|
||||
|
||||
return dat
|
||||
|
||||
@@ -302,14 +302,12 @@
|
||||
|
||||
if(cyborg.health < cyborg.maxHealth)
|
||||
if(cyborg.health < 0)
|
||||
repair_amount = -2.5
|
||||
repair_amount = 2.5
|
||||
powercost = 30
|
||||
else
|
||||
repair_amount = -1
|
||||
repair_amount = 1
|
||||
powercost = 10
|
||||
cyborg.adjustBruteLoss(repair_amount)
|
||||
cyborg.adjustFireLoss(repair_amount)
|
||||
cyborg.updatehealth()
|
||||
cyborg.heal_overall_damage(repair_amount, repair_amount)
|
||||
cyborg.cell.use(powercost)
|
||||
else
|
||||
cyborg.cell.use(5)
|
||||
|
||||
@@ -94,9 +94,7 @@
|
||||
|
||||
hp -= Proj.damage
|
||||
if(hp <= 0)
|
||||
for(var/mob/O in oviewers())
|
||||
if((O.client && !( O.blinded )))
|
||||
to_chat(O, "<span class='warning'>[src] breaks into tiny pieces and collapses!</span>")
|
||||
visible_message("<span class='warning'>[src] breaks into tiny pieces and collapses!</span>")
|
||||
qdel(src)
|
||||
|
||||
// Create a temporary object to represent the damage
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
|
||||
else
|
||||
M.heal_organ_damage(heal_brute, heal_burn)
|
||||
M.updatehealth()
|
||||
user.visible_message("<span class='green'>[user] applies [src] on [M].</span>", \
|
||||
"<span class='green'>You apply [src] on [M].</span>")
|
||||
use(1)
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
if(istype(M,/mob/living/silicon/robot)) //Repairing cyborgs
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(R.getBruteLoss() || R.getFireLoss() )
|
||||
R.adjustBruteLoss(-15)
|
||||
R.adjustFireLoss(-15)
|
||||
R.updatehealth()
|
||||
R.heal_overall_damage(15, 15)
|
||||
use(1)
|
||||
user.visible_message("<span class='notice'>\The [user] applied some [src] at [R]'s damaged areas.</span>",\
|
||||
"<span class='notice'>You apply some [src] at [R]'s damaged areas.</span>")
|
||||
@@ -31,7 +29,6 @@
|
||||
if(S && S.is_robotic())
|
||||
if(S.get_damage())
|
||||
S.heal_damage(15, 15, robo_repair = 1)
|
||||
H.updatehealth()
|
||||
use(1)
|
||||
user.visible_message("<span class='notice'>\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.name] with \the [src].</span>",\
|
||||
"<span class='notice'>You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.name].</span>")
|
||||
|
||||
@@ -332,7 +332,6 @@
|
||||
"<span class='userdanger'>[user] has touched [H.name] with [src]!</span>")
|
||||
H.adjustStaminaLoss(50)
|
||||
H.Weaken(5)
|
||||
H.updatehealth() //forces health update before next life tick
|
||||
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
H.emote("gasp")
|
||||
if(!H.undergoing_cardiac_arrest() && (prob(10) || defib.combat)) // Your heart explodes.
|
||||
@@ -479,7 +478,6 @@
|
||||
"<span class='userdanger'>[user] has touched [H.name] with [src]!</span>")
|
||||
H.adjustStaminaLoss(50)
|
||||
H.Weaken(5)
|
||||
H.updatehealth() //forces health update before next life tick
|
||||
if(!H.undergoing_cardiac_arrest() && prob(10)) // Your heart explodes.
|
||||
H.set_heartattack(TRUE)
|
||||
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
if(nadeassembly)
|
||||
nadeassembly.attack_self(user)
|
||||
return
|
||||
var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
|
||||
var/newtime = input(usr, "Please set the timer.", "Timer", det_time) as num
|
||||
if(user.is_in_active_hand(src))
|
||||
newtime = Clamp(newtime, 10, 60000)
|
||||
det_time = newtime
|
||||
@@ -231,3 +231,38 @@
|
||||
CB.prime()
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/grenade/plastic/x4/thermite
|
||||
name = "T4"
|
||||
desc = "A wall breaching charge, containing fuel, metal oxide and metal powder mixed in just the right way. One hell of a combination. Effective against walls, ineffective against airlocks..."
|
||||
det_time = 2
|
||||
icon_state = "t4breach0"
|
||||
item_state = "t4breach"
|
||||
|
||||
/obj/item/grenade/plastic/x4/thermite/prime()
|
||||
var/turf/location
|
||||
if(target)
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
target.overlays -= image_overlay
|
||||
else
|
||||
location = get_turf(src)
|
||||
if(location)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(8,0, location, aim_dir)
|
||||
if(target && target.density)
|
||||
var/turf/T = get_step(location, aim_dir)
|
||||
for(var/turf/simulated/wall/W in range(1, location))
|
||||
W.thermitemelt(speed = 30)
|
||||
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
|
||||
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
|
||||
else
|
||||
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
|
||||
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
|
||||
|
||||
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
M.adjust_fire_stacks(2)
|
||||
M.IgniteMob()
|
||||
qdel(src)
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand")
|
||||
if(affecting.receive_damage( 0, 5 )) //INFERNO
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
user.visible_message("<span class='notice'>After a few attempts, [user] manages to light the [src], [user.p_they()] however burn[user.p_s()] [user.p_their()] finger in the process.</span>")
|
||||
|
||||
set_light(2)
|
||||
@@ -184,6 +183,7 @@
|
||||
attack_verb = list("burnt","singed")
|
||||
processing_objects.Add(src)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/match/proc/matchburnout()
|
||||
if(lit)
|
||||
@@ -197,6 +197,7 @@
|
||||
desc = "A match. This one has seen better days."
|
||||
attack_verb = list("flicked")
|
||||
processing_objects.Remove(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/match/dropped(mob/user)
|
||||
matchburnout()
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
to_chat(H, "<span class='warning'>[src] cuts into your hand!</span>")
|
||||
if(affecting.receive_damage(force*0.5))
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
|
||||
/obj/item/shard/attackby(obj/item/I, mob/user, params)
|
||||
if(iswelder(I))
|
||||
@@ -87,7 +86,6 @@
|
||||
H.Weaken(3)
|
||||
if(affecting.receive_damage(5, 0))
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
..()
|
||||
|
||||
/obj/item/shard/plasma
|
||||
@@ -126,4 +124,4 @@
|
||||
to_chat(usr, "You add the newly-formed plasma glass to the stack. It now contains [NG.amount] sheets.")
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -246,6 +246,15 @@
|
||||
new /obj/item/grenade/flashbang(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/belt/security/response_team_gamma/New()
|
||||
..()
|
||||
new /obj/item/melee/baton/loaded(src)
|
||||
new /obj/item/reagent_containers/spray/pepper(src)
|
||||
new /obj/item/flash(src)
|
||||
new /obj/item/grenade/flashbang(src)
|
||||
new /obj/item/grenade/flashbang(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/belt/soulstone
|
||||
name = "soul stone belt"
|
||||
desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away"
|
||||
|
||||
@@ -123,3 +123,13 @@
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
new /obj/item/clothing/accessory/medal/gold/captain(src)
|
||||
|
||||
/obj/item/storage/lockbox/t4
|
||||
name = "lockbox (T4)"
|
||||
desc = "Contains three T4 breaching charges."
|
||||
req_access = list(access_cent_specops)
|
||||
|
||||
/obj/item/storage/lockbox/t4/New()
|
||||
..()
|
||||
for(var/i = 0, i < 3, i++)
|
||||
new /obj/item/grenade/plastic/x4/thermite(src)
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
if(display_contents_with_number)
|
||||
for(var/datum/numbered_display/ND in display_contents)
|
||||
ND.sample_object.mouse_opacity = 2
|
||||
ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ND.sample_object.screen_loc = "[cx]:16,[cy]:16"
|
||||
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
|
||||
ND.sample_object.layer = 20
|
||||
@@ -177,7 +177,7 @@
|
||||
cy--
|
||||
else
|
||||
for(var/obj/O in contents)
|
||||
O.mouse_opacity = 2 //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.screen_loc = "[cx]:16,[cy]:16"
|
||||
O.maptext = ""
|
||||
O.layer = 20
|
||||
@@ -309,7 +309,7 @@
|
||||
src.orient2hud(usr)
|
||||
if(usr.s_active)
|
||||
usr.s_active.show_to(usr)
|
||||
W.mouse_opacity = 2 //So you can click on the area around the item to equip it, instead of having to pixel hunt
|
||||
W.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/status = 0
|
||||
var/obj/item/stock_parts/cell/high/bcell = null
|
||||
var/hitcost = 1000
|
||||
var/throw_hit_chance = 35
|
||||
|
||||
/obj/item/melee/baton/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
@@ -28,6 +29,11 @@
|
||||
QDEL_NULL(bcell)
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/baton/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(status && prob(throw_hit_chance))
|
||||
baton_stun(hit_atom)
|
||||
|
||||
/obj/item/melee/baton/loaded/New() //this one starts with a cell pre-installed.
|
||||
..()
|
||||
bcell = new(src)
|
||||
@@ -138,15 +144,17 @@
|
||||
if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
return
|
||||
user.lastattacked = L
|
||||
L.lastattacker = user
|
||||
|
||||
L.Stun(stunforce)
|
||||
L.Weaken(stunforce)
|
||||
L.apply_effect(STUTTER, stunforce)
|
||||
|
||||
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
|
||||
if(user)
|
||||
user.lastattacked = L
|
||||
L.lastattacker = user
|
||||
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
|
||||
add_attack_logs(user, L, "stunned")
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
|
||||
if(isrobot(loc))
|
||||
@@ -160,8 +168,6 @@
|
||||
var/mob/living/carbon/human/H = L
|
||||
H.forcesay(hit_appends)
|
||||
|
||||
add_attack_logs(user, L, "Stunned with [src]")
|
||||
|
||||
/obj/item/melee/baton/emp_act(severity)
|
||||
if(bcell)
|
||||
deductcharge(1000 / severity)
|
||||
@@ -193,6 +199,7 @@
|
||||
throwforce = 5
|
||||
stunforce = 5
|
||||
hitcost = 2000
|
||||
throw_hit_chance = 10
|
||||
slot_flags = SLOT_BACK
|
||||
var/obj/item/assembly/igniter/sparkler = null
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@
|
||||
desc = "A frozen shell of ice containing nanofrost that freezes the surrounding area after activation."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "frozen_smoke_capsule"
|
||||
mouse_opacity = 0
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
/obj/effect/nanofrost_container/proc/Smoke()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user