Resolves conflicts.

This commit is contained in:
Desolate
2018-10-11 05:36:22 -05:00
486 changed files with 16260 additions and 10647 deletions
+1 -1
View File
@@ -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"
+3 -3
View File
@@ -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
+2
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
+12
View File
@@ -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))
+4 -1
View File
@@ -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
+23
View File
@@ -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;\
}
+1 -1
View File
@@ -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
+29
View File
@@ -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
+3 -4
View File
@@ -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)
+88 -17
View File
@@ -1226,7 +1226,7 @@ var/global/list/common_tools = list(
//check if mob is lying down on something we can operate him on.
/proc/can_operate(mob/living/carbon/M)
return (locate(/obj/machinery/optable, M.loc) && (M.lying || M.resting)) || \
(locate(/obj/structure/stool/bed/roller, M.loc) && \
(locate(/obj/structure/bed/roller, M.loc) && \
(M.buckled || M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) && prob(75) || \
(locate(/obj/structure/table/, M.loc) && \
(M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat) && prob(66))
@@ -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
View File
@@ -44,3 +44,5 @@ GLOBAL_LIST_INIT(poi_list, list()) //list of points of interest for observe/
GLOBAL_LIST_INIT(active_jammers, list()) // List of active radio jammers
GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing.
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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 = ""
+1 -1
View File
@@ -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()
+32 -2
View File
@@ -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"
+2 -1
View File
@@ -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)
-20
View File
@@ -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)
GLOB.simple_animal_list -= M
if(ticker.current_state == GAME_STATE_FINISHED && !saved_voice)
var/mob/living/carbon/human/interactive/M = safepick(GLOB.snpc_list)
if(M)
M.saveVoice()
saved_voice = 1
for(last_object in GLOB.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)
GLOB.snpc_list -= M
current_cycle++
-119
View File
@@ -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
+3 -3
View File
@@ -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
+24
View File
@@ -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
+127
View File
@@ -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
+212
View File
@@ -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()
+1 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
+31
View File
@@ -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
+1 -1
View File
@@ -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,27 +24,36 @@ Bonus
level = 5
severity = 0
/datum/symptom/sensory_restoration/proc/check_and_add(reagent, check, add, mob/living/M)
if(M.reagents.get_reagent_amount(reagent) < check)
M.reagents.add_reagent(reagent, add)
return 1
/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2)
if(M.reagents.get_reagent_amount("oculine")<10)
M.reagents.add_reagent("oculine", 10)
if(check_and_add("oculine", 10, 10, M))
to_chat(M, "<span class='notice'>Your hearing feels clearer and crisp.</span>")
if(3)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("oculine") < 10 )
M.reagents.add_reagent_list(list("antihol"=10, "oculine"=10))
if(check_and_add("antihol", 10, 10, M))
to_chat(M, "<span class='notice'>You feel sober.</span>")
check_and_add("oculine", 10, 10, M)
if(4)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("oculine") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10)
M.reagents.add_reagent_list(list("antihol"=10, "oculine"=10, "synaphydramine"=5))
if(check_and_add("synaphydramine", 10, 5, M))
to_chat(M, "<span class='notice'>You feel focused.</span>")
check_and_add("antihol", 10, 10, M)
check_and_add("oculine", 10, 10, M)
if(5)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("oculine") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10 && M.reagents.get_reagent_amount("mannitol") < 10)
M.reagents.add_reagent_list(list("mannitol"=10, "antihol"=10, "oculine"=10, "synaphydramine"=10))
if(check_and_add("mannitol", 10, 10, M))
to_chat(M, "<span class='notice'>Your mind feels relaxed.</span>")
check_and_add("synaphydramine", 10, 5, M)
check_and_add("antihol", 10, 10, M)
check_and_add("oculine", 10, 10, M)
return
/*
+1 -2
View File
@@ -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
-3
View File
@@ -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))
+1 -2
View File
@@ -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 ..()
-2
View File
@@ -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
+1 -3
View File
@@ -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
+1 -3
View File
@@ -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()
+2 -2
View File
@@ -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))
+234 -285
View File
@@ -1,32 +1,22 @@
/* Note from Carnie:
The way datum/mind stuff works has been changed a lot.
Minds now represent IC characters rather than following a client around constantly.
Guidelines for using minds properly:
- Never mind.transfer_to(ghost). The var/current and var/original of a mind must always be of type mob/living!
ghost.mind is however used as a reference to the ghost's corpse
- When creating a new mob for an existing IC character (e.g. cloning a dead guy or borging a brain of a human)
the existing mind of the old mob should be transfered to the new mob like so:
mind.transfer_to(new_mob)
- You must not assign key= or ckey= after transfer_to() since the transfer_to transfers the client for you.
By setting key or ckey explicitly after transfering the mind with transfer_to you will cause bugs like DCing
the player.
- IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you.
- When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting
a ghost to become a xeno during an event). Simply assign the key or ckey like you've always done.
new_mob.key = key
The Login proc will handle making a new mob for that mobtype (including setting up stuff like mind.name). Simple!
However if you want that mind to have any special properties like being a traitor etc you will have to do that
yourself.
*/
/datum/mind
@@ -47,7 +37,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 +68,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 +111,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 +130,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 GLOB.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 +350,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 GLOB.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 +413,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 +1236,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()
@@ -1675,4 +1624,4 @@
/mob/living/simple_animal/construct/armoured/mind_initialize()
..()
mind.assigned_role = "Juggernaut"
mind.special_role = SPECIAL_ROLE_CULTIST
mind.special_role = SPECIAL_ROLE_CULTIST
+8 -6
View File
@@ -89,12 +89,9 @@
for(var/path in backpack_contents)
var/number = backpack_contents[path]
for(var/i = 0, i < number, i++)
equip_item(H, path, slot_in_backpack)
if(implants)
for(var/path in implants)
var/obj/item/implant/I = new path(H)
I.implant(H)
for(var/i in 1 to number)
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)
O.insert(H)
@@ -107,6 +104,11 @@
H.internal = H.get_item_by_slot(internals_slot)
H.update_action_buttons_icon()
if(implants)
for(var/implant_type in implants)
var/obj/item/implant/I = new implant_type(H)
I.implant(H, null)
H.update_body()
return 1
+2 -2
View File
@@ -34,7 +34,7 @@
/obj/effect/proc_holder/spell/aoe_turf/knock/greater
name = "Greater Knock"
desc = "On first cast, will remove access restrictions on all airlocks on the Cyberiad, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!"
desc = "On first cast, will remove access restrictions on all airlocks on the station, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!"
charge_max = 200
invocation = "MAIOR OXIN FIERA"
@@ -54,4 +54,4 @@
command_announcement.Announce("We have removed all access requirements on your station's airlocks. You can thank us later!", "Greetings!", 'sound/misc/notice2.ogg', , , "Space Wizard Federation Message")
else
..()
return
return
+1
View File
@@ -68,6 +68,7 @@ Also, you never added distance checking after target is selected. I've went ahea
ghost.mind.transfer_to(caster)
if(ghost.key)
GLOB.non_respawnable_keys -= ghost.ckey //ghostizing with an argument of 0 will make them unable to respawn forever, which is bad
caster.key = ghost.key //have to transfer the key since the mind was not active
qdel(ghost)
+3 -2
View File
@@ -93,9 +93,10 @@
var/obj/machinery/portable_atmospherics/P = item_to_retrive.loc
P.disconnect()
P.update_icon()
if(istype(item_to_retrive.loc, /obj/structure/disposalholder) || istype(item_to_retrive.loc, /obj/machinery/disposal))//fixes the breaking of disposals. No more bluespace connected disposal bins!
break
item_to_retrive = item_to_retrive.loc
infinite_recursion += 1
if(!item_to_retrive)
+3 -3
View File
@@ -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")
+1 -1
View File
@@ -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.
+5 -5
View File
@@ -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()
+11
View File
@@ -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
+8
View File
@@ -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."
+1 -1
View File
@@ -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()
+8 -2
View File
@@ -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
+15 -13
View File
@@ -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>")
@@ -49,8 +49,9 @@
user.mind.transfer_to(target)
if(ghost && ghost.mind)
ghost.mind.transfer_to(user)
GLOB.non_respawnable_keys -= ghost.ckey //they have a new body, let them be able to re-enter their corpse if they die
user.key = ghost.key
qdel(ghost)
user.Paralyse(2)
target.add_language("Changeling")
user.remove_language("Changeling")
@@ -14,11 +14,15 @@
if(!chosen_dna)
return
transform_dna(user,chosen_dna)
user.changeling_update_languages(changeling.absorbed_languages)
if(user.mind.speech_span == "wingdings") //greys' wingdings isn't stored in DNA
user.mind.speech_span = ""
to_chat(user, "<span class='warning'>Our vocal cords have permanently shifted. We will now speak regularly.</span>")
feedback_add_details("changeling_powers","TR")
return 1
+1 -3
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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)
@@ -672,7 +672,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
// Operating Table / Beds / Lockers
/obj/structure/stool/bed/abductor
/obj/structure/bed/abductor
name = "resting contraption"
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
icon = 'icons/obj/abductor.dmi'
@@ -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()
@@ -29,19 +29,19 @@
toggle = TRUE
/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
if(..())
if(toggle)
if(ishuman(target) && !summoner)
spawn(0)
new /obj/effect/hallucination/delusion(target.loc, target, force_kind = "custom", duration = 200, skip_nearby = 0, custom_icon = icon_state, custom_icon_file = icon)
else
if(prob(45))
if(ismovableatom(target))
var/atom/movable/M = target
if(!M.anchored && M != summoner)
new /obj/effect/temp_visual/guardian/phase/out(get_turf(M))
do_teleport(M, M, 10)
new /obj/effect/temp_visual/guardian/phase/out(get_turf(M))
..()
if(toggle)
if(ishuman(target) && !summoner)
spawn(0)
new /obj/effect/hallucination/delusion(target.loc, target, force_kind = "custom", duration = 200, skip_nearby = 0, custom_icon = icon_state, custom_icon_file = icon)
else
if(prob(45))
if(ismovableatom(target))
var/atom/movable/M = target
if(!M.anchored && M != summoner)
new /obj/effect/temp_visual/guardian/phase/out(get_turf(M))
do_teleport(M, M, 10)
new /obj/effect/temp_visual/guardian/phase/out(get_turf(M))
/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
..()
@@ -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"
+1 -1
View File
@@ -490,7 +490,7 @@ var/global/datum/controller/occupations/job_master
if(T)
H.loc = T
// Moving wheelchair if they have one
if(H.buckled && istype(H.buckled, /obj/structure/stool/bed/chair/wheelchair))
if(H.buckled && istype(H.buckled, /obj/structure/chair/wheelchair))
H.buckled.loc = H.loc
H.buckled.dir = H.dir
+2
View File
@@ -120,6 +120,8 @@
C.forceMove(loc)
if(user.pulling == C)
user.stop_pulling()
if(C.s_active) //Close the container opened
C.s_active.close(C)
for(var/obj/O in src)
O.loc = src.loc
src.add_fingerprint(user)
+2 -4
View File
@@ -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
+12 -14
View File
@@ -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
GLOB.dead_mob_list -= src.occupant
GLOB.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"])
+4 -19
View File
@@ -965,26 +965,11 @@
emagged = 1
/mob/living/simple_animal/hostile/syndicate/ranged/orion
name = "Spaceport Security"
desc = "The Premier security forces for all spaceports found along the Orion Trail."
name = "spaceport security"
desc = "Premier corporate security forces for all spaceports found along the Orion Trail."
faction = list("orion")
loot = list(/obj/effect/landmark/mobcorpse/orionsecurity,
/obj/item/gun/projectile/automatic/c20r,
/obj/item/shield/energy)
/obj/effect/landmark/mobcorpse/orionsecurity
name = "Spaceport Security"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/armor/vest
corpseshoes = /obj/item/clothing/shoes/combat
corpsegloves = /obj/item/clothing/gloves/combat
corpseradio = /obj/item/radio/headset
corpsemask = /obj/item/clothing/mask/gas
corpsehelmet = /obj/item/clothing/head/helmet/swat
corpseback = /obj/item/storage/backpack
corpseid = 1
corpseidjob = "Officer"
corpseidaccess = "Syndicate"
loot = list()
del_on_death = TRUE
/obj/item/orion_ship
name = "model settler ship"
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+4 -5
View File
@@ -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))
+11 -6
View File
@@ -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
+24 -30
View File
@@ -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 -1
View File
@@ -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)
+2 -5
View File
@@ -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)
-1
View File
@@ -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
+4 -1
View File
@@ -71,13 +71,16 @@
buckled_mob.clear_alert("buckled")
buckled_mob = null
post_buckle_mob(.)
post_unbuckle_mob(.)
//Handle any extras after buckling/unbuckling
//Called on buckle_mob() and unbuckle_mob()
/atom/movable/proc/post_buckle_mob(mob/living/M)
return
//same but for unbuckle
/atom/movable/proc/post_unbuckle_mob(mob/living/M)
return
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user)
@@ -21,10 +21,10 @@
color = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6", "xgibup1", "xgibup1", "xgibup1")
/obj/effect/decal/cleanable/blood/gibs/xeno/down
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6", "xgibdown1", "xgibdown1", "xgibdown1")
/obj/effect/decal/cleanable/blood/gibs/xeno/body
random_icon_states = list("xgibhead", "xgibtorso")
@@ -36,4 +36,4 @@
random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
/obj/effect/decal/cleanable/blood/xtracks
basecolor = "#05EE05"
basecolor = "#05EE05"
@@ -2,11 +2,11 @@
//Liquid fuel is used for things that used to rely on volatile fuels or plasma being contained to a couple tiles.
icon = 'icons/effects/effects.dmi'
icon_state = "fuel"
layer = TURF_LAYER+0.2
anchored = 1
layer = LATTICE_LAYER
anchored = TRUE
var/amount = 1 //Basically moles.
/obj/effect/decal/cleanable/liquid_fuel/New(newLoc,amt=1)
/obj/effect/decal/cleanable/liquid_fuel/Initialize(newLoc, amt = 1)
amount = amt
//Be absorbed by any other liquid fuel in the tile.
@@ -21,38 +21,42 @@
/obj/effect/decal/cleanable/liquid_fuel/proc/Spread()
//Allows liquid fuels to sometimes flow into other tiles.
if(amount < 0.5) return
if(amount < 0.5)
return
var/turf/simulated/S = loc
if(!istype(S)) return
if(!istype(S))
return
for(var/d in cardinal)
if(rand(25))
var/turf/simulated/target = get_step(src, d)
var/turf/simulated/origin = get_turf(src)
if(origin.CanPass(null, target, 0, 0) && target.CanPass(null, origin, 0, 0))
if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in target)
new/obj/effect/decal/cleanable/liquid_fuel(target, amount*0.25)
new/obj/effect/decal/cleanable/liquid_fuel(target, amount * 0.25)
amount *= 0.75
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel
icon_state = "mustard"
anchored = 0
anchored = FALSE
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/New(newLoc, amt = 1, d = 0)
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/Initialize(newLoc, amt = 1, d = 0)
dir = d //Setting this direction means you won't get torched by your own flamethrower.
. = ..()
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/Spread()
//The spread for flamethrower fuel is much more precise, to create a wide fire pattern.
if(amount < 0.1) return
if(amount < 0.1)
return
var/turf/simulated/S = loc
if(!istype(S)) return
if(!istype(S))
return
for(var/d in list(turn(dir,90),turn(dir,-90), dir))
var/turf/simulated/O = get_step(S,d)
for(var/d in list(turn(dir, 90), turn(dir, -90), dir))
var/turf/simulated/O = get_step(S, d)
if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O)
continue
if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0))
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d)
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O, amount * 0.25, d)
O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately.
amount *= 0.25
@@ -1,6 +1,6 @@
#define DRYING_TIME 5 * 60*10 //for 1 unit of depth in puddle (amount var)
#define DRYING_TIME 5 * 60 * 10 //for 1 unit of depth in puddle (amount var)
var/global/list/image/splatter_cache=list()
var/global/list/image/splatter_cache = list()
/obj/effect/decal/cleanable/blood
name = "blood"
@@ -8,24 +8,24 @@ var/global/list/image/splatter_cache=list()
desc = "It's thick and gooey. Perhaps it's the chef's cooking?"
var/drydesc = "It's dry and crusty. Someone is not doing their job."
gender = PLURAL
density = 0
anchored = 1
layer = 2
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
var/base_icon = 'icons/effects/blood.dmi'
appearance_flags = NO_CLIENT_COLOR
blood_DNA = list()
var/base_icon = 'icons/effects/blood.dmi'
var/blood_state = BLOOD_STATE_HUMAN
var/bloodiness = MAX_SHOE_BLOODINESS
var/basecolor = "#A10808" // Color when wet.
var/amount = 5
appearance_flags = NO_CLIENT_COLOR
var/dry_timer = 0
var/off_floor = FALSE
/obj/effect/decal/cleanable/blood/New()
..()
/obj/effect/decal/cleanable/blood/Initialize()
. = ..()
update_icon()
if(GAMEMODE_IS_CULT)
var/datum/game_mode/cult/mode_ticker = ticker.mode
@@ -58,7 +58,8 @@ var/global/list/image/splatter_cache=list()
return ..()
/obj/effect/decal/cleanable/blood/update_icon()
if(basecolor == "rainbow") basecolor = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
if(basecolor == "rainbow")
basecolor = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
color = basecolor
/obj/effect/decal/cleanable/blood/proc/dry()
@@ -93,9 +94,9 @@ var/global/list/image/splatter_cache=list()
var/mob/living/carbon/human/H = O
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/hasfeet = 1
var/hasfeet = TRUE
if(!l_foot && !r_foot)
hasfeet = 0
hasfeet = FALSE
if(H.shoes && blood_state && bloodiness)
var/obj/item/clothing/shoes/S = H.shoes
var/add_blood = 0
@@ -137,10 +138,10 @@ var/global/list/image/splatter_cache=list()
gender = PLURAL
icon = 'icons/effects/drip.dmi'
icon_state = "1"
random_icon_states = list("1","2","3","4","5")
random_icon_states = list("1", "2", "3", "4", "5")
amount = 0
var/drips = 1
bloodiness = 0
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
return TRUE
@@ -150,12 +151,12 @@ var/global/list/image/splatter_cache=list()
icon_state = "ltrails_1"
desc = "Your instincts say you shouldn't be following these."
gender = PLURAL
density = 0
layer = 2
density = FALSE
layer = TURF_LAYER
random_icon_states = null
var/list/existing_dirs = list()
blood_DNA = list()
appearance_flags = NO_CLIENT_COLOR
var/list/existing_dirs = list()
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
return TRUE
@@ -164,12 +165,12 @@ var/global/list/image/splatter_cache=list()
icon_state = "tracks"
desc = "It looks like a writing in blood."
gender = NEUTER
random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
random_icon_states = list("writing1", "writing2", "writing3", "writing4", "writing5")
amount = 0
var/message
/obj/effect/decal/cleanable/blood/writing/New()
..()
/obj/effect/decal/cleanable/blood/writing/Initialize()
. = ..()
if(random_icon_states.len)
for(var/obj/effect/decal/cleanable/blood/writing/W in loc)
random_icon_states.Remove(W.icon_state)
@@ -179,20 +180,20 @@ var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
..(user)
to_chat(user, "It reads: <font color='[basecolor]'>\"[message]\"<font>")
to_chat(user, "<span class='notice'>It reads: <font color='[basecolor]'>\"[message]\"<font></span>")
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
gender = PLURAL
density = 0
anchored = 1
layer = 2
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
noclear = TRUE
var/fleshcolor = "#FFFFFF"
noclear = 1
/obj/effect/decal/cleanable/blood/gibs/update_icon()
var/image/giblets = new(base_icon, "[icon_state]_flesh", dir)
@@ -207,10 +208,10 @@ var/global/list/image/splatter_cache=list()
. = ..()
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gibup1", "gibup1", "gibup1")
/obj/effect/decal/cleanable/blood/gibs/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gibdown1", "gibdown1", "gibdown1")
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
@@ -221,15 +222,15 @@ var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/New()
..()
/obj/effect/decal/cleanable/blood/gibs/Initialize()
. = ..()
reagents.add_reagent("liquidgibs", 5)
/obj/effect/decal/cleanable/blood/gibs/cleangibs //most ironic name ever...
/obj/effect/decal/cleanable/blood/gibs/cleangibs/New() //no reagent!
..()
/obj/effect/decal/cleanable/blood/gibs/cleangibs/Initialize() //no reagent!
. = ..()
reagents.remove_reagent("liquidgibs",5)
@@ -246,18 +247,20 @@ var/global/list/image/splatter_cache=list()
break
/obj/effect/decal/cleanable/blood/old/New()
..()
/obj/effect/decal/cleanable/blood/old/Initialize()
. = ..()
bloodiness = 0
dry()
/obj/effect/decal/cleanable/blood/old/can_bloodcrawl_in()
return FALSE
/obj/effect/decal/cleanable/blood/gibs/old/New()
..()
/obj/effect/decal/cleanable/blood/gibs/old/Initialize()
. = ..()
bloodiness = 0
dry()
/obj/effect/decal/cleanable/blood/gibs/old/can_bloodcrawl_in()
return FALSE
#undef DRYING_TIME
+203 -203
View File
@@ -1,203 +1,203 @@
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
gender = PLURAL
density = 0
anchored = 1
layer = 2
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
anchored = 1
/obj/effect/decal/cleanable/ash/New()
..()
reagents.add_reagent("ash", 10)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
gender = PLURAL
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/effects.dmi'
icon_state = "dirt"
mouse_opacity = 0
/obj/effect/decal/cleanable/dirt/blackpowder
name = "black powder"
mouse_opacity = 1
noscoop = 1
/obj/effect/decal/cleanable/dirt/blackpowder/New()
..()
reagents.add_reagent("blackpowder", 40) //size 2 explosion when activated
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
gender = PLURAL
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
/obj/effect/decal/cleanable/flour/foam
name = "Fire fighting foam"
desc = "It's foam."
color = "#EBEBEB"
New()
..()
spawn(150)// 15 seconds
qdel(src)
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
gender = PLURAL
density = 0
anchored = 1
layer = 2
light_range = 1
icon = 'icons/effects/effects.dmi'
icon_state = "greenglow"
New()
..()
spawn(1200)// 2 minutes
qdel(src)
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
density = 0
anchored = 1
layer = 3
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb1"
burntime = 1
/obj/effect/decal/cleanable/cobweb/fire_act()
qdel(src)
/obj/effect/decal/cleanable/molten_object
name = "gooey grey mass"
desc = "It looks like a melted... something."
density = 0
anchored = 1
layer = 3
gender = NEUTER
icon = 'icons/effects/effects.dmi'
icon_state = "molten"
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
icon_state = "big_molten"
/obj/effect/decal/cleanable/cobweb2
name = "cobweb"
desc = "Somebody should remove that."
density = 0
anchored = 1
layer = 3
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb2"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
gender = PLURAL
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
noclear = 1
/obj/effect/decal/cleanable/vomit/New()
..()
reagents.add_reagent("vomit", 5)
/obj/effect/decal/cleanable/vomit/green
name = "green vomit"
desc = "It's all gummy. Ew."
icon_state = "gvomit_1"
random_icon_states = list("gvomit_1", "gvomit_2", "gvomit_3", "gvomit_4")
/obj/effect/decal/cleanable/vomit/green/New()
..()
reagents.remove_reagent("vomit", 5)
reagents.add_reagent("green_vomit", 5)
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
density = 0
anchored = 1
layer = 2
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/fungus
name = "space fungus"
desc = "A fungal growth. Looks pretty nasty."
density = 0
anchored = 1
layer = 2
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
color = "#D5820B"
/obj/effect/decal/cleanable/fungus/New()
..()
reagents.add_reagent("fungus", 10)
/obj/effect/decal/cleanable/confetti //PARTY TIME!
name = "confetti"
desc = "Party time!"
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "confetti1"
random_icon_states = list("confetti1", "confetti2", "confetti3")
anchored = 1
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
anchored = TRUE
/obj/effect/decal/cleanable/ash/Initialize()
. = ..()
reagents.add_reagent("ash", 10)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/dirt.dmi'
icon_state = "dirt"
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/simulated/wall, /obj/structure/falsewall)
smooth = SMOOTH_MORE
mouse_opacity = FALSE
/obj/effect/decal/cleanable/dirt/Initialize()
..()
icon_state = ""
/obj/effect/decal/cleanable/dirt/blackpowder
name = "black powder"
mouse_opacity = TRUE
noscoop = TRUE
/obj/effect/decal/cleanable/dirt/blackpowder/Initialize()
. = ..()
reagents.add_reagent("blackpowder", 40) // size 2 explosion when activated
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
gender = PLURAL
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
/obj/effect/decal/cleanable/flour/foam
name = "Fire fighting foam"
desc = "It's foam."
color = "#EBEBEB"
/obj/effect/decal/cleanable/flour/foam/Initialize()
. = ..()
QDEL_IN(src, 15 SECONDS)
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
gender = PLURAL
density = FALSE
anchored = TRUE
layer = TURF_LAYER
light_range = 1
icon = 'icons/effects/effects.dmi'
icon_state = "greenglow"
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
. = ..()
QDEL_IN(src, 2 MINUTES)
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
layer = OBJ_LAYER
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb1"
burntime = 1
/obj/effect/decal/cleanable/cobweb/fire_act()
qdel(src)
/obj/effect/decal/cleanable/molten_object
name = "gooey grey mass"
desc = "It looks like a melted... something."
density = FALSE
anchored = TRUE
layer = OBJ_LAYER
gender = NEUTER
icon = 'icons/effects/effects.dmi'
icon_state = "molten"
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
icon_state = "big_molten"
/obj/effect/decal/cleanable/cobweb2
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
layer = OBJ_LAYER
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb2"
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
gender = PLURAL
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
noclear = TRUE
/obj/effect/decal/cleanable/vomit/Initialize()
. = ..()
reagents.add_reagent("vomit", 5)
/obj/effect/decal/cleanable/vomit/green
name = "green vomit"
desc = "It's all gummy. Ew."
icon_state = "gvomit_1"
random_icon_states = list("gvomit_1", "gvomit_2", "gvomit_3", "gvomit_4")
/obj/effect/decal/cleanable/vomit/green/Initialize()
. = ..()
reagents.remove_reagent("vomit", 5)
reagents.add_reagent("green_vomit", 5)
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
density = FALSE
anchored = TRUE
layer = TURF_LAYER
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/fungus
name = "space fungus"
desc = "A fungal growth. Looks pretty nasty."
density = FALSE
anchored = TRUE
layer = TURF_LAYER
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
color = "#D5820B"
/obj/effect/decal/cleanable/fungus/Initialize()
. = ..()
reagents.add_reagent("fungus", 10)
/obj/effect/decal/cleanable/confetti //PARTY TIME!
name = "confetti"
desc = "Party time!"
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "confetti1"
random_icon_states = list("confetti1", "confetti2", "confetti3")
anchored = TRUE
@@ -3,7 +3,7 @@
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
basecolor="#030303"
basecolor = "#030303"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
bloodiness = MAX_SHOE_BLOODINESS
@@ -20,7 +20,7 @@
return FALSE
/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions)
spawn (0)
spawn(0)
var/direction = pick(directions)
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
@@ -39,15 +39,15 @@
random_icon_states = list("gibarm", "gibleg")
/obj/effect/decal/cleanable/blood/gibs/robot/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1") //2:7 is close enough to 1:4
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibup1", "gibup1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/gibs/robot/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibdown1", "gibdown1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/oil
name = "motor oil"
desc = "It's black and greasy. Looks like Beepsky made another mess."
basecolor="#030303"
basecolor = "#030303"
bloodiness = MAX_SHOE_BLOODINESS
/obj/effect/decal/cleanable/blood/oil/can_bloodcrawl_in()
@@ -2,7 +2,7 @@
#define TRACKS_CRUSTIFY_TIME 50
// color-dir-dry
var/global/list/image/fluidtrack_cache=list()
var/global/list/image/fluidtrack_cache = list()
// Footprints, tire trails...
/obj/effect/decal/cleanable/blood/tracks
@@ -23,7 +23,7 @@ var/global/list/image/fluidtrack_cache=list()
desc = "You REALLY shouldn't follow these.."
gender = PLURAL
random_icon_states = null
basecolor="#A10808"
basecolor = "#A10808"
var/entered_dirs = 0
var/exited_dirs = 0
blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
@@ -35,9 +35,9 @@ var/global/list/image/fluidtrack_cache=list()
var/obj/item/clothing/shoes/S = H.shoes
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/hasfeet = 1
var/hasfeet = TRUE
if(!l_foot && !r_foot)
hasfeet = 0
hasfeet = FALSE
if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor)
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
entered_dirs |= H.dir
@@ -58,9 +58,9 @@ var/global/list/image/fluidtrack_cache=list()
var/obj/item/clothing/shoes/S = H.shoes
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/hasfeet = 1
var/hasfeet = TRUE
if(!l_foot && !r_foot)
hasfeet = 0
hasfeet = FALSE
if(S && S.bloody_shoes[blood_state] && S.blood_color == basecolor)
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
exited_dirs |= H.dir
+13 -4
View File
@@ -1,8 +1,8 @@
/obj/effect/decal/cleanable
anchored = 1
anchored = TRUE
var/list/random_icon_states = list()
var/noscoop = 0 //if it has this, don't let it be scooped up
var/noclear = 0 //if it has this, don't delete it when its' scooped up
var/noscoop = FALSE //if it has this, don't let it be scooped up
var/noclear = FALSE //if it has this, don't delete it when its' scooped up
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
return FALSE
@@ -11,8 +11,16 @@
if(random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
create_reagents(100)
if(smooth)
smooth_icon(src)
smooth_icon_neighbors(src)
..()
/obj/effect/decal/cleanable/Destroy()
if(smooth)
smooth_icon_neighbors(src)
return ..()
/obj/effect/decal/cleanable/attackby(obj/item/W as obj, mob/user as mob,)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
if(src.reagents && W.reagents && !noscoop)
@@ -28,7 +36,8 @@
qdel(src)
return
if(is_hot(W)) //todo: make heating a reagent holder proc
if(istype(W, /obj/item/clothing/mask/cigarette)) return
if(istype(W, /obj/item/clothing/mask/cigarette))
return
else
src.reagents.chem_temp += 15
src.reagents.handle_reactions()
+3 -3
View File
@@ -3,8 +3,8 @@
desc = "A rune drawn in crayon."
icon = 'icons/effects/crayondecal.dmi'
icon_state = "rune1"
layer = 2.1
anchored = 1
layer = MID_TURF_LAYER
anchored = TRUE
/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune")
@@ -15,4 +15,4 @@
desc = "A [name] drawn in crayon."
icon_state = type
color = main
color = main
+22 -22
View File
@@ -1,7 +1,7 @@
// Used for spray that you spray at walls, tables, hydrovats etc
/obj/effect/decal/spraystill
density = 0
anchored = 1
density = FALSE
anchored = TRUE
layer = 50
plane = HUD_PLANE
@@ -11,38 +11,38 @@
pass_flags = PASSTABLE | PASSGRILLE
/obj/effect/decal/snow
name="snow"
density=0
anchored=1
layer=2
icon='icons/turf/snow.dmi'
name = "snow"
density = FALSE
anchored = TRUE
layer = TURF_DECAL_LAYER
icon = 'icons/turf/snow.dmi'
/obj/effect/decal/snow/clean/edge
icon_state="snow_corner"
icon_state = "snow_corner"
/obj/effect/decal/snow/sand/edge
icon_state="gravsnow_corner"
icon_state = "gravsnow_corner"
/obj/effect/decal/snow/clean/surround
icon_state="snow_surround"
icon_state = "snow_surround"
/obj/effect/decal/snow/sand/surround
icon_state="gravsnow_surround"
icon_state = "gravsnow_surround"
/obj/effect/decal/leaves
name="fall leaves"
density = 0
anchored = 1
layer = 2
icon='icons/obj/flora/plants.dmi'
name = "fall leaves"
density = FALSE
anchored = TRUE
layer = HIGH_TURF_LAYER
icon = 'icons/obj/flora/plants.dmi'
icon_state = "fallleaves"
/obj/effect/decal/straw
name="scattered straw"
density = 0
anchored = 1
layer = 2
icon='icons/obj/flora/plants.dmi'
name = "scattered straw"
density = FALSE
anchored = TRUE
layer = HIGH_TURF_LAYER
icon = 'icons/obj/flora/plants.dmi'
icon_state = "strawscattered"
/obj/effect/decal/straw/medium
@@ -52,4 +52,4 @@
icon_state = "strawscattered2"
/obj/effect/decal/straw/edge
icon_state = "strawscatterededge"
icon_state = "strawscatterededge"
+4 -4
View File
@@ -6,21 +6,21 @@
desc = "They look like human remains. They have a strange aura about them."
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
anchored = 1
anchored = TRUE
/obj/effect/decal/remains/xeno
name = "remains"
desc = "They look like the remains of something... alien. They have a strange aura about them."
icon = 'icons/effects/blood.dmi'
icon_state = "remainsxeno"
anchored = 1
anchored = TRUE
/obj/effect/decal/remains/robot
name = "remains"
desc = "They look like the remains of something mechanical. They have a strange aura about them."
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
anchored = 1
anchored = TRUE
/obj/effect/decal/remains/robot/New()
..()
@@ -33,7 +33,7 @@
desc = "Noooooooooooooooooooooo"
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
anchored = 1
anchored = TRUE
/obj/effect/decal/remains/slime/New()
..()
@@ -1,6 +1,6 @@
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
layer = 2
layer = TURF_LAYER
/obj/effect/decal/warning_stripes/north
icon_state = "N"
@@ -50,7 +50,7 @@
/obj/effect/decal/warning_stripes/northwestsouth
icon_state = "U-E"
/obj/effect/decal/warning_stripes/New()
/obj/effect/decal/warning_stripes/Initialize()
. = ..()
loc.overlays += src
qdel(src)
@@ -107,4 +107,4 @@
icon_state = "16"
/obj/effect/decal/warning_stripes/blue/hollow
icon_state = "18"
icon_state = "18"
@@ -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

Some files were not shown because too many files have changed in this diff Show More